phy-ab8500-usb.c revision 3147dad6fa457e0bb7edaab36f6d290c7048b49e
1969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab/* 2969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * drivers/usb/otg/ab8500_usb.c 3969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 4969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * USB transceiver driver for AB8500 chip 5969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 6969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Copyright (C) 2010 ST-Ericsson AB 7969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> 8969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 9969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * This program is free software; you can redistribute it and/or modify 10969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * it under the terms of the GNU General Public License as published by 11969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * the Free Software Foundation; either version 2 of the License, or 12969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * (at your option) any later version. 13969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 14969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * This program is distributed in the hope that it will be useful, 15969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * but WITHOUT ANY WARRANTY; without even the implied warranty of 16969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * GNU General Public License for more details. 18969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 19969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * You should have received a copy of the GNU General Public License 20969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * along with this program; if not, write to the Free Software 21969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 23969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 24969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 25969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/module.h> 26969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/platform_device.h> 27969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/usb/otg.h> 28969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/slab.h> 29969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/notifier.h> 30969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/interrupt.h> 31969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/delay.h> 32969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/mfd/abx500.h> 33ee66e653ca7425bc8ffca4e00f19a8057cd14e4dLinus Walleij#include <linux/mfd/abx500/ab8500.h> 34af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#include <linux/usb/musb-ux500.h> 35e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri#include <linux/regulator/consumer.h> 36899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard#include <linux/pinctrl/consumer.h> 37969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 387124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_SYS_CTRL2_BLOCK */ 39969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_MAIN_WD_CTRL_REG 0x01 407124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 417124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_USB */ 42969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_USB_LINE_STAT_REG 0x80 43af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#define AB8505_USB_LINE_STAT_REG 0x94 44969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_USB_PHY_CTRL_REG 0x8A 45969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 467124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_DEVELOPMENT */ 477124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_BANK12_ACCESS 0x00 487124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 497124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_DEBUG */ 507124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE1 0x05 517124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE2 0x06 527124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE3 0x07 537124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 54969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_OTG_STAT_ID (1 << 0) 55969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) 56969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) 57969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) 58969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_WD_CTRL_KICK (1 << 1) 59969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 60969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_WD_KICK_DELAY_US 100 /* usec */ 61969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ 62af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#define AB8500_V20_31952_DISABLE_DELAY_US 100 /* usec */ 63969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 64969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab/* Usb line status register */ 65969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabenum ab8500_usb_link_status { 66af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_CONFIGURED_8500 = 0, 67af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_NC_8500, 68af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_NS_8500, 69af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_S_8500, 70af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_NM_8500, 71af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_HS_8500, 72af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_HS_CHIRP_8500, 73af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_DEDICATED_CHG_8500, 74af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_A_8500, 75af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_B_8500, 76af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_NM_8500, 77af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_HS_8500, 78af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_HS_CHIRP_8500, 79af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HM_IDGND_8500, 80af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED_8500, 81af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_VALID_LINK_8500, 82af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri}; 83af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 84af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltierienum ab8505_usb_link_status { 85af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_CONFIGURED_8505 = 0, 86af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_NC_8505, 87af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_NS_8505, 88af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_S_8505, 89af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CDP_8505, 90af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED0_8505, 91af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED1_8505, 92af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_DEDICATED_CHG_8505, 93af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_A_8505, 94af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_B_8505, 95af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_NM_8505, 96af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED2_8505, 97af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED3_8505, 98af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HM_IDGND_8505, 99af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGERPORT_NOT_OK_8505, 100af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGER_DM_HIGH_8505, 101af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8505, 102af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_UPSTREAM_NO_IDGNG_NO_VBUS_8505, 103af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_UPSTREAM_8505, 104af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGER_SE1_8505, 105af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CARKIT_CHGR_1_8505, 106af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CARKIT_CHGR_2_8505, 107af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_DOCK_CHGR_8505, 108af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8505, 109af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8505, 110af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505, 111af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505, 112af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8505, 113af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri}; 114af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 115af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltierienum ab8500_usb_mode { 116af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_IDLE = 0, 117af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_PERIPHERAL, 118af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_HOST, 119af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_DEDICATED_CHG 120969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 121969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 122969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstruct ab8500_usb { 123144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_phy phy; 124969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct device *dev; 12573f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri struct ab8500 *ab8500; 126969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab unsigned vbus_draw; 127969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct work_struct phy_dis_work; 128af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_mode mode; 129e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ape; 130e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_musb; 131e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ulpi; 13254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int saved_v_ulpi; 133af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int previous_link_status_state; 134899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard struct pinctrl *pinctrl; 135899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard struct pinctrl_state *pins_sleep; 136969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 137969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 138144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) 139969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 140144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return container_of(x, struct ab8500_usb, phy); 141969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 142969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 143969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_wd_workaround(struct ab8500_usb *ab) 144969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 145969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 146969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 147969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 148969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_BIT_WD_CTRL_ENABLE); 149969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 150969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab udelay(AB8500_WD_KICK_DELAY_US); 151969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 152969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 153969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 154969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 155969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab (AB8500_BIT_WD_CTRL_ENABLE 156969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab | AB8500_BIT_WD_CTRL_KICK)); 157969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 15873f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri udelay(AB8500_WD_V11_DISABLE_DELAY_US); 159969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 160969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 161969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 162969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 163969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 0); 164969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 165969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 16654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_enable(struct ab8500_usb *ab) 16754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 16854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret, volt; 16954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 17088b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri ret = regulator_enable(ab->v_ape); 17188b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri if (ret) 17288b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri dev_err(ab->dev, "Failed to enable v-ape\n"); 17354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 17454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 17554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi); 17654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ab->saved_v_ulpi < 0) 17754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to get v_ulpi voltage\n"); 17854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 17954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 1300000, 1350000); 18054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 18154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n", 18254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 18354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 18454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_optimum_mode(ab->v_ulpi, 28000); 18554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 18654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", 18754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 18854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 18954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 19088b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri ret = regulator_enable(ab->v_ulpi); 19188b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri if (ret) 19288b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri dev_err(ab->dev, "Failed to enable vddulpivio18\n"); 19354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 19454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 19554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt = regulator_get_voltage(ab->v_ulpi); 19654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if ((volt != 1300000) && (volt != 1350000)) 19754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", 19854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt); 19954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 20054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20188b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri ret = regulator_enable(ab->v_musb); 20288b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri if (ret) 20388b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri dev_err(ab->dev, "Failed to enable musb_1v8\n"); 20454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 20554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_disable(struct ab8500_usb *ab) 20754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 20854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret; 20954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 21054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_musb); 21154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 21254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ulpi); 21354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 21454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri /* USB is not the only consumer of Vintcore, restore old settings */ 21554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 21654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ab->saved_v_ulpi > 0) { 21754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 21854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ab->saved_v_ulpi); 21954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 22054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to %duV, ret=%d\n", 22154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ret); 22254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 22354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 22454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_optimum_mode(ab->v_ulpi, 0); 22554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 22654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", 22754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 22854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 22954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 23054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ape); 23154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 23254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 233af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit) 234af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 235af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Workaround for v2.0 bug # 31952 */ 236af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 237af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 238af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 239af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri bit, bit); 240af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri udelay(AB8500_V20_31952_DISABLE_DELAY_US); 241af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 242af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 243af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 244c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host) 245969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 246c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 247c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 248c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 249969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 250899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard /* mux and configure USB pins to DEFAULT state */ 251899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard ab->pinctrl = pinctrl_get_select(ab->dev, PINCTRL_STATE_DEFAULT); 252899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (IS_ERR(ab->pinctrl)) 253899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_err(ab->dev, "could not get/set default pinstate\n"); 254899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 25554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_enable(ab); 25654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 257c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 258c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 259c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, bit); 260c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri} 261c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 262c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host) 263c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri{ 264c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 265c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 266c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 267c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 268c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_linkstatus(ab, bit); 269c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 270c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 271c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 272c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, 0); 273969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 274c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri /* Needed to disable the phy.*/ 275c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_workaround(ab); 27654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 27754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_disable(ab); 278899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 279899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (!IS_ERR(ab->pinctrl)) { 280899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard /* configure USB pins to SLEEP state */ 281899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard ab->pins_sleep = pinctrl_lookup_state(ab->pinctrl, 282899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard PINCTRL_STATE_SLEEP); 283899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 284899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (IS_ERR(ab->pins_sleep)) 285899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_dbg(ab->dev, "could not get sleep pinstate\n"); 286899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard else if (pinctrl_select_state(ab->pinctrl, ab->pins_sleep)) 287899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_err(ab->dev, "could not set pins to sleep state\n"); 288899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 2893147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri /* 2903147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri * as USB pins are shared with iddet, release them to allow 291899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard * iddet to request them 292899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard */ 293899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard pinctrl_put(ab->pinctrl); 294899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard } 295969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 296969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 297c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_enable(ab, true) 298c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_disable(ab, true) 299c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_enable(ab, false) 300c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_disable(ab, false) 301969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 302af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8505_usb_link_status_update(struct ab8500_usb *ab, 303af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts) 304969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 305af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 306969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 307af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts); 308969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 309af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 310af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen at the time of 311af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in RIDA state 312af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 313af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 && 314af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_NC_8505)) 315af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 316af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 317af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 318969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 319969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab switch (lsts) { 320af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8505: 321af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 322af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8505: 323af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED0_8505: 324af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED1_8505: 325af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED2_8505: 326af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED3_8505: 327af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 328144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = false; 329969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = 0; 330af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 331af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 332af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 333af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Fallback to default B_IDLE as nothing 334af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * is connected 335af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 336af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 337969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 338969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 339af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8505: 340af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 341af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8505: 342af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8505: 343af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8505: 344af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_CDP_8505: 345af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 346af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 347969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_en(ab); 348af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 349af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 350969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 351af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 352af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 353969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 354969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 355af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8505: 356af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_DOCK_CHGR_8505: 357af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 358af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8505: 359af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 360af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 361969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_en(ab); 362af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 363af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 364969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 365144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = true; 366af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 367af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 368af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 369af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 370969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 371969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 372af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8505: 373af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 374af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 375af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 376af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 377af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 378af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 379af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri default: 380969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 381969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 382969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 383af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 384af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 385af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 386af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_link_status_update(struct ab8500_usb *ab, 387af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts) 388af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 389af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 390af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 391af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts); 392af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 393af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 394af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen in case of a 395af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in IDGND and RIDA stage 396af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 397af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 && 398af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_C_NS_8500 || 399af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500)) 400af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 401af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 402af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 && 403af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500) 404af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 405af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 406af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 407af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 408af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri switch (lsts) { 409af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8500: 410af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 411af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8500: 412af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_VALID_LINK_8500: 413af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 414af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 415af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 416af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 417af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 418af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Fallback to default B_IDLE as nothing is connected */ 419af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 420af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 421af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 422af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8500: 423af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_8500: 424af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_CHIRP_8500: 425af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 426af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8500: 427af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8500: 428af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8500: 429af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_NM_8500: 430af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_8500: 431af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_CHIRP_8500: 432af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 433af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 434af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_en(ab); 435af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 436af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 437af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 438af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 439af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 440af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 441af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 442af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8500: 443af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 444af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8500: 445af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 446af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 447af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_en(ab); 448af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 449af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 450af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 451af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = true; 452af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 453af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 454af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 455af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 456af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 457af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 458af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8500: 459af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 460af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 461af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 462af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 463af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 464af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 465af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED_8500: 466af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 467af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 468969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 469969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 470969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 471969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 472af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 473af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Connection Sequence: 474af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Link Status Interrupt 475af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Enable AB clock 476af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Enable AB regulators 477af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Enable USB phy 478af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Reset the musb controller 479af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Switch the ULPI GPIO pins to fucntion mode 480af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 7. Enable the musb Peripheral5 clock 481af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 8. Restore MUSB context 482af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 483af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int abx500_usb_link_status_update(struct ab8500_usb *ab) 484969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 485af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri u8 reg; 486af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int ret = 0; 487af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 488af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500(ab->ab8500)) { 489af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts; 490af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 491af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 492af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); 493af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x0F; 494af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8500_usb_link_status_update(ab, lsts); 495af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } else if (is_ab8505(ab->ab8500)) { 496af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts; 497af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 498af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 499af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); 500af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x1F; 501af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8505_usb_link_status_update(ab, lsts); 502af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 503af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 504af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return ret; 505af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 506af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 507af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 508af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Disconnection Sequence: 509af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Disconect Interrupt 510af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Disable regulators 511af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Disable AB clock 512af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Disable the Phy 513af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Link Status Interrupt 514af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Disable Musb Clock 515af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 516af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data) 517af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 518af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *) data; 519af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum usb_phy_events event = UX500_MUSB_NONE; 520af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 521af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Link status will not be updated till phy is disabled. */ 522af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_HOST) { 523af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 524af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 525af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 526af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 527af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_dis(ab); 528af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 529af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 530af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 531af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_PERIPHERAL) { 532af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 533af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 534af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_dis(ab); 535af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 536af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_CLEAN, &ab->vbus_draw); 537af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 538af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 539af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 540af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 541af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 542af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 543af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_DEDICATED_CHG) { 544af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_wd_linkstatus(ab, 545af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN); 546af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 547af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 548af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN, 0); 549af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 550af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 551969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 552af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return IRQ_HANDLED; 553969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 554969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 555af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_link_status_irq(int irq, void *data) 556969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 5573147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *)data; 558969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 559af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_usb_link_status_update(ab); 560969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 561969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return IRQ_HANDLED; 562969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 563969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 564969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_phy_disable_work(struct work_struct *work) 565969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 566969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = container_of(work, struct ab8500_usb, 567969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab phy_dis_work); 568969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 569144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->host) 570969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 571969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 572144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->gadget) 573969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 574969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 575969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 576c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisettistatic unsigned ab8500_eyediagram_workaroud(struct ab8500_usb *ab, unsigned mA) 577c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti{ 578c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti /* 579c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * AB8500 V2 has eye diagram issues when drawing more than 100mA from 580c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * VBUS. Set charging current to 100mA in case of standard host 581c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti */ 582c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (is_ab8500_2p0_or_earlier(ab->ab8500)) 583c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (mA > 100) 584c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = 100; 585c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 586c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti return mA; 587c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti} 588c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 589144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) 590969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 591969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 592969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 593144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!phy) 594969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 595969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 596144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(phy); 597969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 598c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = ab8500_eyediagram_workaroud(ab, mA); 599c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 600969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = mA; 601969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 60277f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 60377f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri UX500_MUSB_VBUS, &ab->vbus_draw); 60477f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri 605969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 606969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 607969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 6088675381109b0eb1c948a423c2b35e3f4509cb25eHeikki Krogerusstatic int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) 609969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 610969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* TODO */ 611969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 612969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 613969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 614144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_peripheral(struct usb_otg *otg, 615144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_gadget *gadget) 616969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 617969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 618969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 619969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 620969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 621969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 622144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 623969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 624588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->phy.otg->gadget = gadget; 625588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti 626969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 627969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 628969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 629969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 630969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 6313147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri if ((ab->mode != USB_IDLE) && !gadget) { 632588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->mode = USB_IDLE; 633969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 634969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 635969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 636969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 637969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 638969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 639144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) 640969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 641969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 642969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 643969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 644969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 645969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 646144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 647969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 648588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->phy.otg->host = host; 649588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti 650969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 651969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 652969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 653969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 654969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 6553147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri if ((ab->mode != USB_IDLE) && !host) { 656588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->mode = USB_IDLE; 657969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 658969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 659969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 660969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 661969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 662969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 663e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieristatic int ab8500_usb_regulator_get(struct ab8500_usb *ab) 664e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri{ 665e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri int err; 666e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 667e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ape = devm_regulator_get(ab->dev, "v-ape"); 668e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ape)) { 669e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get v-ape supply\n"); 670e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ape); 671e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 672e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 673e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 674e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ulpi = devm_regulator_get(ab->dev, "vddulpivio18"); 675e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ulpi)) { 676e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get vddulpivio18 supply\n"); 677e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ulpi); 678e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 679e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 680e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 681e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_musb = devm_regulator_get(ab->dev, "musb_1v8"); 682e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_musb)) { 683e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get musb_1v8 supply\n"); 684e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_musb); 685e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 686e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 687e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 688e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return 0; 689e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri} 690e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 691af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_irq_setup(struct platform_device *pdev, 692af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab) 693969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 694969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 695af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int irq; 696969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 697af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); 698af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 699969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab dev_err(&pdev->dev, "Link status irq not found\n"); 700af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 701af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 702af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 703af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_link_status_irq, 704af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status", ab); 705af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (err < 0) { 706af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for link status irq\n"); 707af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return err; 708969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 709969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 710af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); 711af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 712af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(&pdev->dev, "ID fall irq not found\n"); 713af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 714af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 715af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 716af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_disconnect_irq, 717af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-id-fall", ab); 718969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err < 0) { 719af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for ID fall irq\n"); 720af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return err; 721af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 722af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 723af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); 724af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 725af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(&pdev->dev, "VBUS fall irq not found\n"); 726af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 727af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 728af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 729af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_disconnect_irq, 730af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-vbus-fall", ab); 731af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (err < 0) { 732af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); 733969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return err; 734969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 735969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 736969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 737969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 738969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 73941ac7b3ab7fe1d6175839947a877fdf95cbd2211Bill Pembertonstatic int ab8500_usb_probe(struct platform_device *pdev) 740969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 741969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 74273f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri struct ab8500 *ab8500; 743144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_otg *otg; 744969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 745969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int rev; 746969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 74773f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab8500 = dev_get_drvdata(pdev->dev.parent); 748969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab rev = abx500_get_chip_id(&pdev->dev); 74973f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri 75073f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri if (is_ab8500_1p1_or_earlier(ab8500)) { 75173f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev); 752969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 753969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 754969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 75581ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri ab = devm_kzalloc(&pdev->dev, sizeof(*ab), GFP_KERNEL); 756969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!ab) 757969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENOMEM; 758969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 75981ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); 76081ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri if (!otg) 761144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return -ENOMEM; 762144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 763969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->dev = &pdev->dev; 76473f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab->ab8500 = ab8500; 765144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.dev = ab->dev; 766144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg = otg; 767144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.label = "ab8500"; 768144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_suspend = ab8500_usb_set_suspend; 769144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_power = ab8500_usb_set_power; 770144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.state = OTG_STATE_UNDEFINED; 771144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 772144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->phy = &ab->phy; 773144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_host = ab8500_usb_set_host; 774144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_peripheral = ab8500_usb_set_peripheral; 775969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 776969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_set_drvdata(pdev, ab); 777969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 778144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); 779969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 780969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* all: Disable phy when called from set_host and set_peripheral */ 781969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); 782969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 783e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = ab8500_usb_regulator_get(ab); 784e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (err) 785e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 786e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 787af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = ab8500_usb_irq_setup(pdev, ab); 788969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err < 0) 78981ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri return err; 790969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 791662dca54ca67c92b7aa14b9a2ec54acacf33ce45Kishon Vijay Abraham I err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); 792969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err) { 793969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab dev_err(&pdev->dev, "Can't register transceiver\n"); 79481ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri return err; 795969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 796969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 7977124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Phy tuning values for AB8500 */ 7987124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 7997124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Enable the PBT/Bank 0x12 access */ 8007124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8017124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01); 8027124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8037124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", 8047124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8057124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8067124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8077124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8); 8087124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8097124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", 8107124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8117124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8127124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8137124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00); 8147124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8157124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", 8167124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8177124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8187124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8197124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); 8207124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8217124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", 8227124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8237124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8247124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Switch to normal mode/disable Bank 0x12 access */ 8257124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8267124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x00); 8277124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8287124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", 8297124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8307124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti } 8317124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8327124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Phy tuning values for AB8505 */ 8337124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (is_ab8505(ab->ab8500)) { 8347124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Enable the PBT/Bank 0x12 access */ 8357124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8367124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 8377124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0x01, 0x01); 8387124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8397124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", 8407124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8417124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8427124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8437124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 8447124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0xC8, 0xC8); 8457124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8467124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", 8477124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8487124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8497124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8507124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 8517124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0x60, 0x60); 8527124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8537124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", 8547124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8557124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8567124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8577124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 8587124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0xFC, 0x80); 8597124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8607124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8617124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", 8627124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8637124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8647124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Switch to normal mode/disable Bank 0x12 access */ 8657124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8667124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 8677124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0x00, 0x00); 8687124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8697124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", 8707124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8717124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti } 8727124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 873af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Needed to enable ID detection. */ 874af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_wd_workaround(ab); 875af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 8768db12231bccc5ebf414b267af68c5a8c1e4432ddSakethram Bommisetti abx500_usb_link_status_update(ab); 8778db12231bccc5ebf414b267af68c5a8c1e4432ddSakethram Bommisetti 87873f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); 879969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 880969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 881969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 882969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 883fb4e98ab63433c4d3a1588ea91c73f1cd7ebaa00Bill Pembertonstatic int ab8500_usb_remove(struct platform_device *pdev) 884969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 885969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = platform_get_drvdata(pdev); 886969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 887969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab cancel_work_sync(&ab->phy_dis_work); 888969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 889662dca54ca67c92b7aa14b9a2ec54acacf33ce45Kishon Vijay Abraham I usb_remove_phy(&ab->phy); 890969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 891f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab if (ab->mode == USB_HOST) 892f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 893f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab else if (ab->mode == USB_PERIPHERAL) 894f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 895969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 896969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 897969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 898969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 899969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic struct platform_driver ab8500_usb_driver = { 900969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .probe = ab8500_usb_probe, 9017690417db5085f0de03aa70b8ca01b0118e8a1b4Bill Pemberton .remove = ab8500_usb_remove, 902969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .driver = { 903969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .name = "ab8500-usb", 904969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .owner = THIS_MODULE, 905969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab }, 906969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 907969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 908969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic int __init ab8500_usb_init(void) 909969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 910969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return platform_driver_register(&ab8500_usb_driver); 911969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 912969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabsubsys_initcall(ab8500_usb_init); 913969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 914969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void __exit ab8500_usb_exit(void) 915969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 916969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_driver_unregister(&ab8500_usb_driver); 917969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 918969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabmodule_exit(ab8500_usb_exit); 919969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 920969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_ALIAS("platform:ab8500_usb"); 921969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_AUTHOR("ST-Ericsson AB"); 922969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_DESCRIPTION("AB8500 usb transceiver driver"); 923969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_LICENSE("GPL"); 924