diff options
Diffstat (limited to 'target/linux/ramips/patches-3.10/0119-USB-phy-add-ralink-SoC-driver.patch')
-rw-r--r-- | target/linux/ramips/patches-3.10/0119-USB-phy-add-ralink-SoC-driver.patch | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/target/linux/ramips/patches-3.10/0119-USB-phy-add-ralink-SoC-driver.patch b/target/linux/ramips/patches-3.10/0119-USB-phy-add-ralink-SoC-driver.patch new file mode 100644 index 0000000000..fbec32cacb --- /dev/null +++ b/target/linux/ramips/patches-3.10/0119-USB-phy-add-ralink-SoC-driver.patch @@ -0,0 +1,229 @@ +From 71e09658d3544143e46ae76e76da8a322cd73e1d Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sun, 14 Jul 2013 23:31:19 +0200 +Subject: [PATCH 119/133] USB: phy: add ralink SoC driver + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + drivers/usb/phy/Kconfig | 8 ++ + drivers/usb/phy/Makefile | 1 + + drivers/usb/phy/ralink-phy.c | 191 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 200 insertions(+) + create mode 100644 drivers/usb/phy/ralink-phy.c + +--- a/drivers/usb/phy/Kconfig ++++ b/drivers/usb/phy/Kconfig +@@ -210,4 +210,12 @@ config USB_ULPI_VIEWPORT + Provides read/write operations to the ULPI phy register set for + controllers with a viewport register (e.g. Chipidea/ARC controllers). + ++config RALINK_USBPHY ++ bool "Ralink USB PHY controller Driver" ++ depends on MIPS && RALINK ++ select USB_OTG_UTILS ++ help ++ Enable this to support ralink USB phy controller for ralink ++ SoCs. ++ + endif # USB_PHY +--- a/drivers/usb/phy/Makefile ++++ b/drivers/usb/phy/Makefile +@@ -31,3 +31,4 @@ obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-us + obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o + obj-$(CONFIG_USB_ULPI) += phy-ulpi.o + obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o ++obj-$(CONFIG_RALINK_USBPHY) += ralink-phy.o +--- /dev/null ++++ b/drivers/usb/phy/ralink-phy.c +@@ -0,0 +1,191 @@ ++/* ++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org> ++ * ++ * based on: Renesas R-Car 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 version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/delay.h> ++#include <linux/io.h> ++#include <linux/usb/otg.h> ++#include <linux/of_platform.h> ++#include <linux/platform_device.h> ++#include <linux/spinlock.h> ++#include <linux/module.h> ++#include <linux/reset.h> ++ ++#include <asm/mach-ralink/ralink_regs.h> ++ ++#define RT_SYSC_REG_SYSCFG1 0x014 ++#define RT_SYSC_REG_CLKCFG1 0x030 ++#define RT_SYSC_REG_USB_PHY_CFG 0x05c ++ ++#define RT_RSTCTRL_UDEV BIT(25) ++#define RT_RSTCTRL_UHST BIT(22) ++#define RT_SYSCFG1_USB0_HOST_MODE BIT(10) ++ ++#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25) ++#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20) ++#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18) ++ ++#define USB_PHY_UTMI_8B60M BIT(1) ++#define UDEV_WAKEUP BIT(0) ++ ++static atomic_t usb_pwr_ref = ATOMIC_INIT(0); ++static struct reset_control *rstdev; ++static struct reset_control *rsthost; ++static u32 phy_clk; ++ ++static void usb_phy_enable(int state) ++{ ++ if (state) ++ rt_sysc_m32(0, phy_clk, RT_SYSC_REG_CLKCFG1); ++ else ++ rt_sysc_m32(phy_clk, 0, RT_SYSC_REG_CLKCFG1); ++ mdelay(100); ++} ++ ++static int usb_power_on(struct usb_phy *phy) ++{ ++ if (atomic_inc_return(&usb_pwr_ref) == 1) { ++ u32 t; ++ ++ usb_phy_enable(1); ++ ++// reset_control_assert(rstdev); ++// reset_control_assert(rsthost); ++ ++ if (OTG_STATE_B_HOST) { ++ rt_sysc_m32(0, RT_SYSCFG1_USB0_HOST_MODE, RT_SYSC_REG_SYSCFG1); ++ reset_control_deassert(rsthost); ++ } else { ++ rt_sysc_m32(RT_SYSCFG1_USB0_HOST_MODE, 0, RT_SYSC_REG_SYSCFG1); ++ reset_control_deassert(rstdev); ++ } ++ mdelay(100); ++ ++ t = rt_sysc_r32(RT_SYSC_REG_USB_PHY_CFG); ++ dev_info(phy->dev, "remote usb device wakeup %s\n", ++ (t & UDEV_WAKEUP) ? ("enabbled") : ("disabled")); ++ if (t & USB_PHY_UTMI_8B60M) ++ dev_info(phy->dev, "UTMI 8bit 60MHz\n"); ++ else ++ dev_info(phy->dev, "UTMI 16bit 30MHz\n"); ++ } ++ ++ return 0; ++} ++ ++static void usb_power_off(struct usb_phy *phy) ++{ ++ if (atomic_dec_return(&usb_pwr_ref) == 0) { ++ usb_phy_enable(0); ++ reset_control_assert(rstdev); ++ reset_control_assert(rsthost); ++ } ++} ++ ++static int usb_set_host(struct usb_otg *otg, struct usb_bus *host) ++{ ++ otg->gadget = NULL; ++ otg->host = host; ++ ++ return 0; ++} ++ ++static int usb_set_peripheral(struct usb_otg *otg, ++ struct usb_gadget *gadget) ++{ ++ otg->host = NULL; ++ otg->gadget = gadget; ++ ++ return 0; ++} ++ ++static const struct of_device_id ralink_usbphy_dt_match[] = { ++ { .compatible = "ralink,rt3xxx-usbphy", .data = (void *) (RT_CLKCFG1_UPHY1_CLK_EN | RT_CLKCFG1_UPHY0_CLK_EN) }, ++ { .compatible = "ralink,mt7620a-usbphy", .data = (void *) MT7620_CLKCFG1_UPHY0_CLK_EN }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ralink_usbphy_dt_match); ++ ++static int usb_phy_probe(struct platform_device *pdev) ++{ ++ const struct of_device_id *match; ++ struct device *dev = &pdev->dev; ++ struct usb_otg *otg; ++ struct usb_phy *phy; ++ int ret; ++ ++ match = of_match_device(ralink_usbphy_dt_match, &pdev->dev); ++ phy_clk = (int) match->data; ++ ++ rsthost = devm_reset_control_get(&pdev->dev, "host"); ++ if (IS_ERR(rsthost)) ++ return PTR_ERR(rsthost); ++ ++ rstdev = devm_reset_control_get(&pdev->dev, "device"); ++ if (IS_ERR(rstdev)) ++ return PTR_ERR(rstdev); ++ ++ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); ++ if (!phy) { ++ dev_err(&pdev->dev, "unable to allocate memory for USB PHY\n"); ++ return -ENOMEM; ++ } ++ ++ otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); ++ if (!otg) { ++ dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n"); ++ return -ENOMEM; ++ } ++ ++ phy->dev = dev; ++ phy->label = dev_name(dev); ++ phy->init = usb_power_on; ++ phy->shutdown = usb_power_off; ++ otg->set_host = usb_set_host; ++ otg->set_peripheral = usb_set_peripheral; ++ otg->phy = phy; ++ phy->otg = otg; ++ ret = usb_add_phy(phy, USB_PHY_TYPE_USB2); ++ ++ if (ret < 0) { ++ dev_err(dev, "usb phy addition error\n"); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, phy); ++ ++ dev_info(&pdev->dev, "loaded\n"); ++ ++ return ret; ++} ++ ++static int usb_phy_remove(struct platform_device *pdev) ++{ ++ struct usb_phy *phy = platform_get_drvdata(pdev); ++ ++ usb_remove_phy(phy); ++ ++ return 0; ++} ++ ++static struct platform_driver usb_phy_driver = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "rt3xxx-usbphy", ++ .of_match_table = of_match_ptr(ralink_usbphy_dt_match), ++ }, ++ .probe = usb_phy_probe, ++ .remove = usb_phy_remove, ++}; ++ ++module_platform_driver(usb_phy_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Ralink USB phy"); ++MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); |