phy-ab8500-usb.c revision 54dfbb08051c2fa666bd4ce6cb7626b9e2a80655
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> 36969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 377124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_SYS_CTRL2_BLOCK */ 38969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_MAIN_WD_CTRL_REG 0x01 397124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 407124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_USB */ 41969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_USB_LINE_STAT_REG 0x80 42af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#define AB8505_USB_LINE_STAT_REG 0x94 43969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_USB_PHY_CTRL_REG 0x8A 44969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 457124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_DEVELOPMENT */ 467124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_BANK12_ACCESS 0x00 477124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 487124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_DEBUG */ 497124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE1 0x05 507124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE2 0x06 517124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE3 0x07 527124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 53969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_OTG_STAT_ID (1 << 0) 54969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) 55969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) 56969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) 57969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_WD_CTRL_KICK (1 << 1) 58969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 59969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_WD_KICK_DELAY_US 100 /* usec */ 60969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ 61af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#define AB8500_V20_31952_DISABLE_DELAY_US 100 /* usec */ 62969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 63969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab/* Usb line status register */ 64969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabenum ab8500_usb_link_status { 65af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_CONFIGURED_8500 = 0, 66af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_NC_8500, 67af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_NS_8500, 68af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_S_8500, 69af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_NM_8500, 70af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_HS_8500, 71af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_HS_CHIRP_8500, 72af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_DEDICATED_CHG_8500, 73af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_A_8500, 74af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_B_8500, 75af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_NM_8500, 76af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_HS_8500, 77af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_HS_CHIRP_8500, 78af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HM_IDGND_8500, 79af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED_8500, 80af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_VALID_LINK_8500, 81af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri}; 82af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 83af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltierienum ab8505_usb_link_status { 84af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_CONFIGURED_8505 = 0, 85af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_NC_8505, 86af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_NS_8505, 87af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_S_8505, 88af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CDP_8505, 89af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED0_8505, 90af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED1_8505, 91af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_DEDICATED_CHG_8505, 92af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_A_8505, 93af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_B_8505, 94af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_NM_8505, 95af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED2_8505, 96af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED3_8505, 97af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HM_IDGND_8505, 98af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGERPORT_NOT_OK_8505, 99af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGER_DM_HIGH_8505, 100af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8505, 101af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_UPSTREAM_NO_IDGNG_NO_VBUS_8505, 102af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_UPSTREAM_8505, 103af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGER_SE1_8505, 104af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CARKIT_CHGR_1_8505, 105af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CARKIT_CHGR_2_8505, 106af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_DOCK_CHGR_8505, 107af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8505, 108af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8505, 109af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505, 110af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505, 111af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8505, 112af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri}; 113af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 114af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltierienum ab8500_usb_mode { 115af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_IDLE = 0, 116af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_PERIPHERAL, 117af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_HOST, 118af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_DEDICATED_CHG 119969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 120969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 121969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstruct ab8500_usb { 122144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_phy phy; 123969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct device *dev; 12473f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri struct ab8500 *ab8500; 125969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab unsigned vbus_draw; 126969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct delayed_work dwork; 127969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct work_struct phy_dis_work; 128969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab unsigned long link_status_wait; 129af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_mode mode; 130e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ape; 131e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_musb; 132e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ulpi; 13354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int saved_v_ulpi; 134af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int previous_link_status_state; 135969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 136969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 137144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) 138969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 139144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return container_of(x, struct ab8500_usb, phy); 140969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 141969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 142969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_wd_workaround(struct ab8500_usb *ab) 143969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 144969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 145969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 146969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 147969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_BIT_WD_CTRL_ENABLE); 148969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 149969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab udelay(AB8500_WD_KICK_DELAY_US); 150969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 151969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 152969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 153969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 154969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab (AB8500_BIT_WD_CTRL_ENABLE 155969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab | AB8500_BIT_WD_CTRL_KICK)); 156969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 15773f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri udelay(AB8500_WD_V11_DISABLE_DELAY_US); 158969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 159969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 160969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 161969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 162969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 0); 163969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 164969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 16554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_enable(struct ab8500_usb *ab) 16654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 16754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret, volt; 16854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 16954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_enable(ab->v_ape); 17054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 17154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 17254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi); 17354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ab->saved_v_ulpi < 0) 17454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to get v_ulpi voltage\n"); 17554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 17654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 1300000, 1350000); 17754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 17854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n", 17954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 18054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 18154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_optimum_mode(ab->v_ulpi, 28000); 18254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 18354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", 18454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 18554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 18654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 18754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_enable(ab->v_ulpi); 18854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 18954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 19054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt = regulator_get_voltage(ab->v_ulpi); 19154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if ((volt != 1300000) && (volt != 1350000)) 19254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", 19354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt); 19454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 19554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 19654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_enable(ab->v_musb); 19754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 19854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 19954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_disable(struct ab8500_usb *ab) 20054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 20154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret; 20254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_musb); 20454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ulpi); 20654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 20754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri /* USB is not the only consumer of Vintcore, restore old settings */ 20854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (!is_ab8500_2p0_or_earlier(ab->ab8500)) { 20954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ab->saved_v_ulpi > 0) { 21054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 21154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ab->saved_v_ulpi); 21254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 21354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to %duV, ret=%d\n", 21454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ret); 21554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 21654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 21754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_optimum_mode(ab->v_ulpi, 0); 21854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 21954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", 22054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 22154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 22254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 22354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ape); 22454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 22554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 226af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit) 227af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 228af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Workaround for v2.0 bug # 31952 */ 229af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 230af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 231af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 232af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri bit, bit); 233af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri udelay(AB8500_V20_31952_DISABLE_DELAY_US); 234af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 235af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 236af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 237c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host) 238969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 239c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 240c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 241c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 242969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 24354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_enable(ab); 24454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 245c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 246c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 247c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, bit); 248c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri} 249c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 250c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host) 251c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri{ 252c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 253c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 254c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 255c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 256c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_linkstatus(ab, bit); 257c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 258c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 259c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 260c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, 0); 261969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 262c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri /* Needed to disable the phy.*/ 263c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_workaround(ab); 26454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 26554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_disable(ab); 266969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 267969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 268c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_enable(ab, true) 269c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_disable(ab, true) 270c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_enable(ab, false) 271c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_disable(ab, false) 272969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 273af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8505_usb_link_status_update(struct ab8500_usb *ab, 274af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts) 275969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 276af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 277969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 278af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts); 279969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 280af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 281af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen at the time of 282af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in RIDA state 283af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 284af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 && 285af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_NC_8505)) 286af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 287af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 288af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 289969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 290969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab switch (lsts) { 291af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8505: 292af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 293af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8505: 294af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED0_8505: 295af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED1_8505: 296af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED2_8505: 297af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED3_8505: 298af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 299144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = false; 300969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = 0; 301af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 302af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 303af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 304af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Fallback to default B_IDLE as nothing 305af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * is connected 306af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 307af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 308969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 309969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 310af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8505: 311af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 312af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8505: 313af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8505: 314af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8505: 315af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_CDP_8505: 316af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 317af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 318969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_en(ab); 319af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 320af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 321969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 322af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 323af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 324969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 325969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 326af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8505: 327af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_DOCK_CHGR_8505: 328af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 329af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8505: 330af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 331af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 332969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_en(ab); 333af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 334af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 335969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 336144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = true; 337af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 338af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 339af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 340af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 341969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 342969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 343af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8505: 344af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 345af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 346af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 347af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 348af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 349af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 350af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri default: 351969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 352969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 353969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 354af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 355af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 356af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 357af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_link_status_update(struct ab8500_usb *ab, 358af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts) 359af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 360af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 361af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 362af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts); 363af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 364af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 365af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen in case of a 366af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in IDGND and RIDA stage 367af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 368af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 && 369af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_C_NS_8500 || 370af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500)) 371af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 372af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 373af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 && 374af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500) 375af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 376af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 377af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 378af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 379af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri switch (lsts) { 380af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8500: 381af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 382af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8500: 383af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_VALID_LINK_8500: 384af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 385af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 386af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 387af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 388af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 389af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Fallback to default B_IDLE as nothing is connected */ 390af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 391af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 392af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 393af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8500: 394af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_8500: 395af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_CHIRP_8500: 396af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 397af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8500: 398af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8500: 399af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8500: 400af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_NM_8500: 401af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_8500: 402af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_CHIRP_8500: 403af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 404af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 405af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_en(ab); 406af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 407af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 408af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 409af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 410af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 411af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 412af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 413af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8500: 414af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 415af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8500: 416af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 417af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 418af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_en(ab); 419af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 420af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 421af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 422af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = true; 423af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 424af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 425af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 426af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 427af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 428af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 429af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8500: 430af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 431af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 432af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 433af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 434af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 435af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 436af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED_8500: 437af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 438af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 439969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 440969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 441969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 442969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 443af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 444af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Connection Sequence: 445af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Link Status Interrupt 446af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Enable AB clock 447af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Enable AB regulators 448af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Enable USB phy 449af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Reset the musb controller 450af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Switch the ULPI GPIO pins to fucntion mode 451af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 7. Enable the musb Peripheral5 clock 452af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 8. Restore MUSB context 453af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 454af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int abx500_usb_link_status_update(struct ab8500_usb *ab) 455969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 456af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri u8 reg; 457af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int ret = 0; 458af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 459af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500(ab->ab8500)) { 460af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts; 461af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 462af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 463af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); 464af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x0F; 465af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8500_usb_link_status_update(ab, lsts); 466af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } else if (is_ab8505(ab->ab8500)) { 467af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts; 468af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 469af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 470af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); 471af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x1F; 472af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8505_usb_link_status_update(ab, lsts); 473af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 474af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 475af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return ret; 476af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 477af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 478af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 479af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Disconnection Sequence: 480af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Disconect Interrupt 481af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Disable regulators 482af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Disable AB clock 483af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Disable the Phy 484af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Link Status Interrupt 485af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Disable Musb Clock 486af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 487af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data) 488af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 489af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *) data; 490af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum usb_phy_events event = UX500_MUSB_NONE; 491af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 492af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Link status will not be updated till phy is disabled. */ 493af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_HOST) { 494af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 495af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 496af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 497af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 498af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_dis(ab); 499af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 500af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 501af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 502af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_PERIPHERAL) { 503af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 504af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 505af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_dis(ab); 506af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 507af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_CLEAN, &ab->vbus_draw); 508af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 509af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 510af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 511af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 512af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 513af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 514af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_DEDICATED_CHG) { 515af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_wd_linkstatus(ab, 516af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN); 517af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 518af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 519af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN, 0); 520af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 521af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 522969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 523af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return IRQ_HANDLED; 524969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 525969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 526af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_link_status_irq(int irq, void *data) 527969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 528969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = (struct ab8500_usb *) data; 529969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 530af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_usb_link_status_update(ab); 531969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 532969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return IRQ_HANDLED; 533969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 534969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 535af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic void ab8500_usb_delayed_work(struct work_struct *work) 536af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 537af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab = container_of(work, struct ab8500_usb, 538af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dwork.work); 539af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 540af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_usb_link_status_update(ab); 541af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 542af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 543969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_phy_disable_work(struct work_struct *work) 544969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 545969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = container_of(work, struct ab8500_usb, 546969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab phy_dis_work); 547969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 548144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->host) 549969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 550969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 551144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->gadget) 552969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 553969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 554969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 555c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisettistatic unsigned ab8500_eyediagram_workaroud(struct ab8500_usb *ab, unsigned mA) 556c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti{ 557c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti /* 558c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * AB8500 V2 has eye diagram issues when drawing more than 100mA from 559c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * VBUS. Set charging current to 100mA in case of standard host 560c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti */ 561c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (is_ab8500_2p0_or_earlier(ab->ab8500)) 562c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (mA > 100) 563c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = 100; 564c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 565c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti return mA; 566c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti} 567c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 568144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) 569969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 570969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 571969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 572144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!phy) 573969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 574969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 575144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(phy); 576969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 577c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = ab8500_eyediagram_workaroud(ab, mA); 578c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 579969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = mA; 580969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 581969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (mA) 582144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus atomic_notifier_call_chain(&ab->phy.notifier, 583af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_ENUMERATED, ab->phy.otg->gadget); 584969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 585969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 586969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 587969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab/* TODO: Implement some way for charging or other drivers to read 588969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * ab->vbus_draw. 589969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 590969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 5918675381109b0eb1c948a423c2b35e3f4509cb25eHeikki Krogerusstatic int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) 592969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 593969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* TODO */ 594969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 595969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 596969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 597144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_peripheral(struct usb_otg *otg, 598144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_gadget *gadget) 599969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 600969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 601969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 602969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 603969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 604969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 605144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 606969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 607969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 608969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 609969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 610969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 611969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 612969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!gadget) { 613144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->gadget = NULL; 614969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 615969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } else { 616144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->gadget = gadget; 617144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->phy->state = OTG_STATE_B_IDLE; 618969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 619969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Phy will not be enabled if cable is already 620969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * plugged-in. Schedule to enable phy. 621969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Use same delay to avoid any race condition. 622969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 623969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_delayed_work(&ab->dwork, ab->link_status_wait); 624969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 625969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 626969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 627969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 628969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 629144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) 630969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 631969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 632969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 633969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 634969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 635969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 636144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 637969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 638969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 639969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 640969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 641969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 642969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 643969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!host) { 644144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->host = NULL; 645969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 646969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } else { 647144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->host = host; 648969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Phy will not be enabled if cable is already 649969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * plugged-in. Schedule to enable phy. 650969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Use same delay to avoid any race condition. 651969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 652969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_delayed_work(&ab->dwork, ab->link_status_wait); 653969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 654969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 655969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 656969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 657969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 658e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieristatic int ab8500_usb_regulator_get(struct ab8500_usb *ab) 659e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri{ 660e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri int err; 661e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 662e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ape = devm_regulator_get(ab->dev, "v-ape"); 663e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ape)) { 664e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get v-ape supply\n"); 665e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ape); 666e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 667e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 668e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 669e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ulpi = devm_regulator_get(ab->dev, "vddulpivio18"); 670e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ulpi)) { 671e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get vddulpivio18 supply\n"); 672e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ulpi); 673e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 674e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 675e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 676e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_musb = devm_regulator_get(ab->dev, "musb_1v8"); 677e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_musb)) { 678e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get musb_1v8 supply\n"); 679e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_musb); 680e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 681e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 682e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 683e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return 0; 684e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri} 685e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 686af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_irq_setup(struct platform_device *pdev, 687af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab) 688969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 689969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 690af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int irq; 691969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 692af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); 693af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 694969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab dev_err(&pdev->dev, "Link status irq not found\n"); 695af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 696af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 697af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 698af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_link_status_irq, 699af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status", ab); 700af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (err < 0) { 701af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for link status irq\n"); 702af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return err; 703969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 704969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 705af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); 706af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 707af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(&pdev->dev, "ID fall irq not found\n"); 708af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 709af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 710af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 711af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_disconnect_irq, 712af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-id-fall", ab); 713969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err < 0) { 714af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for ID fall irq\n"); 715af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return err; 716af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 717af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 718af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); 719af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (irq < 0) { 720af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(&pdev->dev, "VBUS fall irq not found\n"); 721af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return irq; 722af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 723af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 724af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_disconnect_irq, 725af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, "usb-vbus-fall", ab); 726af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (err < 0) { 727af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); 728969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return err; 729969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 730969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 731969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 732969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 733969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 73441ac7b3ab7fe1d6175839947a877fdf95cbd2211Bill Pembertonstatic int ab8500_usb_probe(struct platform_device *pdev) 735969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 736969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 73773f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri struct ab8500 *ab8500; 738144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_otg *otg; 739969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 740969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int rev; 741969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 74273f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab8500 = dev_get_drvdata(pdev->dev.parent); 743969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab rev = abx500_get_chip_id(&pdev->dev); 74473f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri 74573f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri if (is_ab8500_1p1_or_earlier(ab8500)) { 74673f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev); 747969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 748969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 749969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 75081ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri ab = devm_kzalloc(&pdev->dev, sizeof(*ab), GFP_KERNEL); 751969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!ab) 752969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENOMEM; 753969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 75481ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); 75581ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri if (!otg) 756144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return -ENOMEM; 757144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 758969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->dev = &pdev->dev; 75973f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab->ab8500 = ab8500; 760144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.dev = ab->dev; 761144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg = otg; 762144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.label = "ab8500"; 763144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_suspend = ab8500_usb_set_suspend; 764144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_power = ab8500_usb_set_power; 765144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.state = OTG_STATE_UNDEFINED; 766144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 767144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->phy = &ab->phy; 768144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_host = ab8500_usb_set_host; 769144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_peripheral = ab8500_usb_set_peripheral; 770969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 771969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_set_drvdata(pdev, ab); 772969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 773144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ATOMIC_INIT_NOTIFIER_HEAD(&ab->phy.notifier); 774969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 775969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* v1: Wait for link status to become stable. 776969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * all: Updates form set_host and set_peripheral as they are atomic. 777969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 778969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab INIT_DELAYED_WORK(&ab->dwork, ab8500_usb_delayed_work); 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 87673f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); 877969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 878969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 879969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 880969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 881fb4e98ab63433c4d3a1588ea91c73f1cd7ebaa00Bill Pembertonstatic int ab8500_usb_remove(struct platform_device *pdev) 882969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 883969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = platform_get_drvdata(pdev); 884969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 885969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab cancel_delayed_work_sync(&ab->dwork); 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 891969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 892969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 893969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 894969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_set_drvdata(pdev, NULL); 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