diff options
Diffstat (limited to 'drivers/usb/phy')
25 files changed, 195 insertions, 2685 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index aff702c0eb9f..0f8ab981d572 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -137,35 +137,6 @@ config USB_ISP1301 To compile this driver as a module, choose M here: the module will be called phy-isp1301. -config USB_MSM_OTG - tristate "Qualcomm on-chip USB OTG controller support" - depends on (USB || USB_GADGET) && (ARCH_QCOM || COMPILE_TEST) - depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y' - depends on RESET_CONTROLLER - select USB_PHY - help - Enable this to support the USB OTG transceiver on Qualcomm chips. It - handles PHY initialization, clock management, and workarounds - required after resetting the hardware and power management. - This driver is required even for peripheral only or host only - mode configurations. - This driver is not supported on boards like trout which - has an external PHY. - -config USB_QCOM_8X16_PHY - tristate "Qualcomm APQ8016/MSM8916 on-chip USB PHY controller support" - depends on ARCH_QCOM || COMPILE_TEST - depends on RESET_CONTROLLER - select USB_PHY - select USB_ULPI_VIEWPORT - help - Enable this to support the USB transceiver on Qualcomm 8x16 chipsets. - It handles PHY initialization, clock management, power management, - and workarounds required after resetting the hardware. - - To compile this driver as a module, choose M here: the - module will be called phy-qcom-8x16-usb. - config USB_MV_OTG tristate "Marvell USB OTG support" depends on USB_EHCI_MV && USB_MV_UDC && PM && USB_OTG diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 0c40ccc90631..25e579fb92b8 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -19,8 +19,6 @@ obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o -obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o -obj-$(CONFIG_USB_QCOM_8X16_PHY) += phy-qcom-8x16-usb.o obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o obj-$(CONFIG_USB_ULPI) += phy-ulpi.o diff --git a/drivers/usb/phy/of.c b/drivers/usb/phy/of.c index 66ffa82457a8..1ab134f45d67 100644 --- a/drivers/usb/phy/of.c +++ b/drivers/usb/phy/of.c @@ -1,10 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * USB of helper code - * - * 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. */ #include <linux/kernel.h> diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 61bf2285d5b1..87295313a10c 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * USB transceiver driver for AB8500 family chips * @@ -5,21 +6,6 @@ * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> * Avinash Kumar <avinash.kumar@stericsson.com> * Thirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.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. - * - * 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> diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index 5f5f19813fde..a3cb25cb74f8 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/module.h> #include <linux/platform_device.h> #include <linux/err.h> diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 7e5aece769da..b36fa8b953d0 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/module.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index cf8f40ae6e01..900875f326d7 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2007,2008 Freescale semiconductor, Inc. * @@ -5,20 +6,6 @@ * Jerry Huang <Chang-Ming.Huang@freescale.com> * * Initialization based on code from Shlomi Gridish. - * - * 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. - * - * 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> diff --git a/drivers/usb/phy/phy-fsl-usb.h b/drivers/usb/phy/phy-fsl-usb.h index 23149954a09c..43d410f6641b 100644 --- a/drivers/usb/phy/phy-fsl-usb.h +++ b/drivers/usb/phy/phy-fsl-usb.h @@ -1,19 +1,5 @@ -/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. - * - * 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. - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2007,2008 Freescale Semiconductor, Inc. */ #include <linux/usb/otg-fsm.h> #include <linux/usb/otg.h> diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 89d6e7a5fdb7..74ba88297991 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * NOP USB transceiver for all USB transceiver which are either built-in * into USB IP or which are mostly autonomous. @@ -5,20 +6,6 @@ * Copyright (C) 2009 Texas Instruments Inc * Author: Ajay Kumar Gupta <ajay.gupta@ti.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. - * - * 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. - * * Current status: * This provides a "nop" transceiver for PHYs which are * autonomous such as isp1504, isp1707, etc. @@ -224,7 +211,7 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, int err = 0; u32 clk_rate = 0; - bool needs_vcc = false; + bool needs_vcc = false, needs_clk = false; if (dev->of_node) { struct device_node *node = dev->of_node; @@ -233,6 +220,7 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, clk_rate = 0; needs_vcc = of_property_read_bool(node, "vcc-supply"); + needs_clk = of_property_read_bool(node, "clocks"); nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); err = PTR_ERR_OR_ZERO(nop->gpiod_reset); @@ -275,6 +263,8 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, if (IS_ERR(nop->clk)) { dev_dbg(dev, "Can't get phy clock: %ld\n", PTR_ERR(nop->clk)); + if (needs_clk) + return PTR_ERR(nop->clk); } if (!IS_ERR(nop->clk) && clk_rate) { diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index f66120db8a41..553e2573c74f 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * gpio-vbus.c - simple GPIO VBUS sensing driver for B peripheral devices * * Copyright (c) 2008 Philipp Zabel <philipp.zabel@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/kernel.h> diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index c6052c814bcc..7041ba030052 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * isp1301_omap - ISP 1301 USB transceiver, talking to OMAP OTG controller * * Copyright (C) 2004 Texas Instruments * Copyright (C) 2004 David Brownell - * - * 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. - * - * 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/kernel.h> @@ -1183,9 +1170,11 @@ static irqreturn_t isp1301_irq(int irq, void *isp) return IRQ_HANDLED; } -static void isp1301_timer(unsigned long _isp) +static void isp1301_timer(struct timer_list *t) { - isp1301_defer_work((void *)_isp, WORK_TIMER); + struct isp1301 *isp = from_timer(isp, t, timer); + + isp1301_defer_work(isp, WORK_TIMER); } /*-------------------------------------------------------------------------*/ @@ -1222,7 +1211,6 @@ static int isp1301_remove(struct i2c_client *i2c) if (machine_is_omap_h2()) gpio_free(2); - isp->timer.data = 0; set_bit(WORK_STOP, &isp->todo); del_timer_sync(&isp->timer); flush_work(&isp->work); @@ -1507,9 +1495,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) } INIT_WORK(&isp->work, isp1301_work); - init_timer(&isp->timer); - isp->timer.function = isp1301_timer; - isp->timer.data = (unsigned long) isp; + timer_setup(&isp->timer, isp1301_timer, 0); i2c_set_clientdata(i2c, isp); isp->client = i2c; diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index f333024660b4..93b7d6a30aad 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NXP ISP1301 USB transceiver driver * * Copyright (C) 2012 Roland Stigge * * Author: Roland Stigge <stigge@antcom.de> - * - * 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/module.h> diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c index 01d4e4cdbc79..19871266312d 100644 --- a/drivers/usb/phy/phy-keystone.c +++ b/drivers/usb/phy/phy-keystone.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * phy-keystone - USB PHY, talking to dwc3 controller in Keystone. * * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.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. * * Author: WingMan Kwok <w-kwok2@ti.com> - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/module.h> diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c deleted file mode 100644 index 3d0dd2f97415..000000000000 --- a/drivers/usb/phy/phy-msm-usb.c +++ /dev/null @@ -1,2085 +0,0 @@ -/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#include <linux/module.h> -#include <linux/device.h> -#include <linux/extcon.h> -#include <linux/gpio/consumer.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/err.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/ioport.h> -#include <linux/uaccess.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include <linux/pm_runtime.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/reboot.h> -#include <linux/reset.h> -#include <linux/types.h> -#include <linux/usb/otg.h> - -#include <linux/usb.h> -#include <linux/usb/otg.h> -#include <linux/usb/of.h> -#include <linux/usb/ulpi.h> -#include <linux/usb/gadget.h> -#include <linux/usb/hcd.h> -#include <linux/usb/msm_hsusb_hw.h> -#include <linux/regulator/consumer.h> - -/** - * OTG control - * - * OTG_NO_CONTROL Id/VBUS notifications not required. Useful in host - * only configuration. - * OTG_PHY_CONTROL Id/VBUS notifications comes form USB PHY. - * OTG_PMIC_CONTROL Id/VBUS notifications comes from PMIC hardware. - * OTG_USER_CONTROL Id/VBUS notifcations comes from User via sysfs. - * - */ -enum otg_control_type { - OTG_NO_CONTROL = 0, - OTG_PHY_CONTROL, - OTG_PMIC_CONTROL, - OTG_USER_CONTROL, -}; - -/** - * PHY used in - * - * INVALID_PHY Unsupported PHY - * CI_45NM_INTEGRATED_PHY Chipidea 45nm integrated PHY - * SNPS_28NM_INTEGRATED_PHY Synopsis 28nm integrated PHY - * - */ -enum msm_usb_phy_type { - INVALID_PHY = 0, - CI_45NM_INTEGRATED_PHY, - SNPS_28NM_INTEGRATED_PHY, -}; - -#define IDEV_CHG_MAX 1500 -#define IUNIT 100 - -/** - * Different states involved in USB charger detection. - * - * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection - * process is not yet started. - * USB_CHG_STATE_WAIT_FOR_DCD Waiting for Data pins contact. - * USB_CHG_STATE_DCD_DONE Data pin contact is detected. - * USB_CHG_STATE_PRIMARY_DONE Primary detection is completed (Detects - * between SDP and DCP/CDP). - * USB_CHG_STATE_SECONDARY_DONE Secondary detection is completed (Detects - * between DCP and CDP). - * USB_CHG_STATE_DETECTED USB charger type is determined. - * - */ -enum usb_chg_state { - USB_CHG_STATE_UNDEFINED = 0, - USB_CHG_STATE_WAIT_FOR_DCD, - USB_CHG_STATE_DCD_DONE, - USB_CHG_STATE_PRIMARY_DONE, - USB_CHG_STATE_SECONDARY_DONE, - USB_CHG_STATE_DETECTED, -}; - -/** - * USB charger types - * - * USB_INVALID_CHARGER Invalid USB charger. - * USB_SDP_CHARGER Standard downstream port. Refers to a downstream port - * on USB2.0 compliant host/hub. - * USB_DCP_CHARGER Dedicated charger port (AC charger/ Wall charger). - * USB_CDP_CHARGER Charging downstream port. Enumeration can happen and - * IDEV_CHG_MAX can be drawn irrespective of USB state. - * - */ -enum usb_chg_type { - USB_INVALID_CHARGER = 0, - USB_SDP_CHARGER, - USB_DCP_CHARGER, - USB_CDP_CHARGER, -}; - -/** - * struct msm_otg_platform_data - platform device data - * for msm_otg driver. - * @phy_init_seq: PHY configuration sequence values. Value of -1 is reserved as - * "do not overwrite default vaule at this address". - * @phy_init_sz: PHY configuration sequence size. - * @vbus_power: VBUS power on/off routine. - * @power_budget: VBUS power budget in mA (0 will be treated as 500mA). - * @mode: Supported mode (OTG/peripheral/host). - * @otg_control: OTG switch controlled by user/Id pin - */ -struct msm_otg_platform_data { - int *phy_init_seq; - int phy_init_sz; - void (*vbus_power)(bool on); - unsigned power_budget; - enum usb_dr_mode mode; - enum otg_control_type otg_control; - enum msm_usb_phy_type phy_type; - void (*setup_gpio)(enum usb_otg_state state); -}; - -/** - * struct msm_otg: OTG driver data. Shared by HCD and DCD. - * @otg: USB OTG Transceiver structure. - * @pdata: otg device platform data. - * @irq: IRQ number assigned for HSUSB controller. - * @clk: clock struct of usb_hs_clk. - * @pclk: clock struct of usb_hs_pclk. - * @core_clk: clock struct of usb_hs_core_clk. - * @regs: ioremapped register base address. - * @inputs: OTG state machine inputs(Id, SessValid etc). - * @sm_work: OTG state machine work. - * @in_lpm: indicates low power mode (LPM) state. - * @async_int: Async interrupt arrived. - * @cur_power: The amount of mA available from downstream port. - * @chg_work: Charger detection work. - * @chg_state: The state of charger detection process. - * @chg_type: The type of charger attached. - * @dcd_retires: The retry count used to track Data contact - * detection process. - * @manual_pullup: true if VBUS is not routed to USB controller/phy - * and controller driver therefore enables pull-up explicitly before - * starting controller using usbcmd run/stop bit. - * @vbus: VBUS signal state trakining, using extcon framework - * @id: ID signal state trakining, using extcon framework - * @switch_gpio: Descriptor for GPIO used to control external Dual - * SPDT USB Switch. - * @reboot: Used to inform the driver to route USB D+/D- line to Device - * connector - */ -struct msm_otg { - struct usb_phy phy; - struct msm_otg_platform_data *pdata; - int irq; - struct clk *clk; - struct clk *pclk; - struct clk *core_clk; - void __iomem *regs; -#define ID 0 -#define B_SESS_VLD 1 - unsigned long inputs; - struct work_struct sm_work; - atomic_t in_lpm; - int async_int; - unsigned cur_power; - int phy_number; - struct delayed_work chg_work; - enum usb_chg_state chg_state; - enum usb_chg_type chg_type; - u8 dcd_retries; - struct regulator *v3p3; - struct regulator *v1p8; - struct regulator *vddcx; - struct regulator_bulk_data supplies[3]; - - struct reset_control *phy_rst; - struct reset_control *link_rst; - int vdd_levels[3]; - - bool manual_pullup; - - struct gpio_desc *switch_gpio; - struct notifier_block reboot; -}; - -#define MSM_USB_BASE (motg->regs) -#define DRIVER_NAME "msm_otg" - -#define ULPI_IO_TIMEOUT_USEC (10 * 1000) -#define LINK_RESET_TIMEOUT_USEC (250 * 1000) - -#define USB_PHY_3P3_VOL_MIN 3050000 /* uV */ -#define USB_PHY_3P3_VOL_MAX 3300000 /* uV */ -#define USB_PHY_3P3_HPM_LOAD 50000 /* uA */ -#define USB_PHY_3P3_LPM_LOAD 4000 /* uA */ - -#define USB_PHY_1P8_VOL_MIN 1800000 /* uV */ -#define USB_PHY_1P8_VOL_MAX 1800000 /* uV */ -#define USB_PHY_1P8_HPM_LOAD 50000 /* uA */ -#define USB_PHY_1P8_LPM_LOAD 4000 /* uA */ - -#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */ -#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */ -#define USB_PHY_SUSP_DIG_VOL 500000 /* uV */ - -enum vdd_levels { - VDD_LEVEL_NONE = 0, - VDD_LEVEL_MIN, - VDD_LEVEL_MAX, -}; - -static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) -{ - int ret = 0; - - if (init) { - ret = regulator_set_voltage(motg->vddcx, - motg->vdd_levels[VDD_LEVEL_MIN], - motg->vdd_levels[VDD_LEVEL_MAX]); - if (ret) { - dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); - return ret; - } - - ret = regulator_enable(motg->vddcx); - if (ret) - dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); - } else { - ret = regulator_set_voltage(motg->vddcx, 0, - motg->vdd_levels[VDD_LEVEL_MAX]); - if (ret) - dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); - ret = regulator_disable(motg->vddcx); - if (ret) - dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); - } - - return ret; -} - -static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) -{ - int rc = 0; - - if (init) { - rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN, - USB_PHY_3P3_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "Cannot set v3p3 voltage\n"); - goto exit; - } - rc = regulator_enable(motg->v3p3); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); - goto exit; - } - rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN, - USB_PHY_1P8_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "Cannot set v1p8 voltage\n"); - goto disable_3p3; - } - rc = regulator_enable(motg->v1p8); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); - goto disable_3p3; - } - - return 0; - } - - regulator_disable(motg->v1p8); -disable_3p3: - regulator_disable(motg->v3p3); -exit: - return rc; -} - -static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) -{ - int ret = 0; - - if (on) { - ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_HPM_LOAD); - if (ret < 0) { - pr_err("Could not set HPM for v1p8\n"); - return ret; - } - ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_HPM_LOAD); - if (ret < 0) { - pr_err("Could not set HPM for v3p3\n"); - regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD); - return ret; - } - } else { - ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD); - if (ret < 0) - pr_err("Could not set LPM for v1p8\n"); - ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_LPM_LOAD); - if (ret < 0) - pr_err("Could not set LPM for v3p3\n"); - } - - pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); - return ret < 0 ? ret : 0; -} - -static int ulpi_read(struct usb_phy *phy, u32 reg) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int cnt = 0; - - /* initiate read operation */ - writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(phy->dev, "ulpi_read: timeout %08x\n", - readl(USB_ULPI_VIEWPORT)); - return -ETIMEDOUT; - } - return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); -} - -static int ulpi_write(struct usb_phy *phy, u32 val, u32 reg) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int cnt = 0; - - /* initiate write operation */ - writel(ULPI_RUN | ULPI_WRITE | - ULPI_ADDR(reg) | ULPI_DATA(val), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(phy->dev, "ulpi_write: timeout\n"); - return -ETIMEDOUT; - } - return 0; -} - -static struct usb_phy_io_ops msm_otg_io_ops = { - .read = ulpi_read, - .write = ulpi_write, -}; - -static void ulpi_init(struct msm_otg *motg) -{ - struct msm_otg_platform_data *pdata = motg->pdata; - int *seq = pdata->phy_init_seq, idx; - u32 addr = ULPI_EXT_VENDOR_SPECIFIC; - - for (idx = 0; idx < pdata->phy_init_sz; idx++) { - if (seq[idx] == -1) - continue; - - dev_vdbg(motg->phy.dev, "ulpi: write 0x%02x to 0x%02x\n", - seq[idx], addr + idx); - ulpi_write(&motg->phy, seq[idx], addr + idx); - } -} - -static int msm_phy_notify_disconnect(struct usb_phy *phy, - enum usb_device_speed speed) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int val; - - if (motg->manual_pullup) { - val = ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL; - usb_phy_io_write(phy, val, ULPI_CLR(ULPI_MISC_A)); - } - - /* - * Put the transceiver in non-driving mode. Otherwise host - * may not detect soft-disconnection. - */ - val = ulpi_read(phy, ULPI_FUNC_CTRL); - val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; - val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; - ulpi_write(phy, val, ULPI_FUNC_CTRL); - - return 0; -} - -static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) -{ - int ret; - - if (assert) - ret = reset_control_assert(motg->link_rst); - else - ret = reset_control_deassert(motg->link_rst); - - if (ret) - dev_err(motg->phy.dev, "usb link clk reset %s failed\n", - assert ? "assert" : "deassert"); - - return ret; -} - -static int msm_otg_phy_clk_reset(struct msm_otg *motg) -{ - int ret = 0; - - if (motg->phy_rst) - ret = reset_control_reset(motg->phy_rst); - - if (ret) - dev_err(motg->phy.dev, "usb phy clk reset failed\n"); - - return ret; -} - -static int msm_link_reset(struct msm_otg *motg) -{ - u32 val; - int ret; - - ret = msm_otg_link_clk_reset(motg, 1); - if (ret) - return ret; - - /* wait for 1ms delay as suggested in HPG. */ - usleep_range(1000, 1200); - - ret = msm_otg_link_clk_reset(motg, 0); - if (ret) - return ret; - - if (motg->phy_number) - writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); - - /* put transceiver in serial mode as part of reset */ - val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; - writel(val | PORTSC_PTS_SERIAL, USB_PORTSC); - - return 0; -} - -static int msm_otg_reset(struct usb_phy *phy) -{ - struct msm_otg *motg = container_of(phy, struct msm_otg, phy); - int cnt = 0; - - writel(USBCMD_RESET, USB_USBCMD); - while (cnt < LINK_RESET_TIMEOUT_USEC) { - if (!(readl(USB_USBCMD) & USBCMD_RESET)) - break; - udelay(1); - cnt++; - } - if (cnt >= LINK_RESET_TIMEOUT_USEC) - return -ETIMEDOUT; - - /* select ULPI phy and cl |
