phy-ab8500-usb.c revision 899f0f561b51506f40eb78c9c4aaeeabf97cf35c
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 delayed_work dwork; 128969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct work_struct phy_dis_work; 129969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab unsigned long link_status_wait; 130af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_mode mode; 131e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ape; 132e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_musb; 133e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ulpi; 13454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int saved_v_ulpi; 135af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int previous_link_status_state; 136899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard struct pinctrl *pinctrl; 137899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard struct pinctrl_state *pins_sleep; 138969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 139969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 140144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) 141969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 142144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return container_of(x, struct ab8500_usb, phy); 143969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 144969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 145969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_wd_workaround(struct ab8500_usb *ab) 146969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 147969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 148969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 149969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 150969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_BIT_WD_CTRL_ENABLE); 151969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 152969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab udelay(AB8500_WD_KICK_DELAY_US); 153969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 154969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 155969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 156969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 157969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab (AB8500_BIT_WD_CTRL_ENABLE 158969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab | AB8500_BIT_WD_CTRL_KICK)); 159969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 16073f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri udelay(AB8500_WD_V11_DISABLE_DELAY_US); 161969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 162969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 163969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 164969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 165969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 0); 166969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 167969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 16854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_enable(struct ab8500_usb *ab) 16954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 17054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret, volt; 17154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 17254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_enable(ab->v_ape); 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 19054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_enable(ab->v_ulpi); 19154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 19254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 19354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt = regulator_get_voltage(ab->v_ulpi); 19454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if ((volt != 1300000) && (volt != 1350000)) 19554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", 19654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt); 19754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 19854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 19954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_enable(ab->v_musb); 20054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 20154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_disable(struct ab8500_usb *ab) 20354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 20454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret; 20554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_musb); 20754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ulpi); 20954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 21054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri /* USB is not the only consumer of Vintcore, restore old settings */ 21154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 21254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ab->saved_v_ulpi > 0) { 21354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 21454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ab->saved_v_ulpi); 21554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 21654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to %duV, ret=%d\n", 21754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ret); 21854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 21954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 22054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_optimum_mode(ab->v_ulpi, 0); 22154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 22254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", 22354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 22454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 22554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 22654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ape); 22754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 22854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 229af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit) 230af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 231af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Workaround for v2.0 bug # 31952 */ 232af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 233af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 234af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 235af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri bit, bit); 236af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri udelay(AB8500_V20_31952_DISABLE_DELAY_US); 237af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 238af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 239af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 240c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host) 241969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 242c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 243c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 244c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 245969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 246899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard /* mux and configure USB pins to DEFAULT state */ 247899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard ab->pinctrl = pinctrl_get_select(ab->dev, PINCTRL_STATE_DEFAULT); 248899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (IS_ERR(ab->pinctrl)) 249899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_err(ab->dev, "could not get/set default pinstate\n"); 250899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 25154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_enable(ab); 25254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 253c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 254c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 255c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, bit); 256c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri} 257c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 258c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host) 259c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri{ 260c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 261c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 262c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 263c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 264c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_linkstatus(ab, bit); 265c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 266c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 267c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 268c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, 0); 269969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 270c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri /* Needed to disable the phy.*/ 271c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_workaround(ab); 27254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 27354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_disable(ab); 274899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 275899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (!IS_ERR(ab->pinctrl)) { 276899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard /* configure USB pins to SLEEP state */ 277899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard ab->pins_sleep = pinctrl_lookup_state(ab->pinctrl, 278899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard PINCTRL_STATE_SLEEP); 279899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 280899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (IS_ERR(ab->pins_sleep)) 281899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_dbg(ab->dev, "could not get sleep pinstate\n"); 282899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard else if (pinctrl_select_state(ab->pinctrl, ab->pins_sleep)) 283899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_err(ab->dev, "could not set pins to sleep state\n"); 284899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 285899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard /* as USB pins are shared with idddet, release them to allow 286899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard * iddet to request them 287899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard */ 288899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard pinctrl_put(ab->pinctrl); 289899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard } 290969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 291969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 292c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_enable(ab, true) 293c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_disable(ab, true) 294c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_enable(ab, false) 295c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_disable(ab, false) 296969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 297af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8505_usb_link_status_update(struct ab8500_usb *ab, 298af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts) 299969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 300af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 301969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 302af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts); 303969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 304af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 305af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen at the time of 306af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in RIDA state 307af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 308af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 && 309af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_NC_8505)) 310af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 311af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 312af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 313969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 314969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab switch (lsts) { 315af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8505: 316af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 317af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8505: 318af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED0_8505: 319af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED1_8505: 320af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED2_8505: 321af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED3_8505: 322af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 323144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = false; 324969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = 0; 325af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 326af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 327af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 328af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Fallback to default B_IDLE as nothing 329af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * is connected 330af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 331af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 332969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 333969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 334af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8505: 335af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 336af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8505: 337af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8505: 338af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8505: 339af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_CDP_8505: 340af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 341af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 342969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_en(ab); 343af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 344af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 345969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 346af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 347af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 348969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 349969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 350af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8505: 351af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_DOCK_CHGR_8505: 352af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 353af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8505: 354af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 355af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 356969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_en(ab); 357af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 358af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 359969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 360144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = true; 361af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 362af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 363af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 364af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 365969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 366969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 367af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8505: 368af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 369af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 370af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 371af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 372af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 373af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 374af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri default: 375969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 376969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 377969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 378af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 379af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 380af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 381af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_link_status_update(struct ab8500_usb *ab, 382af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts) 383af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 384af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 385af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 386af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts); 387af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 388af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 389af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen in case of a 390af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in IDGND and RIDA stage 391af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 392af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 && 393af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_C_NS_8500 || 394af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500)) 395af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 396af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 397af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 && 398af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500) 399af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 400af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 401af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 402af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 403af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri switch (lsts) { 404af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8500: 405af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 406af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8500: 407af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_VALID_LINK_8500: 408af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 409af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 410af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 411af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 412af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 413af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Fallback to default B_IDLE as nothing is connected */ 414af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 415af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 416af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 417af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8500: 418af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_8500: 419af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_CHIRP_8500: 420af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 421af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8500: 422af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8500: 423af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8500: 424af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_NM_8500: 425af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_8500: 426af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_CHIRP_8500: 427af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 428af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 429af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_en(ab); 430af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 431af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 432af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 433af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 434af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 435af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 436af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 437af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8500: 438af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 439af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8500: 440af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 441af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 442af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_en(ab); 443af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 444af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 445af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 446af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = true; 447af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 448af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 449af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 450af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 451af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 452af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 453af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8500: 454af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 455af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 456af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 457af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 458af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 459af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 460af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED_8500: 461af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 462af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 463969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 464969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 465969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 466969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 467af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 468af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Connection Sequence: 469af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Link Status Interrupt 470af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Enable AB clock 471af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Enable AB regulators 472af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Enable USB phy 473af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Reset the musb controller 474af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Switch the ULPI GPIO pins to fucntion mode 475af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 7. Enable the musb Peripheral5 clock 476af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 8. Restore MUSB context 477af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 478af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int abx500_usb_link_status_update(struct ab8500_usb *ab) 479969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 480af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri u8 reg; 481af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int ret = 0; 482af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 483af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500(ab->ab8500)) { 484af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts; 485af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 486af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 487af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); 488af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x0F; 489af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8500_usb_link_status_update(ab, lsts); 490af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } else if (is_ab8505(ab->ab8500)) { 491af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts; 492af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 493af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 494af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); 495af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x1F; 496af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8505_usb_link_status_update(ab, lsts); 497af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 498af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 499af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return ret; 500af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 501af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 502af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 503af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Disconnection Sequence: 504af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Disconect Interrupt 505af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Disable regulators 506af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Disable AB clock 507af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Disable the Phy 508af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Link Status Interrupt 509af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Disable Musb Clock 510af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 511af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data) 512af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 513af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *) data; 514af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum usb_phy_events event = UX500_MUSB_NONE; 515af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 516af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Link status will not be updated till phy is disabled. */ 517af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_HOST) { 518af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 519af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 520af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 521af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 522af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_dis(ab); 523af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 524af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 525af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 526af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_PERIPHERAL) { 527af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 528af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 529af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_dis(ab); 530af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 531af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_CLEAN, &ab->vbus_draw); 532af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 533af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 534af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 535af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 536af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 537af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 538af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_DEDICATED_CHG) { 539af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_wd_linkstatus(ab, 540af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN); 541af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 542af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 543af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN, 0); 544af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 545af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 546969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 547af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return IRQ_HANDLED; 548969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 549969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 550af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_link_status_irq(int irq, void *data) 551969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 552969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = (struct ab8500_usb *) data; 553969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 554af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_usb_link_status_update(ab); 555969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 556969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return IRQ_HANDLED; 557969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 558969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 559af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic void ab8500_usb_delayed_work(struct work_struct *work) 560af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 561af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab = container_of(work, struct ab8500_usb, 562af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dwork.work); 563af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 564af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_usb_link_status_update(ab); 565af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 566af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 567969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_phy_disable_work(struct work_struct *work) 568969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 569969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = container_of(work, struct ab8500_usb, 570969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab phy_dis_work); 571969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 572144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->host) 573969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 574969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 575144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->gadget) 576969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 577969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 578969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 579c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisettistatic unsigned ab8500_eyediagram_workaroud(struct ab8500_usb *ab, unsigned mA) 580c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti{ 581c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti /* 582c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * AB8500 V2 has eye diagram issues when drawing more than 100mA from 583c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * VBUS. Set charging current to 100mA in case of standard host 584c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti */ 585c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (is_ab8500_2p0_or_earlier(ab->ab8500)) 586c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (mA > 100) 587c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = 100; 588c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 589c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti return mA; 590c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti} 591c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 592144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) 593969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 594969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 595969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 596144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!phy) 597969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 598969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 599144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(phy); 600969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 601c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = ab8500_eyediagram_workaroud(ab, mA); 602c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 603969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = mA; 604969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 60577f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 60677f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri UX500_MUSB_VBUS, &ab->vbus_draw); 60777f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri 608969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 609969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 610969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 6118675381109b0eb1c948a423c2b35e3f4509cb25eHeikki Krogerusstatic int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) 612969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 613969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* TODO */ 614969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 615969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 616969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 617144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_peripheral(struct usb_otg *otg, 618144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_gadget *gadget) 619969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 620969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 621969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 622969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 623969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 624969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 625144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 626969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 627969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 628969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 629969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 630969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 631969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 632969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!gadget) { 633144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->gadget = NULL; 634969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 635969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } else { 636144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->gadget = gadget; 637144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->phy->state = OTG_STATE_B_IDLE; 638969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 639969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Phy will not be enabled if cable is already 640969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * plugged-in. Schedule to enable phy. 641969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Use same delay to avoid any race condition. 642969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 643969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_delayed_work(&ab->dwork, ab->link_status_wait); 644969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 645969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 646969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 647969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 648969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 649144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) 650969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 651969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 652969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 653969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 654969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 655969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 656144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 657969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 658969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 659969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 660969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 661969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 662969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 663969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!host) { 664144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->host = NULL; 665969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 666969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } else { 667144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->host = host; 668969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Phy will not be enabled if cable is already 669969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * plugged-in. Schedule to enable phy. 670969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Use same delay to avoid any race condition. 671969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 672969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_delayed_work(&ab->dwork, ab->link_status_wait); 673969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 674969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 675969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 676969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 677969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 678e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieristatic int ab8500_usb_regulator_get(struct ab8500_usb *ab) 679e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri{ 680e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri int err; 681e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 682e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ape = devm_regulator_get(ab->dev, "v-ape"); 683e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ape)) { 684e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get v-ape supply\n"); 685e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ape); 686e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 687e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 688e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 689e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ulpi = devm_regulator_get(ab->dev, "vddulpivio18"); 690e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ulpi)) { 691e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get vddulpivio18 supply\n"); 692e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ulpi); 693e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 694e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 695e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 696e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_musb = devm_regulator_get(ab->dev, "musb_1v8"); 697e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_musb)) { 698e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get musb_1v8 supply\n"); 699e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_musb); 700e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 701e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 702e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 703e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return 0; 704e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri} 705e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 706af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_irq_setup(struct platform_device *pdev, 707af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab) 708969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 709969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 710af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int irq; 711969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 712af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); 713af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 714969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab dev_err(&pdev->dev, "Link status irq not found\n"); 715af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 716af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 717af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 718af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_link_status_irq, 719af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status", ab); 720af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (err < 0) { 721af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for link status irq\n"); 722af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return err; 723969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 724969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 725af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); 726af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 727af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(&pdev->dev, "ID fall irq not found\n"); 728af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 729af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 730af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 731af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_disconnect_irq, 732af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-id-fall", ab); 733969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err < 0) { 734af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for ID fall irq\n"); 735af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return err; 736af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 737af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 738af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); 739af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 740af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(&pdev->dev, "VBUS fall irq not found\n"); 741af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 742af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 743af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 744af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_disconnect_irq, 745af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-vbus-fall", ab); 746af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (err < 0) { 747af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); 748969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return err; 749969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 750969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 751969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 752969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 753969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 75441ac7b3ab7fe1d6175839947a877fdf95cbd2211Bill Pembertonstatic int ab8500_usb_probe(struct platform_device *pdev) 755969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 756969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 75773f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri struct ab8500 *ab8500; 758144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_otg *otg; 759969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 760969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int rev; 761969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 76273f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab8500 = dev_get_drvdata(pdev->dev.parent); 763969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab rev = abx500_get_chip_id(&pdev->dev); 76473f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri 76573f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri if (is_ab8500_1p1_or_earlier(ab8500)) { 76673f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev); 767969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 768969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 769969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 77081ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri ab = devm_kzalloc(&pdev->dev, sizeof(*ab), GFP_KERNEL); 771969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!ab) 772969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENOMEM; 773969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 77481ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); 77581ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri if (!otg) 776144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return -ENOMEM; 777144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 778969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->dev = &pdev->dev; 77973f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab->ab8500 = ab8500; 780144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.dev = ab->dev; 781144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg = otg; 782144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.label = "ab8500"; 783144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_suspend = ab8500_usb_set_suspend; 784144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_power = ab8500_usb_set_power; 785144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.state = OTG_STATE_UNDEFINED; 786144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 787144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->phy = &ab->phy; 788144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_host = ab8500_usb_set_host; 789144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_peripheral = ab8500_usb_set_peripheral; 790969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 791969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_set_drvdata(pdev, ab); 792969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 793144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); 794969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 795969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* v1: Wait for link status to become stable. 796969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * all: Updates form set_host and set_peripheral as they are atomic. 797969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 798969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab INIT_DELAYED_WORK(&ab->dwork, ab8500_usb_delayed_work); 799969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 800969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* all: Disable phy when called from set_host and set_peripheral */ 801969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); 802969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 803e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = ab8500_usb_regulator_get(ab); 804e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (err) 805e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 806e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 807af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = ab8500_usb_irq_setup(pdev, ab); 808969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err < 0) 80981ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri return err; 810969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 811662dca54ca67c92b7aa14b9a2ec54acacf33ce45Kishon Vijay Abraham I err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); 812969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err) { 813969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab dev_err(&pdev->dev, "Can't register transceiver\n"); 81481ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri return err; 815969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 816969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 8177124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Phy tuning values for AB8500 */ 8187124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 8197124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Enable the PBT/Bank 0x12 access */ 8207124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8217124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01); 8227124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8237124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", 8247124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8257124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8267124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8277124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8); 8287124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8297124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", 8307124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8317124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8327124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8337124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00); 8347124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8357124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", 8367124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8377124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8387124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8397124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); 8407124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8417124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", 8427124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8437124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8447124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Switch to normal mode/disable Bank 0x12 access */ 8457124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_set_register_interruptible(ab->dev, 8467124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x00); 8477124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8487124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", 8497124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8507124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti } 8517124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8527124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Phy tuning values for AB8505 */ 8537124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (is_ab8505(ab->ab8500)) { 8547124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Enable the PBT/Bank 0x12 access */ 8557124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8567124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 8577124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0x01, 0x01); 8587124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8597124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", 8607124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8617124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8627124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8637124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 8647124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0xC8, 0xC8); 8657124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8667124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", 8677124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8687124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8697124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8707124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 8717124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0x60, 0x60); 8727124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8737124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", 8747124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8757124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8767124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8777124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 8787124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0xFC, 0x80); 8797124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8807124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8817124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", 8827124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8837124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 8847124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti /* Switch to normal mode/disable Bank 0x12 access */ 8857124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err = abx500_mask_and_set_register_interruptible(ab->dev, 8867124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 8877124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 0x00, 0x00); 8887124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti if (err < 0) 8897124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", 8907124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti err); 8917124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti } 8927124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 893af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Needed to enable ID detection. */ 894af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_wd_workaround(ab); 895af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 89673f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); 897969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 898969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 899969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 900969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 901fb4e98ab63433c4d3a1588ea91c73f1cd7ebaa00Bill Pembertonstatic int ab8500_usb_remove(struct platform_device *pdev) 902969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 903969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = platform_get_drvdata(pdev); 904969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 905969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab cancel_delayed_work_sync(&ab->dwork); 906969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 907969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab cancel_work_sync(&ab->phy_dis_work); 908969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 909662dca54ca67c92b7aa14b9a2ec54acacf33ce45Kishon Vijay Abraham I usb_remove_phy(&ab->phy); 910969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 911f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab if (ab->mode == USB_HOST) 912f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 913f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab else if (ab->mode == USB_PERIPHERAL) 914f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 915969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 916969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_set_drvdata(pdev, NULL); 917969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 918969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 919969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 920969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 921969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic struct platform_driver ab8500_usb_driver = { 922969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .probe = ab8500_usb_probe, 9237690417db5085f0de03aa70b8ca01b0118e8a1b4Bill Pemberton .remove = ab8500_usb_remove, 924969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .driver = { 925969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .name = "ab8500-usb", 926969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .owner = THIS_MODULE, 927969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab }, 928969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 929969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 930969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic int __init ab8500_usb_init(void) 931969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 932969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return platform_driver_register(&ab8500_usb_driver); 933969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 934969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabsubsys_initcall(ab8500_usb_init); 935969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 936969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void __exit ab8500_usb_exit(void) 937969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 938969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_driver_unregister(&ab8500_usb_driver); 939969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 940969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabmodule_exit(ab8500_usb_exit); 941969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 942969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_ALIAS("platform:ab8500_usb"); 943969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_AUTHOR("ST-Ericsson AB"); 944969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_DESCRIPTION("AB8500 usb transceiver driver"); 945969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_LICENSE("GPL"); 946