* [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
2012-08-10 7:10 ` Praveen Paneri
@ 2012-08-10 7:10 ` Praveen Paneri
-1 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 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
This driver uses usb_phy interface to interact with s3c-hsotg. Supports
phy_init and phy_shutdown functions to enable/disable phy. Tested with
smdk6410 and smdkv310. More SoCs can be brought under later.
Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
---
.../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
drivers/usb/phy/Kconfig | 8 +
drivers/usb/phy/Makefile | 1 +
drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
drivers/usb/phy/samsung-usbphy.h | 48 +++
include/linux/platform_data/samsung-usbphy.h | 27 ++
6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
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..fefd9c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,9 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+
+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 e7cf84f..d916477 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -15,3 +15,11 @@ config USB_ISP1301
To compile this driver as a module, choose M here: the
module will be called isp1301.
+
+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 eca095b..dfca70d 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -5,3 +5,4 @@
ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,345 @@
+/* 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#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>
+
+#include "samsung-usbphy.h"
+
+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
+ * @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 cpu_type;
+};
+
+#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Enables or disables the phy clock
+ * returns 0 on success else the error
+ */
+static int samsung_usbphy_clk_control(struct samsung_usbphy *sphy, bool on)
+{
+ if (on) {
+ if (!sphy->clk) {
+ sphy->clk = clk_get(sphy->dev, "otg");
+ if (IS_ERR(sphy->clk)) {
+ dev_err(sphy->dev, "Failed to get otg clock\n");
+ return PTR_ERR(sphy->clk);
+ }
+ }
+ clk_enable(sphy->clk);
+ } else {
+ clk_disable(sphy->clk);
+ clk_put(sphy->clk);
+ }
+
+ return 0;
+}
+
+/*
+ * Returns reference clock frequency
+ */
+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 |= S3C_PHYCLK_CLKSEL_12M;
+ break;
+ case 24 * MHZ:
+ refclk_freq |= S3C_PHYCLK_CLKSEL_24M;
+ break;
+ default:
+ case 48 * MHZ:
+ /* default reference clock */
+ refclk_freq |= S3C_PHYCLK_CLKSEL_48M;
+ 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 = samsung_usbphy_get_refclk_freq(sphy);
+ phypwr = readl(regs + S3C_PHYPWR);
+ rstcon = readl(regs + S3C_RSTCON);
+
+ switch (sphy->cpu_type) {
+ case TYPE_S3C64XX:
+ phyclk &= ~(S3C_PHYCLK_COMMON_ON_N);
+ phypwr &= ~S3C_PHYPWR_NORMAL_MASK;
+ rstcon |= S3C_RSTCON_PHY;
+ break;
+ case TYPE_EXYNOS4210:
+ phypwr &= ~EXYNOS4_PHYPWR_NORMAL_MASK;
+ rstcon |= S3C_RSTCON_PHY;
+ default:
+ break;
+ }
+
+ writel(phyclk, regs + S3C_PHYCLK);
+ /* set to normal of PHY0 */
+ writel(phypwr, regs + S3C_PHYPWR);
+ /* reset all ports of PHY and Link */
+ writel(rstcon, regs + S3C_RSTCON);
+ udelay(10);
+ rstcon &= ~S3C_RSTCON_PHY;
+ writel(rstcon, regs + S3C_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+ void __iomem *regs = sphy->regs;
+ u32 phypwr;
+
+ phypwr = readl(regs + S3C_PHYPWR);
+
+ switch (sphy->cpu_type) {
+ case TYPE_S3C64XX:
+ phypwr |= S3C_PHYPWR_NORMAL_MASK;
+ break;
+ case TYPE_EXYNOS4210:
+ phypwr |= EXYNOS4_PHYPWR_NORMAL_MASK;
+ default:
+ break;
+ }
+
+ /* unset to normal of PHY0 */
+ writel(phypwr, regs + S3C_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 = samsung_usbphy_clk_control(sphy, true);
+ if (ret) {
+ dev_err(sphy->dev, "phy clock enable failed\n");
+ 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);
+ 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);
+
+ /* De-initialize usb phy registers */
+ samsung_usbphy_disable(sphy);
+
+ /* Enable phy isolation */
+ if (sphy->plat && sphy->plat->pmu_isolation)
+ sphy->plat->pmu_isolation(true);
+
+ /* Disable the phy clock */
+ samsung_usbphy_clk_control(sphy, false);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+ int data;
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(samsung_usbphy_dt_match,
+ pdev->dev.of_node);
+ data = (int) match->data;
+ return data;
+ }
+#endif
+ 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;
+ int ret;
+
+ 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;
+
+ sphy->dev = &pdev->dev;
+ sphy->plat = pdata;
+ sphy->regs = phy_base;
+ 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);
+
+ ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+ if (ret)
+ goto err;
+
+ platform_set_drvdata(pdev, sphy);
+
+ dev_info(&pdev->dev, "Initialized samsung USB OTG PHY module\n");
+err:
+ 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);
+
+ if (sphy->clk) {
+ clk_put(sphy->clk);
+ sphy->clk = NULL;
+ }
+
+ 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/drivers/usb/phy/samsung-usbphy.h b/drivers/usb/phy/samsung-usbphy.h
new file mode 100644
index 0000000..093b1dc
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Yulgon Kim <yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ * Author: Joonyoung Shim <jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * 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_H
+#define __SAMSUNG_USBPHY_H
+
+#define S3C_PHYPWR (0x00)
+
+#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
+#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
+#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
+#define S3C_PHYPWR_FORCE_SUSPEND (1 << 1)
+/* For Exynos4 */
+#define EXYNOS4_PHYPWR_NORMAL_MASK (0x39 << 0)
+#define EXYNOS4_PHYPWR_SLEEP (1 << 5)
+
+#define S3C_PHYCLK (0x04)
+
+#define S3C_PHYCLK_MODE_SERIAL (1 << 6)
+#define S3C_PHYCLK_EXT_OSC (1 << 5)
+#define S3C_PHYCLK_COMMON_ON_N (1 << 4)
+#define S3C_PHYCLK_ID_PULL (1 << 2)
+#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
+#define S3C_PHYCLK_CLKSEL_SHIFT (0)
+#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
+#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
+#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
+
+#define S3C_RSTCON (0x08)
+
+#define S3C_RSTCON_PHYCLK (1 << 2)
+#define S3C_RSTCON_HCLK (1 << 1)
+#define S3C_RSTCON_PHY (1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+#endif /* __SAMSUNG_USBPHY_H */
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] 27+ messages in thread
* [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-08-10 7:10 ` Praveen Paneri
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 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 phy. Tested with
smdk6410 and smdkv310. More SoCs can be brought under later.
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>
---
.../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
drivers/usb/phy/Kconfig | 8 +
drivers/usb/phy/Makefile | 1 +
drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
drivers/usb/phy/samsung-usbphy.h | 48 +++
include/linux/platform_data/samsung-usbphy.h | 27 ++
6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
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..fefd9c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,9 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+
+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 e7cf84f..d916477 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -15,3 +15,11 @@ config USB_ISP1301
To compile this driver as a module, choose M here: the
module will be called isp1301.
+
+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 eca095b..dfca70d 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -5,3 +5,4 @@
ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,345 @@
+/* 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#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>
+
+#include "samsung-usbphy.h"
+
+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
+ * @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 cpu_type;
+};
+
+#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Enables or disables the phy clock
+ * returns 0 on success else the error
+ */
+static int samsung_usbphy_clk_control(struct samsung_usbphy *sphy, bool on)
+{
+ if (on) {
+ if (!sphy->clk) {
+ sphy->clk = clk_get(sphy->dev, "otg");
+ if (IS_ERR(sphy->clk)) {
+ dev_err(sphy->dev, "Failed to get otg clock\n");
+ return PTR_ERR(sphy->clk);
+ }
+ }
+ clk_enable(sphy->clk);
+ } else {
+ clk_disable(sphy->clk);
+ clk_put(sphy->clk);
+ }
+
+ return 0;
+}
+
+/*
+ * Returns reference clock frequency
+ */
+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 |= S3C_PHYCLK_CLKSEL_12M;
+ break;
+ case 24 * MHZ:
+ refclk_freq |= S3C_PHYCLK_CLKSEL_24M;
+ break;
+ default:
+ case 48 * MHZ:
+ /* default reference clock */
+ refclk_freq |= S3C_PHYCLK_CLKSEL_48M;
+ 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 = samsung_usbphy_get_refclk_freq(sphy);
+ phypwr = readl(regs + S3C_PHYPWR);
+ rstcon = readl(regs + S3C_RSTCON);
+
+ switch (sphy->cpu_type) {
+ case TYPE_S3C64XX:
+ phyclk &= ~(S3C_PHYCLK_COMMON_ON_N);
+ phypwr &= ~S3C_PHYPWR_NORMAL_MASK;
+ rstcon |= S3C_RSTCON_PHY;
+ break;
+ case TYPE_EXYNOS4210:
+ phypwr &= ~EXYNOS4_PHYPWR_NORMAL_MASK;
+ rstcon |= S3C_RSTCON_PHY;
+ default:
+ break;
+ }
+
+ writel(phyclk, regs + S3C_PHYCLK);
+ /* set to normal of PHY0 */
+ writel(phypwr, regs + S3C_PHYPWR);
+ /* reset all ports of PHY and Link */
+ writel(rstcon, regs + S3C_RSTCON);
+ udelay(10);
+ rstcon &= ~S3C_RSTCON_PHY;
+ writel(rstcon, regs + S3C_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+ void __iomem *regs = sphy->regs;
+ u32 phypwr;
+
+ phypwr = readl(regs + S3C_PHYPWR);
+
+ switch (sphy->cpu_type) {
+ case TYPE_S3C64XX:
+ phypwr |= S3C_PHYPWR_NORMAL_MASK;
+ break;
+ case TYPE_EXYNOS4210:
+ phypwr |= EXYNOS4_PHYPWR_NORMAL_MASK;
+ default:
+ break;
+ }
+
+ /* unset to normal of PHY0 */
+ writel(phypwr, regs + S3C_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 = samsung_usbphy_clk_control(sphy, true);
+ if (ret) {
+ dev_err(sphy->dev, "phy clock enable failed\n");
+ 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);
+ 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);
+
+ /* De-initialize usb phy registers */
+ samsung_usbphy_disable(sphy);
+
+ /* Enable phy isolation */
+ if (sphy->plat && sphy->plat->pmu_isolation)
+ sphy->plat->pmu_isolation(true);
+
+ /* Disable the phy clock */
+ samsung_usbphy_clk_control(sphy, false);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+ int data;
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(samsung_usbphy_dt_match,
+ pdev->dev.of_node);
+ data = (int) match->data;
+ return data;
+ }
+#endif
+ 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;
+ int ret;
+
+ 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;
+
+ sphy->dev = &pdev->dev;
+ sphy->plat = pdata;
+ sphy->regs = phy_base;
+ 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);
+
+ ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+ if (ret)
+ goto err;
+
+ platform_set_drvdata(pdev, sphy);
+
+ dev_info(&pdev->dev, "Initialized samsung USB OTG PHY module\n");
+err:
+ 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);
+
+ if (sphy->clk) {
+ clk_put(sphy->clk);
+ sphy->clk = NULL;
+ }
+
+ 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/drivers/usb/phy/samsung-usbphy.h b/drivers/usb/phy/samsung-usbphy.h
new file mode 100644
index 0000000..093b1dc
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Yulgon Kim <yulgon.kim@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * 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_H
+#define __SAMSUNG_USBPHY_H
+
+#define S3C_PHYPWR (0x00)
+
+#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
+#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
+#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
+#define S3C_PHYPWR_FORCE_SUSPEND (1 << 1)
+/* For Exynos4 */
+#define EXYNOS4_PHYPWR_NORMAL_MASK (0x39 << 0)
+#define EXYNOS4_PHYPWR_SLEEP (1 << 5)
+
+#define S3C_PHYCLK (0x04)
+
+#define S3C_PHYCLK_MODE_SERIAL (1 << 6)
+#define S3C_PHYCLK_EXT_OSC (1 << 5)
+#define S3C_PHYCLK_COMMON_ON_N (1 << 4)
+#define S3C_PHYCLK_ID_PULL (1 << 2)
+#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
+#define S3C_PHYCLK_CLKSEL_SHIFT (0)
+#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
+#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
+#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
+
+#define S3C_RSTCON (0x08)
+
+#define S3C_RSTCON_PHYCLK (1 << 2)
+#define S3C_RSTCON_HCLK (1 << 1)
+#define S3C_RSTCON_PHY (1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+#endif /* __SAMSUNG_USBPHY_H */
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] 27+ messages in thread
[parent not found: <1344582631-13658-2-git-send-email-p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>]
* Re: [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
2012-08-10 7:10 ` Praveen Paneri
@ 2012-08-10 7:04 ` Felipe Balbi
-1 siblings, 0 replies; 27+ messages in thread
From: Felipe Balbi @ 2012-08-10 7:04 UTC (permalink / raw)
To: Praveen Paneri
Cc: l.majewski-Sze3O3UU22JBDgjK7y7TUQ,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
heiko-4mtYJXux2i+zQB+pC5nmwQ,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-usb-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
ben-linux-elnMNo+KYs3YtjvyW6yDsg,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
[-- Attachment #1.1: Type: text/plain, Size: 14605 bytes --]
Hi,
On Fri, Aug 10, 2012 at 12:40:27PM +0530, Praveen Paneri wrote:
> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
> phy_init and phy_shutdown functions to enable/disable phy. Tested with
> smdk6410 and smdkv310. More SoCs can be brought under later.
>
> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Acked-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
this looks good. Just 2 comments below.
> ---
> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
> drivers/usb/phy/Kconfig | 8 +
> drivers/usb/phy/Makefile | 1 +
> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
> drivers/usb/phy/samsung-usbphy.h | 48 +++
> include/linux/platform_data/samsung-usbphy.h | 27 ++
> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
> 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..fefd9c8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,9 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +
> +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 e7cf84f..d916477 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -15,3 +15,11 @@ config USB_ISP1301
>
> To compile this driver as a module, choose M here: the
> module will be called isp1301.
> +
> +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 eca095b..dfca70d 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -5,3 +5,4 @@
> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>
> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,345 @@
> +/* 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> +*/
> +
> +#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>
> +
> +#include "samsung-usbphy.h"
> +
> +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
> + * @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 cpu_type;
> +};
> +
> +#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
> +
> +/*
> + * Enables or disables the phy clock
> + * returns 0 on success else the error
> + */
> +static int samsung_usbphy_clk_control(struct samsung_usbphy *sphy, bool on)
> +{
> + if (on) {
> + if (!sphy->clk) {
> + sphy->clk = clk_get(sphy->dev, "otg");
> + if (IS_ERR(sphy->clk)) {
> + dev_err(sphy->dev, "Failed to get otg clock\n");
> + return PTR_ERR(sphy->clk);
> + }
> + }
> + clk_enable(sphy->clk);
> + } else {
> + clk_disable(sphy->clk);
> + clk_put(sphy->clk);
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Returns reference clock frequency
> + */
> +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 |= S3C_PHYCLK_CLKSEL_12M;
> + break;
> + case 24 * MHZ:
> + refclk_freq |= S3C_PHYCLK_CLKSEL_24M;
> + break;
> + default:
> + case 48 * MHZ:
> + /* default reference clock */
> + refclk_freq |= S3C_PHYCLK_CLKSEL_48M;
> + 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 = samsung_usbphy_get_refclk_freq(sphy);
> + phypwr = readl(regs + S3C_PHYPWR);
> + rstcon = readl(regs + S3C_RSTCON);
> +
> + switch (sphy->cpu_type) {
> + case TYPE_S3C64XX:
> + phyclk &= ~(S3C_PHYCLK_COMMON_ON_N);
> + phypwr &= ~S3C_PHYPWR_NORMAL_MASK;
> + rstcon |= S3C_RSTCON_PHY;
> + break;
> + case TYPE_EXYNOS4210:
> + phypwr &= ~EXYNOS4_PHYPWR_NORMAL_MASK;
> + rstcon |= S3C_RSTCON_PHY;
> + default:
> + break;
> + }
> +
> + writel(phyclk, regs + S3C_PHYCLK);
> + /* set to normal of PHY0 */
> + writel(phypwr, regs + S3C_PHYPWR);
> + /* reset all ports of PHY and Link */
> + writel(rstcon, regs + S3C_RSTCON);
> + udelay(10);
> + rstcon &= ~S3C_RSTCON_PHY;
> + writel(rstcon, regs + S3C_RSTCON);
> +}
> +
> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> + void __iomem *regs = sphy->regs;
> + u32 phypwr;
> +
> + phypwr = readl(regs + S3C_PHYPWR);
> +
> + switch (sphy->cpu_type) {
> + case TYPE_S3C64XX:
> + phypwr |= S3C_PHYPWR_NORMAL_MASK;
> + break;
> + case TYPE_EXYNOS4210:
> + phypwr |= EXYNOS4_PHYPWR_NORMAL_MASK;
> + default:
> + break;
> + }
> +
> + /* unset to normal of PHY0 */
> + writel(phypwr, regs + S3C_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 = samsung_usbphy_clk_control(sphy, true);
> + if (ret) {
> + dev_err(sphy->dev, "phy clock enable failed\n");
> + 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);
> + 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);
> +
> + /* De-initialize usb phy registers */
> + samsung_usbphy_disable(sphy);
> +
> + /* Enable phy isolation */
> + if (sphy->plat && sphy->plat->pmu_isolation)
> + sphy->plat->pmu_isolation(true);
> +
> + /* Disable the phy clock */
> + samsung_usbphy_clk_control(sphy, false);
> +}
> +
> +static const struct of_device_id samsung_usbphy_dt_match[];
> +
> +static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
> +{
> +#ifdef CONFIG_OF
> + int data;
> + if (pdev->dev.of_node) {
> + const struct of_device_id *match;
> + match = of_match_node(samsung_usbphy_dt_match,
> + pdev->dev.of_node);
> + data = (int) match->data;
> + return data;
> + }
> +#endif
> + 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;
> + int ret;
> +
> + 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;
> +
> + sphy->dev = &pdev->dev;
> + sphy->plat = pdata;
> + sphy->regs = phy_base;
> + 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);
> +
> + ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
> + if (ret)
> + goto err;
> +
> + platform_set_drvdata(pdev, sphy);
> +
> + dev_info(&pdev->dev, "Initialized samsung USB OTG PHY module\n");
please avoid dev_info() at the end of probe. It just makes booting
noisier.
> +err:
> + 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);
> +
> + if (sphy->clk) {
> + clk_put(sphy->clk);
> + sphy->clk = NULL;
> + }
> +
> + 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/drivers/usb/phy/samsung-usbphy.h b/drivers/usb/phy/samsung-usbphy.h
> new file mode 100644
> index 0000000..093b1dc
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.h
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + * Author: Yulgon Kim <yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + * Author: Joonyoung Shim <jy0922.shim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + *
> + * 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_H
> +#define __SAMSUNG_USBPHY_H
> +
> +#define S3C_PHYPWR (0x00)
> +
> +#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
> +#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
> +#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
> +#define S3C_PHYPWR_FORCE_SUSPEND (1 << 1)
> +/* For Exynos4 */
> +#define EXYNOS4_PHYPWR_NORMAL_MASK (0x39 << 0)
> +#define EXYNOS4_PHYPWR_SLEEP (1 << 5)
> +
> +#define S3C_PHYCLK (0x04)
> +
> +#define S3C_PHYCLK_MODE_SERIAL (1 << 6)
> +#define S3C_PHYCLK_EXT_OSC (1 << 5)
> +#define S3C_PHYCLK_COMMON_ON_N (1 << 4)
> +#define S3C_PHYCLK_ID_PULL (1 << 2)
> +#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
> +#define S3C_PHYCLK_CLKSEL_SHIFT (0)
> +#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
> +#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
> +#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
> +
> +#define S3C_RSTCON (0x08)
> +
> +#define S3C_RSTCON_PHYCLK (1 << 2)
> +#define S3C_RSTCON_HCLK (1 << 1)
> +#define S3C_RSTCON_PHY (1 << 0)
> +
> +#ifndef MHZ
> +#define MHZ (1000*1000)
> +#endif
this header is so small that it doesn't make sense to have it. pleae
move these macros to C source file itself ;-)
--
balbi
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 192 bytes --]
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-08-10 7:04 ` Felipe Balbi
0 siblings, 0 replies; 27+ messages in thread
From: Felipe Balbi @ 2012-08-10 7:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
On Fri, Aug 10, 2012 at 12:40:27PM +0530, Praveen Paneri wrote:
> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
> phy_init and phy_shutdown functions to enable/disable phy. Tested with
> smdk6410 and smdkv310. More SoCs can be brought under later.
>
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Acked-by: Heiko Stuebner <heiko@sntech.de>
this looks good. Just 2 comments below.
> ---
> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
> drivers/usb/phy/Kconfig | 8 +
> drivers/usb/phy/Makefile | 1 +
> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
> drivers/usb/phy/samsung-usbphy.h | 48 +++
> include/linux/platform_data/samsung-usbphy.h | 27 ++
> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
> 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..fefd9c8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,9 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +
> +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 e7cf84f..d916477 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -15,3 +15,11 @@ config USB_ISP1301
>
> To compile this driver as a module, choose M here: the
> module will be called isp1301.
> +
> +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 eca095b..dfca70d 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -5,3 +5,4 @@
> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>
> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,345 @@
> +/* 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> +*/
> +
> +#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>
> +
> +#include "samsung-usbphy.h"
> +
> +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
> + * @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 cpu_type;
> +};
> +
> +#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
> +
> +/*
> + * Enables or disables the phy clock
> + * returns 0 on success else the error
> + */
> +static int samsung_usbphy_clk_control(struct samsung_usbphy *sphy, bool on)
> +{
> + if (on) {
> + if (!sphy->clk) {
> + sphy->clk = clk_get(sphy->dev, "otg");
> + if (IS_ERR(sphy->clk)) {
> + dev_err(sphy->dev, "Failed to get otg clock\n");
> + return PTR_ERR(sphy->clk);
> + }
> + }
> + clk_enable(sphy->clk);
> + } else {
> + clk_disable(sphy->clk);
> + clk_put(sphy->clk);
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Returns reference clock frequency
> + */
> +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 |= S3C_PHYCLK_CLKSEL_12M;
> + break;
> + case 24 * MHZ:
> + refclk_freq |= S3C_PHYCLK_CLKSEL_24M;
> + break;
> + default:
> + case 48 * MHZ:
> + /* default reference clock */
> + refclk_freq |= S3C_PHYCLK_CLKSEL_48M;
> + 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 = samsung_usbphy_get_refclk_freq(sphy);
> + phypwr = readl(regs + S3C_PHYPWR);
> + rstcon = readl(regs + S3C_RSTCON);
> +
> + switch (sphy->cpu_type) {
> + case TYPE_S3C64XX:
> + phyclk &= ~(S3C_PHYCLK_COMMON_ON_N);
> + phypwr &= ~S3C_PHYPWR_NORMAL_MASK;
> + rstcon |= S3C_RSTCON_PHY;
> + break;
> + case TYPE_EXYNOS4210:
> + phypwr &= ~EXYNOS4_PHYPWR_NORMAL_MASK;
> + rstcon |= S3C_RSTCON_PHY;
> + default:
> + break;
> + }
> +
> + writel(phyclk, regs + S3C_PHYCLK);
> + /* set to normal of PHY0 */
> + writel(phypwr, regs + S3C_PHYPWR);
> + /* reset all ports of PHY and Link */
> + writel(rstcon, regs + S3C_RSTCON);
> + udelay(10);
> + rstcon &= ~S3C_RSTCON_PHY;
> + writel(rstcon, regs + S3C_RSTCON);
> +}
> +
> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> + void __iomem *regs = sphy->regs;
> + u32 phypwr;
> +
> + phypwr = readl(regs + S3C_PHYPWR);
> +
> + switch (sphy->cpu_type) {
> + case TYPE_S3C64XX:
> + phypwr |= S3C_PHYPWR_NORMAL_MASK;
> + break;
> + case TYPE_EXYNOS4210:
> + phypwr |= EXYNOS4_PHYPWR_NORMAL_MASK;
> + default:
> + break;
> + }
> +
> + /* unset to normal of PHY0 */
> + writel(phypwr, regs + S3C_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 = samsung_usbphy_clk_control(sphy, true);
> + if (ret) {
> + dev_err(sphy->dev, "phy clock enable failed\n");
> + 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);
> + 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);
> +
> + /* De-initialize usb phy registers */
> + samsung_usbphy_disable(sphy);
> +
> + /* Enable phy isolation */
> + if (sphy->plat && sphy->plat->pmu_isolation)
> + sphy->plat->pmu_isolation(true);
> +
> + /* Disable the phy clock */
> + samsung_usbphy_clk_control(sphy, false);
> +}
> +
> +static const struct of_device_id samsung_usbphy_dt_match[];
> +
> +static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
> +{
> +#ifdef CONFIG_OF
> + int data;
> + if (pdev->dev.of_node) {
> + const struct of_device_id *match;
> + match = of_match_node(samsung_usbphy_dt_match,
> + pdev->dev.of_node);
> + data = (int) match->data;
> + return data;
> + }
> +#endif
> + 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;
> + int ret;
> +
> + 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;
> +
> + sphy->dev = &pdev->dev;
> + sphy->plat = pdata;
> + sphy->regs = phy_base;
> + 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);
> +
> + ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
> + if (ret)
> + goto err;
> +
> + platform_set_drvdata(pdev, sphy);
> +
> + dev_info(&pdev->dev, "Initialized samsung USB OTG PHY module\n");
please avoid dev_info() at the end of probe. It just makes booting
noisier.
> +err:
> + 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);
> +
> + if (sphy->clk) {
> + clk_put(sphy->clk);
> + sphy->clk = NULL;
> + }
> +
> + 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/drivers/usb/phy/samsung-usbphy.h b/drivers/usb/phy/samsung-usbphy.h
> new file mode 100644
> index 0000000..093b1dc
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.h
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + * Author: Yulgon Kim <yulgon.kim@samsung.com>
> + * Author: Joonyoung Shim <jy0922.shim@samsung.com>
> + * Author: Praveen Paneri <p.paneri@samsung.com>
> + *
> + * 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_H
> +#define __SAMSUNG_USBPHY_H
> +
> +#define S3C_PHYPWR (0x00)
> +
> +#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
> +#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
> +#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
> +#define S3C_PHYPWR_FORCE_SUSPEND (1 << 1)
> +/* For Exynos4 */
> +#define EXYNOS4_PHYPWR_NORMAL_MASK (0x39 << 0)
> +#define EXYNOS4_PHYPWR_SLEEP (1 << 5)
> +
> +#define S3C_PHYCLK (0x04)
> +
> +#define S3C_PHYCLK_MODE_SERIAL (1 << 6)
> +#define S3C_PHYCLK_EXT_OSC (1 << 5)
> +#define S3C_PHYCLK_COMMON_ON_N (1 << 4)
> +#define S3C_PHYCLK_ID_PULL (1 << 2)
> +#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
> +#define S3C_PHYCLK_CLKSEL_SHIFT (0)
> +#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
> +#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
> +#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
> +
> +#define S3C_RSTCON (0x08)
> +
> +#define S3C_RSTCON_PHYCLK (1 << 2)
> +#define S3C_RSTCON_HCLK (1 << 1)
> +#define S3C_RSTCON_PHY (1 << 0)
> +
> +#ifndef MHZ
> +#define MHZ (1000*1000)
> +#endif
this header is so small that it doesn't make sense to have it. pleae
move these macros to C source file itself ;-)
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120810/60f0d152/attachment-0001.sig>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
2012-08-10 7:04 ` Felipe Balbi
@ 2012-08-10 7:16 ` Praveen Paneri
-1 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:16 UTC (permalink / raw)
To: balbi
Cc: linux-usb, devicetree-discuss, linux-arm-kernel,
linux-samsung-soc, kgene.kim, gregkh, thomas.abraham, ben-linux,
broonie, l.majewski, kyungmin.park, grant.likely, heiko
On Fri, Aug 10, 2012 at 12:34 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Fri, Aug 10, 2012 at 12:40:27PM +0530, Praveen Paneri wrote:
>> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
>> phy_init and phy_shutdown functions to enable/disable phy. Tested with
>> smdk6410 and smdkv310. More SoCs can be brought under later.
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Acked-by: Heiko Stuebner <heiko@sntech.de>
>
> this looks good. Just 2 comments below.
>
>> ---
>> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
>> drivers/usb/phy/Kconfig | 8 +
>> drivers/usb/phy/Makefile | 1 +
>> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
>> drivers/usb/phy/samsung-usbphy.h | 48 +++
>> include/linux/platform_data/samsung-usbphy.h | 27 ++
>> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
>> 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..fefd9c8
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> @@ -0,0 +1,9 @@
>> +* Samsung's usb phy transceiver
>> +
>> +The Samsung's phy transceiver is used for controlling usb otg phy for
>> +s3c-hsotg usb device controller.
>> +
>> +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 e7cf84f..d916477 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -15,3 +15,11 @@ config USB_ISP1301
>>
>> To compile this driver as a module, choose M here: the
>> module will be called isp1301.
>> +
>> +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 eca095b..dfca70d 100644
>> --- a/drivers/usb/phy/Makefile
>> +++ b/drivers/usb/phy/Makefile
>> @@ -5,3 +5,4 @@
>> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>>
>> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.c
>> @@ -0,0 +1,345 @@
>> +/* 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.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>> +*/
>> +
>> +#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>
>> +
>> +#include "samsung-usbphy.h"
>> +
>> +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
>> + * @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 cpu_type;
>> +};
>> +
>> +#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
>> +
>> +/*
>> + * Enables or disables the phy clock
>> + * returns 0 on success else the error
>> + */
>> +static int samsung_usbphy_clk_control(struct samsung_usbphy *sphy, bool on)
>> +{
>> + if (on) {
>> + if (!sphy->clk) {
>> + sphy->clk = clk_get(sphy->dev, "otg");
>> + if (IS_ERR(sphy->clk)) {
>> + dev_err(sphy->dev, "Failed to get otg clock\n");
>> + return PTR_ERR(sphy->clk);
>> + }
>> + }
>> + clk_enable(sphy->clk);
>> + } else {
>> + clk_disable(sphy->clk);
>> + clk_put(sphy->clk);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Returns reference clock frequency
>> + */
>> +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 |= S3C_PHYCLK_CLKSEL_12M;
>> + break;
>> + case 24 * MHZ:
>> + refclk_freq |= S3C_PHYCLK_CLKSEL_24M;
>> + break;
>> + default:
>> + case 48 * MHZ:
>> + /* default reference clock */
>> + refclk_freq |= S3C_PHYCLK_CLKSEL_48M;
>> + 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 = samsung_usbphy_get_refclk_freq(sphy);
>> + phypwr = readl(regs + S3C_PHYPWR);
>> + rstcon = readl(regs + S3C_RSTCON);
>> +
>> + switch (sphy->cpu_type) {
>> + case TYPE_S3C64XX:
>> + phyclk &= ~(S3C_PHYCLK_COMMON_ON_N);
>> + phypwr &= ~S3C_PHYPWR_NORMAL_MASK;
>> + rstcon |= S3C_RSTCON_PHY;
>> + break;
>> + case TYPE_EXYNOS4210:
>> + phypwr &= ~EXYNOS4_PHYPWR_NORMAL_MASK;
>> + rstcon |= S3C_RSTCON_PHY;
>> + default:
>> + break;
>> + }
>> +
>> + writel(phyclk, regs + S3C_PHYCLK);
>> + /* set to normal of PHY0 */
>> + writel(phypwr, regs + S3C_PHYPWR);
>> + /* reset all ports of PHY and Link */
>> + writel(rstcon, regs + S3C_RSTCON);
>> + udelay(10);
>> + rstcon &= ~S3C_RSTCON_PHY;
>> + writel(rstcon, regs + S3C_RSTCON);
>> +}
>> +
>> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>> +{
>> + void __iomem *regs = sphy->regs;
>> + u32 phypwr;
>> +
>> + phypwr = readl(regs + S3C_PHYPWR);
>> +
>> + switch (sphy->cpu_type) {
>> + case TYPE_S3C64XX:
>> + phypwr |= S3C_PHYPWR_NORMAL_MASK;
>> + break;
>> + case TYPE_EXYNOS4210:
>> + phypwr |= EXYNOS4_PHYPWR_NORMAL_MASK;
>> + default:
>> + break;
>> + }
>> +
>> + /* unset to normal of PHY0 */
>> + writel(phypwr, regs + S3C_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 = samsung_usbphy_clk_control(sphy, true);
>> + if (ret) {
>> + dev_err(sphy->dev, "phy clock enable failed\n");
>> + 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);
>> + 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);
>> +
>> + /* De-initialize usb phy registers */
>> + samsung_usbphy_disable(sphy);
>> +
>> + /* Enable phy isolation */
>> + if (sphy->plat && sphy->plat->pmu_isolation)
>> + sphy->plat->pmu_isolation(true);
>> +
>> + /* Disable the phy clock */
>> + samsung_usbphy_clk_control(sphy, false);
>> +}
>> +
>> +static const struct of_device_id samsung_usbphy_dt_match[];
>> +
>> +static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
>> +{
>> +#ifdef CONFIG_OF
>> + int data;
>> + if (pdev->dev.of_node) {
>> + const struct of_device_id *match;
>> + match = of_match_node(samsung_usbphy_dt_match,
>> + pdev->dev.of_node);
>> + data = (int) match->data;
>> + return data;
>> + }
>> +#endif
>> + 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;
>> + int ret;
>> +
>> + 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;
>> +
>> + sphy->dev = &pdev->dev;
>> + sphy->plat = pdata;
>> + sphy->regs = phy_base;
>> + 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);
>> +
>> + ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>> + if (ret)
>> + goto err;
>> +
>> + platform_set_drvdata(pdev, sphy);
>> +
>> + dev_info(&pdev->dev, "Initialized samsung USB OTG PHY module\n");
>
> please avoid dev_info() at the end of probe. It just makes booting
> noisier.
>
>> +err:
>> + 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);
>> +
>> + if (sphy->clk) {
>> + clk_put(sphy->clk);
>> + sphy->clk = NULL;
>> + }
>> +
>> + 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/drivers/usb/phy/samsung-usbphy.h b/drivers/usb/phy/samsung-usbphy.h
>> new file mode 100644
>> index 0000000..093b1dc
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.h
>> @@ -0,0 +1,48 @@
>> +/*
>> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
>> + * Author: Yulgon Kim <yulgon.kim@samsung.com>
>> + * Author: Joonyoung Shim <jy0922.shim@samsung.com>
>> + * Author: Praveen Paneri <p.paneri@samsung.com>
>> + *
>> + * 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_H
>> +#define __SAMSUNG_USBPHY_H
>> +
>> +#define S3C_PHYPWR (0x00)
>> +
>> +#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
>> +#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
>> +#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
>> +#define S3C_PHYPWR_FORCE_SUSPEND (1 << 1)
>> +/* For Exynos4 */
>> +#define EXYNOS4_PHYPWR_NORMAL_MASK (0x39 << 0)
>> +#define EXYNOS4_PHYPWR_SLEEP (1 << 5)
>> +
>> +#define S3C_PHYCLK (0x04)
>> +
>> +#define S3C_PHYCLK_MODE_SERIAL (1 << 6)
>> +#define S3C_PHYCLK_EXT_OSC (1 << 5)
>> +#define S3C_PHYCLK_COMMON_ON_N (1 << 4)
>> +#define S3C_PHYCLK_ID_PULL (1 << 2)
>> +#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
>> +#define S3C_PHYCLK_CLKSEL_SHIFT (0)
>> +#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
>> +#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
>> +#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
>> +
>> +#define S3C_RSTCON (0x08)
>> +
>> +#define S3C_RSTCON_PHYCLK (1 << 2)
>> +#define S3C_RSTCON_HCLK (1 << 1)
>> +#define S3C_RSTCON_PHY (1 << 0)
>> +
>> +#ifndef MHZ
>> +#define MHZ (1000*1000)
>> +#endif
>
> this header is so small that it doesn't make sense to have it. pleae
> move these macros to C source file itself ;-)
Thanks! I will do that.
Praveen
>
> --
> balbi
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-08-10 7:16 ` Praveen Paneri
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:16 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Aug 10, 2012 at 12:34 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Fri, Aug 10, 2012 at 12:40:27PM +0530, Praveen Paneri wrote:
>> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
>> phy_init and phy_shutdown functions to enable/disable phy. Tested with
>> smdk6410 and smdkv310. More SoCs can be brought under later.
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Acked-by: Heiko Stuebner <heiko@sntech.de>
>
> this looks good. Just 2 comments below.
>
>> ---
>> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
>> drivers/usb/phy/Kconfig | 8 +
>> drivers/usb/phy/Makefile | 1 +
>> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
>> drivers/usb/phy/samsung-usbphy.h | 48 +++
>> include/linux/platform_data/samsung-usbphy.h | 27 ++
>> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
>> 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..fefd9c8
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> @@ -0,0 +1,9 @@
>> +* Samsung's usb phy transceiver
>> +
>> +The Samsung's phy transceiver is used for controlling usb otg phy for
>> +s3c-hsotg usb device controller.
>> +
>> +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 e7cf84f..d916477 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -15,3 +15,11 @@ config USB_ISP1301
>>
>> To compile this driver as a module, choose M here: the
>> module will be called isp1301.
>> +
>> +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 eca095b..dfca70d 100644
>> --- a/drivers/usb/phy/Makefile
>> +++ b/drivers/usb/phy/Makefile
>> @@ -5,3 +5,4 @@
>> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>>
>> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.c
>> @@ -0,0 +1,345 @@
>> +/* 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.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>> +*/
>> +
>> +#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>
>> +
>> +#include "samsung-usbphy.h"
>> +
>> +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
>> + * @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 cpu_type;
>> +};
>> +
>> +#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
>> +
>> +/*
>> + * Enables or disables the phy clock
>> + * returns 0 on success else the error
>> + */
>> +static int samsung_usbphy_clk_control(struct samsung_usbphy *sphy, bool on)
>> +{
>> + if (on) {
>> + if (!sphy->clk) {
>> + sphy->clk = clk_get(sphy->dev, "otg");
>> + if (IS_ERR(sphy->clk)) {
>> + dev_err(sphy->dev, "Failed to get otg clock\n");
>> + return PTR_ERR(sphy->clk);
>> + }
>> + }
>> + clk_enable(sphy->clk);
>> + } else {
>> + clk_disable(sphy->clk);
>> + clk_put(sphy->clk);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Returns reference clock frequency
>> + */
>> +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 |= S3C_PHYCLK_CLKSEL_12M;
>> + break;
>> + case 24 * MHZ:
>> + refclk_freq |= S3C_PHYCLK_CLKSEL_24M;
>> + break;
>> + default:
>> + case 48 * MHZ:
>> + /* default reference clock */
>> + refclk_freq |= S3C_PHYCLK_CLKSEL_48M;
>> + 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 = samsung_usbphy_get_refclk_freq(sphy);
>> + phypwr = readl(regs + S3C_PHYPWR);
>> + rstcon = readl(regs + S3C_RSTCON);
>> +
>> + switch (sphy->cpu_type) {
>> + case TYPE_S3C64XX:
>> + phyclk &= ~(S3C_PHYCLK_COMMON_ON_N);
>> + phypwr &= ~S3C_PHYPWR_NORMAL_MASK;
>> + rstcon |= S3C_RSTCON_PHY;
>> + break;
>> + case TYPE_EXYNOS4210:
>> + phypwr &= ~EXYNOS4_PHYPWR_NORMAL_MASK;
>> + rstcon |= S3C_RSTCON_PHY;
>> + default:
>> + break;
>> + }
>> +
>> + writel(phyclk, regs + S3C_PHYCLK);
>> + /* set to normal of PHY0 */
>> + writel(phypwr, regs + S3C_PHYPWR);
>> + /* reset all ports of PHY and Link */
>> + writel(rstcon, regs + S3C_RSTCON);
>> + udelay(10);
>> + rstcon &= ~S3C_RSTCON_PHY;
>> + writel(rstcon, regs + S3C_RSTCON);
>> +}
>> +
>> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>> +{
>> + void __iomem *regs = sphy->regs;
>> + u32 phypwr;
>> +
>> + phypwr = readl(regs + S3C_PHYPWR);
>> +
>> + switch (sphy->cpu_type) {
>> + case TYPE_S3C64XX:
>> + phypwr |= S3C_PHYPWR_NORMAL_MASK;
>> + break;
>> + case TYPE_EXYNOS4210:
>> + phypwr |= EXYNOS4_PHYPWR_NORMAL_MASK;
>> + default:
>> + break;
>> + }
>> +
>> + /* unset to normal of PHY0 */
>> + writel(phypwr, regs + S3C_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 = samsung_usbphy_clk_control(sphy, true);
>> + if (ret) {
>> + dev_err(sphy->dev, "phy clock enable failed\n");
>> + 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);
>> + 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);
>> +
>> + /* De-initialize usb phy registers */
>> + samsung_usbphy_disable(sphy);
>> +
>> + /* Enable phy isolation */
>> + if (sphy->plat && sphy->plat->pmu_isolation)
>> + sphy->plat->pmu_isolation(true);
>> +
>> + /* Disable the phy clock */
>> + samsung_usbphy_clk_control(sphy, false);
>> +}
>> +
>> +static const struct of_device_id samsung_usbphy_dt_match[];
>> +
>> +static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
>> +{
>> +#ifdef CONFIG_OF
>> + int data;
>> + if (pdev->dev.of_node) {
>> + const struct of_device_id *match;
>> + match = of_match_node(samsung_usbphy_dt_match,
>> + pdev->dev.of_node);
>> + data = (int) match->data;
>> + return data;
>> + }
>> +#endif
>> + 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;
>> + int ret;
>> +
>> + 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;
>> +
>> + sphy->dev = &pdev->dev;
>> + sphy->plat = pdata;
>> + sphy->regs = phy_base;
>> + 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);
>> +
>> + ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>> + if (ret)
>> + goto err;
>> +
>> + platform_set_drvdata(pdev, sphy);
>> +
>> + dev_info(&pdev->dev, "Initialized samsung USB OTG PHY module\n");
>
> please avoid dev_info() at the end of probe. It just makes booting
> noisier.
>
>> +err:
>> + 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);
>> +
>> + if (sphy->clk) {
>> + clk_put(sphy->clk);
>> + sphy->clk = NULL;
>> + }
>> +
>> + 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/drivers/usb/phy/samsung-usbphy.h b/drivers/usb/phy/samsung-usbphy.h
>> new file mode 100644
>> index 0000000..093b1dc
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.h
>> @@ -0,0 +1,48 @@
>> +/*
>> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
>> + * Author: Yulgon Kim <yulgon.kim@samsung.com>
>> + * Author: Joonyoung Shim <jy0922.shim@samsung.com>
>> + * Author: Praveen Paneri <p.paneri@samsung.com>
>> + *
>> + * 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_H
>> +#define __SAMSUNG_USBPHY_H
>> +
>> +#define S3C_PHYPWR (0x00)
>> +
>> +#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
>> +#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
>> +#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
>> +#define S3C_PHYPWR_FORCE_SUSPEND (1 << 1)
>> +/* For Exynos4 */
>> +#define EXYNOS4_PHYPWR_NORMAL_MASK (0x39 << 0)
>> +#define EXYNOS4_PHYPWR_SLEEP (1 << 5)
>> +
>> +#define S3C_PHYCLK (0x04)
>> +
>> +#define S3C_PHYCLK_MODE_SERIAL (1 << 6)
>> +#define S3C_PHYCLK_EXT_OSC (1 << 5)
>> +#define S3C_PHYCLK_COMMON_ON_N (1 << 4)
>> +#define S3C_PHYCLK_ID_PULL (1 << 2)
>> +#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
>> +#define S3C_PHYCLK_CLKSEL_SHIFT (0)
>> +#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
>> +#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
>> +#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
>> +
>> +#define S3C_RSTCON (0x08)
>> +
>> +#define S3C_RSTCON_PHYCLK (1 << 2)
>> +#define S3C_RSTCON_HCLK (1 << 1)
>> +#define S3C_RSTCON_PHY (1 << 0)
>> +
>> +#ifndef MHZ
>> +#define MHZ (1000*1000)
>> +#endif
>
> this header is so small that it doesn't make sense to have it. pleae
> move these macros to C source file itself ;-)
Thanks! I will do that.
Praveen
>
> --
> balbi
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
2012-08-10 7:10 ` Praveen Paneri
@ 2012-08-10 7:19 ` ABRAHAM, KISHON VIJAY
-1 siblings, 0 replies; 27+ messages in thread
From: ABRAHAM, KISHON VIJAY @ 2012-08-10 7:19 UTC (permalink / raw)
To: Praveen Paneri
Cc: linux-usb, devicetree-discuss, linux-arm-kernel,
linux-samsung-soc, kgene.kim, balbi, gregkh, thomas.abraham,
ben-linux, broonie, l.majewski, kyungmin.park, grant.likely,
heiko
Hi,
On Fri, Aug 10, 2012 at 12:40 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 phy. Tested with
> smdk6410 and smdkv310. More SoCs can be brought under later.
>
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Acked-by: Heiko Stuebner <heiko@sntech.de>
> ---
> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
> drivers/usb/phy/Kconfig | 8 +
> drivers/usb/phy/Makefile | 1 +
> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
> drivers/usb/phy/samsung-usbphy.h | 48 +++
> include/linux/platform_data/samsung-usbphy.h | 27 ++
> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
> 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..fefd9c8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,9 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +
> +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 e7cf84f..d916477 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -15,3 +15,11 @@ config USB_ISP1301
>
> To compile this driver as a module, choose M here: the
> module will be called isp1301.
> +
> +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 eca095b..dfca70d 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -5,3 +5,4 @@
> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>
> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,345 @@
> +/* 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
I suggest you drop that last paragraph unless you want to keep track
of Free Software Foundation office. Right now it is 51 Franklin
Street, Boston (http://www.fsf.org/about/contact/) :-)
-Kishon
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-08-10 7:19 ` ABRAHAM, KISHON VIJAY
0 siblings, 0 replies; 27+ messages in thread
From: ABRAHAM, KISHON VIJAY @ 2012-08-10 7:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
On Fri, Aug 10, 2012 at 12:40 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 phy. Tested with
> smdk6410 and smdkv310. More SoCs can be brought under later.
>
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Acked-by: Heiko Stuebner <heiko@sntech.de>
> ---
> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
> drivers/usb/phy/Kconfig | 8 +
> drivers/usb/phy/Makefile | 1 +
> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
> drivers/usb/phy/samsung-usbphy.h | 48 +++
> include/linux/platform_data/samsung-usbphy.h | 27 ++
> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
> 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..fefd9c8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,9 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +
> +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 e7cf84f..d916477 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -15,3 +15,11 @@ config USB_ISP1301
>
> To compile this driver as a module, choose M here: the
> module will be called isp1301.
> +
> +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 eca095b..dfca70d 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -5,3 +5,4 @@
> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>
> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,345 @@
> +/* 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
I suggest you drop that last paragraph unless you want to keep track
of Free Software Foundation office. Right now it is 51 Franklin
Street, Boston (http://www.fsf.org/about/contact/) :-)
-Kishon
^ permalink raw reply [flat|nested] 27+ messages in thread
[parent not found: <CAAe_U6K=h7gP+fTQTkzP_WQfccVMYhG+UtsLprDMrsozuBywoQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
2012-08-10 7:19 ` ABRAHAM, KISHON VIJAY
@ 2012-08-10 7:36 ` Praveen Paneri
-1 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:36 UTC (permalink / raw)
To: ABRAHAM, KISHON VIJAY
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
On Fri, Aug 10, 2012 at 12:49 PM, ABRAHAM, KISHON VIJAY <kishon-l0cyMroinI0@public.gmane.org> wrote:
> Hi,
>
> On Fri, Aug 10, 2012 at 12:40 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 phy. Tested with
>> smdk6410 and smdkv310. More SoCs can be brought under later.
>>
>> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>> Acked-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
>> ---
>> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
>> drivers/usb/phy/Kconfig | 8 +
>> drivers/usb/phy/Makefile | 1 +
>> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
>> drivers/usb/phy/samsung-usbphy.h | 48 +++
>> include/linux/platform_data/samsung-usbphy.h | 27 ++
>> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
>> 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..fefd9c8
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> @@ -0,0 +1,9 @@
>> +* Samsung's usb phy transceiver
>> +
>> +The Samsung's phy transceiver is used for controlling usb otg phy for
>> +s3c-hsotg usb device controller.
>> +
>> +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 e7cf84f..d916477 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -15,3 +15,11 @@ config USB_ISP1301
>>
>> To compile this driver as a module, choose M here: the
>> module will be called isp1301.
>> +
>> +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 eca095b..dfca70d 100644
>> --- a/drivers/usb/phy/Makefile
>> +++ b/drivers/usb/phy/Makefile
>> @@ -5,3 +5,4 @@
>> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>>
>> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.c
>> @@ -0,0 +1,345 @@
>> +/* 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.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>
> I suggest you drop that last paragraph unless you want to keep track
> of Free Software Foundation office. Right now it is 51 Franklin
> Street, Boston (http://www.fsf.org/about/contact/) :-)
Yeah! it can be dropped :-)
Praveen
>
> -Kishon
> --
> 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
--
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] 27+ messages in thread
* [PATCH v4 1/5] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-08-10 7:36 ` Praveen Paneri
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:36 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Aug 10, 2012 at 12:49 PM, ABRAHAM, KISHON VIJAY <kishon@ti.com> wrote:
> Hi,
>
> On Fri, Aug 10, 2012 at 12:40 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 phy. Tested with
>> smdk6410 and smdkv310. More SoCs can be brought under later.
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Acked-by: Heiko Stuebner <heiko@sntech.de>
>> ---
>> .../devicetree/bindings/usb/samsung-usbphy.txt | 9 +
>> drivers/usb/phy/Kconfig | 8 +
>> drivers/usb/phy/Makefile | 1 +
>> drivers/usb/phy/samsung-usbphy.c | 345 ++++++++++++++++++++
>> drivers/usb/phy/samsung-usbphy.h | 48 +++
>> include/linux/platform_data/samsung-usbphy.h | 27 ++
>> 6 files changed, 438 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 drivers/usb/phy/samsung-usbphy.h
>> 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..fefd9c8
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> @@ -0,0 +1,9 @@
>> +* Samsung's usb phy transceiver
>> +
>> +The Samsung's phy transceiver is used for controlling usb otg phy for
>> +s3c-hsotg usb device controller.
>> +
>> +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 e7cf84f..d916477 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -15,3 +15,11 @@ config USB_ISP1301
>>
>> To compile this driver as a module, choose M here: the
>> module will be called isp1301.
>> +
>> +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 eca095b..dfca70d 100644
>> --- a/drivers/usb/phy/Makefile
>> +++ b/drivers/usb/phy/Makefile
>> @@ -5,3 +5,4 @@
>> ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
>>
>> obj-$(CONFIG_USB_ISP1301) += isp1301.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..739b6c9
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.c
>> @@ -0,0 +1,345 @@
>> +/* 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.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>
> I suggest you drop that last paragraph unless you want to keep track
> of Free Software Foundation office. Right now it is 51 Franklin
> Street, Boston (http://www.fsf.org/about/contact/) :-)
Yeah! it can be dropped :-)
Praveen
>
> -Kishon
> --
> 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] 27+ messages in thread
* [PATCH v4 2/5] usb: s3c-hsotg: Adding phy driver support
2012-08-10 7:10 ` Praveen Paneri
@ 2012-08-10 7:10 ` Praveen Paneri
-1 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 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
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>
---
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 b13e0bb..60f6160 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/otg.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;
}
+ plat = pdev->dev.platform_data;
+ if (!plat) {
+ /* Fallback for transceiver */
+ phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+ if (IS_ERR_OR_NULL(phy)) {
+ dev_err(&pdev->dev, "no platform data or transceiver defined\n");
+ return -EPROBE_DEFER;
+ } else {
+ hsotg->phy = phy;
+ }
+ } else {
+ hsotg->plat = plat;
+ }
+
hsotg->dev = dev;
- hsotg->plat = plat;
hsotg->clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(hsotg->clk)) {
--
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] 27+ messages in thread
* [PATCH v4 2/5] usb: s3c-hsotg: Adding phy driver support
@ 2012-08-10 7:10 ` Praveen Paneri
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 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>
---
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 b13e0bb..60f6160 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/otg.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;
}
+ plat = pdev->dev.platform_data;
+ if (!plat) {
+ /* Fallback for transceiver */
+ phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+ if (IS_ERR_OR_NULL(phy)) {
+ dev_err(&pdev->dev, "no platform data or transceiver defined\n");
+ return -EPROBE_DEFER;
+ } else {
+ hsotg->phy = phy;
+ }
+ } else {
+ hsotg->plat = plat;
+ }
+
hsotg->dev = dev;
- hsotg->plat = plat;
hsotg->clk = clk_get(&pdev->dev, "otg");
if (IS_ERR(hsotg->clk)) {
--
1.7.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v4 4/5] ARM: S3C64XX: Enabling samsung-usbphy driver
2012-08-10 7:10 ` Praveen Paneri
@ 2012-08-10 7:10 ` Praveen Paneri
-1 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 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
Adding platform device for samsung-usbphy driver. Enabling it for
s3c64xx based machines using s3c-hsotg.
Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
arch/arm/mach-s3c64xx/include/mach/map.h | 2 +
arch/arm/mach-s3c64xx/mach-crag6410.c | 4 +++
arch/arm/mach-s3c64xx/mach-smartq.c | 5 ++++
arch/arm/mach-s3c64xx/mach-smdk6410.c | 4 +++
arch/arm/mach-s3c64xx/setup-usb-phy.c | 14 +++++++++++
arch/arm/plat-samsung/devs.c | 33 ++++++++++++++++++++++++++
arch/arm/plat-samsung/include/plat/devs.h | 1 +
arch/arm/plat-samsung/include/plat/usb-phy.h | 1 +
8 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index 8e2097b..dc482bb 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -65,6 +65,7 @@
#define S3C64XX_PA_NAND (0x70200000)
#define S3C64XX_PA_FB (0x77100000)
+#define S3C64XX_PA_USB_HSPHY (0x7C100000)
#define S3C64XX_PA_USB_HSOTG (0x7C000000)
#define S3C64XX_PA_WATCHDOG (0x7E004000)
#define S3C64XX_PA_RTC (0x7E005000)
@@ -113,6 +114,7 @@
#define S3C_PA_FB S3C64XX_PA_FB
#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
+#define S3C_PA_USB_PHY S3C64XX_PA_USB_HSPHY
#define S3C_PA_RTC S3C64XX_PA_RTC
#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
#define S3C_PA_SPI0 S3C64XX_PA_SPI0
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index b0f5baf..a9c3b5e 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -31,6 +31,7 @@
#include <linux/spi/spi.h>
#include <linux/i2c/pca953x.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <video/platform_lcd.h>
@@ -336,6 +337,7 @@ static struct platform_device wallvdd_device = {
};
static struct platform_device *crag6410_devices[] __initdata = {
+ &samsung_device_usbphy,
&s3c_device_hsmmc0,
&s3c_device_hsmmc2,
&s3c_device_i2c0,
@@ -765,6 +767,7 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
.num_leds = ARRAY_SIZE(gpio_leds),
};
+static struct samsung_usbphy_data crag6410_usbphy_pdata;
static void __init crag6410_machine_init(void)
{
@@ -790,6 +793,7 @@ static void __init crag6410_machine_init(void)
s3c_i2c0_set_platdata(&i2c0_pdata);
s3c_i2c1_set_platdata(&i2c1_pdata);
s3c_fb_set_platdata(&crag6410_lcd_pdata);
+ samsung_usbphy_set_pdata(&crag6410_usbphy_pdata);
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index 7400da1..0e75c36 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -18,6 +18,7 @@
#include <linux/serial_core.h>
#include <linux/spi/spi_gpio.h>
#include <linux/usb/gpio_vbus.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -234,6 +235,7 @@ static struct i2c_board_info smartq_i2c_devs[] __initdata = {
};
static struct platform_device *smartq_devices[] __initdata = {
+ &samsung_device_usbphy,
&s3c_device_hsmmc1, /* Init iNAND first, ... */
&s3c_device_hsmmc0, /* ... then the external SD card */
&s3c_device_hsmmc2,
@@ -380,9 +382,12 @@ void __init smartq_map_io(void)
smartq_lcd_mode_set();
}
+static struct samsung_usbphy_data smartq_usbphy_pdata;
+
void __init smartq_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
+ samsung_usbphy_set_pdata(&smartq_usbphy_pdata);
s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index cbdc91b..6c2ee6d 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -30,6 +30,7 @@
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/pwm_backlight.h>
+#include <linux/platform_data/samsung-usbphy.h>
#ifdef CONFIG_SMDK6410_WM1190_EV1
#include <linux/mfd/wm8350/core.h>
@@ -263,6 +264,7 @@ static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
static struct map_desc smdk6410_iodesc[] = {};
static struct platform_device *smdk6410_devices[] __initdata = {
+ &samsung_device_usbphy,
#ifdef CONFIG_SMDK6410_SD_CH0
&s3c_device_hsmmc0,
#endif
@@ -626,6 +628,7 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
.pwm_id = 1,
};
+static struct samsung_usbphy_data smdk6410_usbphy_pdata;
static void __init smdk6410_map_io(void)
{
@@ -655,6 +658,7 @@ static void __init smdk6410_machine_init(void)
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+ samsung_usbphy_set_pdata(&smdk6410_usbphy_pdata);
samsung_keypad_set_platdata(&smdk6410_keypad_data);
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
index 7a09553..3aee778 100644
--- a/arch/arm/mach-s3c64xx/setup-usb-phy.c
+++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c
@@ -9,3 +9,17 @@
*
*/
+#include <linux/io.h>
+#include <mach/map.h>
+#include <mach/regs-sys.h>
+
+void s5p_usb_phy_pmu_isolation(int on)
+{
+ if (on) {
+ writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK,
+ S3C64XX_OTHERS);
+ } else {
+ writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK,
+ S3C64XX_OTHERS);
+ }
+}
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 74e31ce..9a796cb 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -31,6 +31,7 @@
#include <linux/ioport.h>
#include <linux/platform_data/s3c-hsudc.h>
#include <linux/platform_data/s3c-hsotg.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/irq.h>
#include <asm/pmu.h>
@@ -1343,6 +1344,35 @@ struct platform_device s5p_device_mixer = {
/* USB */
+#ifdef CONFIG_S3C_DEV_USB_HSOTG
+/* USB PHY*/
+static struct resource samsung_usbphy_resource[] = {
+ [0] = {
+ .start = S3C_PA_USB_PHY,
+ .end = S3C_PA_USB_PHY + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device samsung_device_usbphy = {
+ .name = "s3c64xx-usbphy",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(samsung_usbphy_resource),
+ .resource = samsung_usbphy_resource,
+};
+
+void __init samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd)
+{
+ struct samsung_usbphy_data *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct samsung_usbphy_data),
+ &samsung_device_usbphy);
+
+ if (!npd->pmu_isolation)
+ npd->pmu_isolation = s5p_usb_phy_pmu_isolation;
+}
+#endif
+
#ifdef CONFIG_S3C_DEV_USB_HOST
static struct resource s3c_usb_resource[] = {
[0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
@@ -1449,6 +1479,8 @@ struct platform_device s3c_device_usb_hsotg = {
},
};
+#ifndef CONFIG_ARCH_S3C64XX
+/* TODO: To be removed later. Currently only S3C64XX is platform data free */
void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
{
struct s3c_hsotg_plat *npd;
@@ -1461,6 +1493,7 @@ void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
if (!npd->phy_exit)
npd->phy_exit = s5p_usb_phy_exit;
}
+#endif
#endif /* CONFIG_S3C_DEV_USB_HSOTG */
/* USB High Spped 2.0 Device (Gadget) */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 5da4b4f..3849c88 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -138,6 +138,7 @@ extern struct platform_device exynos_device_drm;
extern struct platform_device samsung_asoc_dma;
extern struct platform_device samsung_asoc_idma;
extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_usbphy;
/* s3c2440 specific devices */
diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h
index 959bcdb..165ffe7 100644
--- a/arch/arm/plat-samsung/include/plat/usb-phy.h
+++ b/arch/arm/plat-samsung/include/plat/usb-phy.h
@@ -18,5 +18,6 @@ enum s5p_usb_phy_type {
extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+extern void s5p_usb_phy_pmu_isolation(int on);
#endif /* __PLAT_SAMSUNG_USB_PHY_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] 27+ messages in thread
* [PATCH v4 4/5] ARM: S3C64XX: Enabling samsung-usbphy driver
@ 2012-08-10 7:10 ` Praveen Paneri
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 UTC (permalink / raw)
To: linux-arm-kernel
Adding platform device for samsung-usbphy driver. Enabling it for
s3c64xx based machines using s3c-hsotg.
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
---
arch/arm/mach-s3c64xx/include/mach/map.h | 2 +
arch/arm/mach-s3c64xx/mach-crag6410.c | 4 +++
arch/arm/mach-s3c64xx/mach-smartq.c | 5 ++++
arch/arm/mach-s3c64xx/mach-smdk6410.c | 4 +++
arch/arm/mach-s3c64xx/setup-usb-phy.c | 14 +++++++++++
arch/arm/plat-samsung/devs.c | 33 ++++++++++++++++++++++++++
arch/arm/plat-samsung/include/plat/devs.h | 1 +
arch/arm/plat-samsung/include/plat/usb-phy.h | 1 +
8 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index 8e2097b..dc482bb 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -65,6 +65,7 @@
#define S3C64XX_PA_NAND (0x70200000)
#define S3C64XX_PA_FB (0x77100000)
+#define S3C64XX_PA_USB_HSPHY (0x7C100000)
#define S3C64XX_PA_USB_HSOTG (0x7C000000)
#define S3C64XX_PA_WATCHDOG (0x7E004000)
#define S3C64XX_PA_RTC (0x7E005000)
@@ -113,6 +114,7 @@
#define S3C_PA_FB S3C64XX_PA_FB
#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
+#define S3C_PA_USB_PHY S3C64XX_PA_USB_HSPHY
#define S3C_PA_RTC S3C64XX_PA_RTC
#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
#define S3C_PA_SPI0 S3C64XX_PA_SPI0
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index b0f5baf..a9c3b5e 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -31,6 +31,7 @@
#include <linux/spi/spi.h>
#include <linux/i2c/pca953x.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <video/platform_lcd.h>
@@ -336,6 +337,7 @@ static struct platform_device wallvdd_device = {
};
static struct platform_device *crag6410_devices[] __initdata = {
+ &samsung_device_usbphy,
&s3c_device_hsmmc0,
&s3c_device_hsmmc2,
&s3c_device_i2c0,
@@ -765,6 +767,7 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
.num_leds = ARRAY_SIZE(gpio_leds),
};
+static struct samsung_usbphy_data crag6410_usbphy_pdata;
static void __init crag6410_machine_init(void)
{
@@ -790,6 +793,7 @@ static void __init crag6410_machine_init(void)
s3c_i2c0_set_platdata(&i2c0_pdata);
s3c_i2c1_set_platdata(&i2c1_pdata);
s3c_fb_set_platdata(&crag6410_lcd_pdata);
+ samsung_usbphy_set_pdata(&crag6410_usbphy_pdata);
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index 7400da1..0e75c36 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -18,6 +18,7 @@
#include <linux/serial_core.h>
#include <linux/spi/spi_gpio.h>
#include <linux/usb/gpio_vbus.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -234,6 +235,7 @@ static struct i2c_board_info smartq_i2c_devs[] __initdata = {
};
static struct platform_device *smartq_devices[] __initdata = {
+ &samsung_device_usbphy,
&s3c_device_hsmmc1, /* Init iNAND first, ... */
&s3c_device_hsmmc0, /* ... then the external SD card */
&s3c_device_hsmmc2,
@@ -380,9 +382,12 @@ void __init smartq_map_io(void)
smartq_lcd_mode_set();
}
+static struct samsung_usbphy_data smartq_usbphy_pdata;
+
void __init smartq_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
+ samsung_usbphy_set_pdata(&smartq_usbphy_pdata);
s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index cbdc91b..6c2ee6d 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -30,6 +30,7 @@
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/pwm_backlight.h>
+#include <linux/platform_data/samsung-usbphy.h>
#ifdef CONFIG_SMDK6410_WM1190_EV1
#include <linux/mfd/wm8350/core.h>
@@ -263,6 +264,7 @@ static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
static struct map_desc smdk6410_iodesc[] = {};
static struct platform_device *smdk6410_devices[] __initdata = {
+ &samsung_device_usbphy,
#ifdef CONFIG_SMDK6410_SD_CH0
&s3c_device_hsmmc0,
#endif
@@ -626,6 +628,7 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
.pwm_id = 1,
};
+static struct samsung_usbphy_data smdk6410_usbphy_pdata;
static void __init smdk6410_map_io(void)
{
@@ -655,6 +658,7 @@ static void __init smdk6410_machine_init(void)
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+ samsung_usbphy_set_pdata(&smdk6410_usbphy_pdata);
samsung_keypad_set_platdata(&smdk6410_keypad_data);
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
index 7a09553..3aee778 100644
--- a/arch/arm/mach-s3c64xx/setup-usb-phy.c
+++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c
@@ -9,3 +9,17 @@
*
*/
+#include <linux/io.h>
+#include <mach/map.h>
+#include <mach/regs-sys.h>
+
+void s5p_usb_phy_pmu_isolation(int on)
+{
+ if (on) {
+ writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK,
+ S3C64XX_OTHERS);
+ } else {
+ writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK,
+ S3C64XX_OTHERS);
+ }
+}
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 74e31ce..9a796cb 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -31,6 +31,7 @@
#include <linux/ioport.h>
#include <linux/platform_data/s3c-hsudc.h>
#include <linux/platform_data/s3c-hsotg.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/irq.h>
#include <asm/pmu.h>
@@ -1343,6 +1344,35 @@ struct platform_device s5p_device_mixer = {
/* USB */
+#ifdef CONFIG_S3C_DEV_USB_HSOTG
+/* USB PHY*/
+static struct resource samsung_usbphy_resource[] = {
+ [0] = {
+ .start = S3C_PA_USB_PHY,
+ .end = S3C_PA_USB_PHY + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device samsung_device_usbphy = {
+ .name = "s3c64xx-usbphy",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(samsung_usbphy_resource),
+ .resource = samsung_usbphy_resource,
+};
+
+void __init samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd)
+{
+ struct samsung_usbphy_data *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct samsung_usbphy_data),
+ &samsung_device_usbphy);
+
+ if (!npd->pmu_isolation)
+ npd->pmu_isolation = s5p_usb_phy_pmu_isolation;
+}
+#endif
+
#ifdef CONFIG_S3C_DEV_USB_HOST
static struct resource s3c_usb_resource[] = {
[0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
@@ -1449,6 +1479,8 @@ struct platform_device s3c_device_usb_hsotg = {
},
};
+#ifndef CONFIG_ARCH_S3C64XX
+/* TODO: To be removed later. Currently only S3C64XX is platform data free */
void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
{
struct s3c_hsotg_plat *npd;
@@ -1461,6 +1493,7 @@ void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
if (!npd->phy_exit)
npd->phy_exit = s5p_usb_phy_exit;
}
+#endif
#endif /* CONFIG_S3C_DEV_USB_HSOTG */
/* USB High Spped 2.0 Device (Gadget) */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 5da4b4f..3849c88 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -138,6 +138,7 @@ extern struct platform_device exynos_device_drm;
extern struct platform_device samsung_asoc_dma;
extern struct platform_device samsung_asoc_idma;
extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_usbphy;
/* s3c2440 specific devices */
diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h
index 959bcdb..165ffe7 100644
--- a/arch/arm/plat-samsung/include/plat/usb-phy.h
+++ b/arch/arm/plat-samsung/include/plat/usb-phy.h
@@ -18,5 +18,6 @@ enum s5p_usb_phy_type {
extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+extern void s5p_usb_phy_pmu_isolation(int on);
#endif /* __PLAT_SAMSUNG_USB_PHY_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH v4 5/5] ARM: Exynos4210: Enabling samsung-usbphy driver
2012-08-10 7:10 ` Praveen Paneri
@ 2012-08-10 7:10 ` Praveen Paneri
-1 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 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
Adding usbphy node for Exynos4210 along with the platform data.
Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
arch/arm/boot/dts/exynos4210.dtsi | 5 +++++
arch/arm/mach-exynos/include/mach/map.h | 1 +
arch/arm/mach-exynos/mach-exynos4-dt.c | 8 ++++++++
arch/arm/mach-exynos/setup-usb-phy.c | 13 +++++++++++++
4 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 02891fe..e28cf10 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -62,6 +62,11 @@
interrupts = <0 44 0>, <0 45 0>;
};
+ usbphy@125B0000 {
+ compatible = "samsung,exynos4210-usbphy";
+ reg = <0x125B0000 0x100>;
+ };
+
keypad@100A0000 {
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index c72b675..0625c0a 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -234,6 +234,7 @@
#define S3C_PA_SPI1 EXYNOS4_PA_SPI1
#define S3C_PA_SPI2 EXYNOS4_PA_SPI2
#define S3C_PA_USB_HSOTG EXYNOS4_PA_HSOTG
+#define S3C_PA_USB_PHY EXYNOS4_PA_HSPHY
#define S5P_PA_EHCI EXYNOS4_PA_EHCI
#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index b2b5d5f..0739be8 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -13,6 +13,7 @@
#include <linux/of_platform.h>
#include <linux/serial_core.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
@@ -20,9 +21,14 @@
#include <plat/cpu.h>
#include <plat/regs-serial.h>
+#include <plat/usb-phy.h>
#include "common.h"
+static struct samsung_usbphy_data exynos4_usbphy_pdata = {
+ .pmu_isolation = s5p_usb_phy_pmu_isolation,
+};
+
/*
* The following lookup table is used to override device names when devices
* are registered from device tree. This is temporarily added to enable
@@ -63,6 +69,8 @@ static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
"exynos4210-spi.2", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
+ OF_DEV_AUXDATA("samsung,exynos4210-usbphy", EXYNOS4_PA_HSPHY,
+ "s3c-usbphy", &exynos4_usbphy_pdata),
{},
};
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index b81cc56..1c62d20 100644
--- a/arch/arm/mach-exynos/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -221,3 +221,16 @@ int s5p_usb_phy_exit(struct platform_device *pdev, int type)
return -EINVAL;
}
+
+void s5p_usb_phy_pmu_isolation(int on)
+{
+ if (on) {
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ & ~S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ } else {
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ | S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ }
+}
--
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] 27+ messages in thread
* [PATCH v4 5/5] ARM: Exynos4210: Enabling samsung-usbphy driver
@ 2012-08-10 7:10 ` Praveen Paneri
0 siblings, 0 replies; 27+ messages in thread
From: Praveen Paneri @ 2012-08-10 7:10 UTC (permalink / raw)
To: linux-arm-kernel
Adding usbphy node for Exynos4210 along with the platform data.
Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
---
arch/arm/boot/dts/exynos4210.dtsi | 5 +++++
arch/arm/mach-exynos/include/mach/map.h | 1 +
arch/arm/mach-exynos/mach-exynos4-dt.c | 8 ++++++++
arch/arm/mach-exynos/setup-usb-phy.c | 13 +++++++++++++
4 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 02891fe..e28cf10 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -62,6 +62,11 @@
interrupts = <0 44 0>, <0 45 0>;
};
+ usbphy at 125B0000 {
+ compatible = "samsung,exynos4210-usbphy";
+ reg = <0x125B0000 0x100>;
+ };
+
keypad at 100A0000 {
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index c72b675..0625c0a 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -234,6 +234,7 @@
#define S3C_PA_SPI1 EXYNOS4_PA_SPI1
#define S3C_PA_SPI2 EXYNOS4_PA_SPI2
#define S3C_PA_USB_HSOTG EXYNOS4_PA_HSOTG
+#define S3C_PA_USB_PHY EXYNOS4_PA_HSPHY
#define S5P_PA_EHCI EXYNOS4_PA_EHCI
#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index b2b5d5f..0739be8 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -13,6 +13,7 @@
#include <linux/of_platform.h>
#include <linux/serial_core.h>
+#include <linux/platform_data/samsung-usbphy.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
@@ -20,9 +21,14 @@
#include <plat/cpu.h>
#include <plat/regs-serial.h>
+#include <plat/usb-phy.h>
#include "common.h"
+static struct samsung_usbphy_data exynos4_usbphy_pdata = {
+ .pmu_isolation = s5p_usb_phy_pmu_isolation,
+};
+
/*
* The following lookup table is used to override device names when devices
* are registered from device tree. This is temporarily added to enable
@@ -63,6 +69,8 @@ static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
"exynos4210-spi.2", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
+ OF_DEV_AUXDATA("samsung,exynos4210-usbphy", EXYNOS4_PA_HSPHY,
+ "s3c-usbphy", &exynos4_usbphy_pdata),
{},
};
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index b81cc56..1c62d20 100644
--- a/arch/arm/mach-exynos/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -221,3 +221,16 @@ int s5p_usb_phy_exit(struct platform_device *pdev, int type)
return -EINVAL;
}
+
+void s5p_usb_phy_pmu_isolation(int on)
+{
+ if (on) {
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ & ~S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ } else {
+ writel(readl(S5P_USBDEVICE_PHY_CONTROL)
+ | S5P_USBDEVICE_PHY_ENABLE,
+ S5P_USBDEVICE_PHY_CONTROL);
+ }
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 27+ messages in thread