1969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab/* 2969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * drivers/usb/otg/ab8500_usb.c 3969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 40c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri * USB transceiver driver for AB8500 family chips 5969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 60c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri * Copyright (C) 2010-2013 ST-Ericsson AB 7969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> 80c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri * Avinash Kumar <avinash.kumar@stericsson.com> 9f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri * Thirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.com> 10969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 11969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * This program is free software; you can redistribute it and/or modify 12969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * it under the terms of the GNU General Public License as published by 13969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * the Free Software Foundation; either version 2 of the License, or 14969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * (at your option) any later version. 15969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 16969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * This program is distributed in the hope that it will be useful, 17969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * but WITHOUT ANY WARRANTY; without even the implied warranty of 18969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * GNU General Public License for more details. 20969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 21969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * You should have received a copy of the GNU General Public License 22969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * along with this program; if not, write to the Free Software 23969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * 25969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 26969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 27969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/module.h> 28969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/platform_device.h> 29969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/usb/otg.h> 30969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/slab.h> 31969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/notifier.h> 32969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/interrupt.h> 33969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/delay.h> 34d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab#include <linux/clk.h> 35d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab#include <linux/err.h> 36969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#include <linux/mfd/abx500.h> 37ee66e653ca7425bc8ffca4e00f19a8057cd14e4dLinus Walleij#include <linux/mfd/abx500/ab8500.h> 38af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#include <linux/usb/musb-ux500.h> 39e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri#include <linux/regulator/consumer.h> 40899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard#include <linux/pinctrl/consumer.h> 41969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 427124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_SYS_CTRL2_BLOCK */ 43969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_MAIN_WD_CTRL_REG 0x01 447124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 457124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_USB */ 46969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_USB_LINE_STAT_REG 0x80 47af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#define AB8505_USB_LINE_STAT_REG 0x94 480c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_USB_LINK_STAT_REG 0x94 49f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri#define AB9540_USB_LINK_STAT_REG 0x94 500c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_USB_OTG_CTL_REG 0x87 51969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_USB_PHY_CTRL_REG 0x8A 520c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_VBUS_CTRL_REG 0x82 53969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 547124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_DEVELOPMENT */ 557124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_BANK12_ACCESS 0x00 567124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 577124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti/* Bank AB8500_DEBUG */ 580c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_DEBUG 0x32 597124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE1 0x05 607124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE2 0x06 617124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti#define AB8500_USB_PHY_TUNE3 0x07 627124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 630c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri/* Bank AB8500_INTERRUPT */ 640c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8500_IT_SOURCE2_REG 0x01 650c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 66969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_OTG_STAT_ID (1 << 0) 67969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) 68969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) 69969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) 70969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_BIT_WD_CTRL_KICK (1 << 1) 710c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8500_BIT_SOURCE2_VBUSDET (1 << 7) 720c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_BIT_OTG_CTL_VBUS_VALID_ENA (1 << 0) 730c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_BIT_OTG_CTL_ID_HOST_ENA (1 << 1) 740c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_BIT_OTG_CTL_ID_DEV_ENA (1 << 5) 750c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8540_BIT_VBUS_CTRL_CHARG_DET_ENA (1 << 0) 76969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 77969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_WD_KICK_DELAY_US 100 /* usec */ 78969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab#define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ 79af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri#define AB8500_V20_31952_DISABLE_DELAY_US 100 /* usec */ 80969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 81969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab/* Usb line status register */ 82969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabenum ab8500_usb_link_status { 83af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_CONFIGURED_8500 = 0, 84af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_NC_8500, 85af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_NS_8500, 86af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_S_8500, 87af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_NM_8500, 88af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_HS_8500, 89af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HOST_CHG_HS_CHIRP_8500, 90af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_DEDICATED_CHG_8500, 91af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_A_8500, 92af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_B_8500, 93af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_NM_8500, 94af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_HS_8500, 95af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_HS_CHIRP_8500, 96af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HM_IDGND_8500, 97af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED_8500, 98af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_VALID_LINK_8500, 99af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri}; 100af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 101af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltierienum ab8505_usb_link_status { 102af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_NOT_CONFIGURED_8505 = 0, 103af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_NC_8505, 104af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_NS_8505, 105af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_HOST_C_S_8505, 106af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CDP_8505, 107af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED0_8505, 108af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED1_8505, 109af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_DEDICATED_CHG_8505, 110af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_A_8505, 111af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_B_8505, 112af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_RID_C_NM_8505, 113af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED2_8505, 114af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_RESERVED3_8505, 115af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_HM_IDGND_8505, 116af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGERPORT_NOT_OK_8505, 117af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGER_DM_HIGH_8505, 118af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8505, 119af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_UPSTREAM_NO_IDGNG_NO_VBUS_8505, 120af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_STD_UPSTREAM_8505, 121af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CHARGER_SE1_8505, 122af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CARKIT_CHGR_1_8505, 123af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_CARKIT_CHGR_2_8505, 124af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_ACA_DOCK_CHGR_8505, 125af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8505, 126af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8505, 127af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505, 128af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505, 129af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8505, 130af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri}; 131af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 1320c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltierienum ab8540_usb_link_status { 1330c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_NOT_CONFIGURED_8540 = 0, 1340c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_STD_HOST_NC_8540, 1350c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_STD_HOST_C_NS_8540, 1360c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_STD_HOST_C_S_8540, 1370c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_CDP_8540, 1380c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_RESERVED0_8540, 1390c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_RESERVED1_8540, 1400c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_DEDICATED_CHG_8540, 1410c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_ACA_RID_A_8540, 1420c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_ACA_RID_B_8540, 1430c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_ACA_RID_C_NM_8540, 1440c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_RESERVED2_8540, 1450c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_RESERVED3_8540, 1460c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_HM_IDGND_8540, 1470c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_CHARGERPORT_NOT_OK_8540, 1480c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_CHARGER_DM_HIGH_8540, 1490c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8540, 1500c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_STD_UPSTREAM_NO_IDGNG_VBUS_8540, 1510c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_STD_UPSTREAM_8540, 1520c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_CHARGER_SE1_8540, 1530c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_CARKIT_CHGR_1_8540, 1540c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_CARKIT_CHGR_2_8540, 1550c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_ACA_DOCK_CHGR_8540, 1560c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8540, 1570c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8540, 1580c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8540, 1590c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8540, 1600c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8540 1610c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri}; 1620c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 163f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltierienum ab9540_usb_link_status { 164f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_NOT_CONFIGURED_9540 = 0, 165f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_STD_HOST_NC_9540, 166f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_STD_HOST_C_NS_9540, 167f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_STD_HOST_C_S_9540, 168f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_CDP_9540, 169f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_RESERVED0_9540, 170f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_RESERVED1_9540, 171f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_DEDICATED_CHG_9540, 172f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_ACA_RID_A_9540, 173f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_ACA_RID_B_9540, 174f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_ACA_RID_C_NM_9540, 175f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_RESERVED2_9540, 176f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_RESERVED3_9540, 177f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_HM_IDGND_9540, 178f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_CHARGERPORT_NOT_OK_9540, 179f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_CHARGER_DM_HIGH_9540, 180f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_PHYEN_NO_VBUS_NO_IDGND_9540, 181f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_STD_UPSTREAM_NO_IDGNG_VBUS_9540, 182f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_STD_UPSTREAM_9540, 183f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_CHARGER_SE1_9540, 184f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_CARKIT_CHGR_1_9540, 185f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_CARKIT_CHGR_2_9540, 186f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_ACA_DOCK_CHGR_9540, 187f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_9540, 188f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_9540, 189f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_EN_9540, 190f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_9540, 191f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_9540 192f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri}; 193f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 194af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltierienum ab8500_usb_mode { 195af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_IDLE = 0, 196af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_PERIPHERAL, 197af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_HOST, 198af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri USB_DEDICATED_CHG 199969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 200969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 201bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri/* Register USB_LINK_STATUS interrupt */ 202bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri#define AB8500_USB_FLAG_USE_LINK_STATUS_IRQ (1 << 0) 203bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri/* Register ID_WAKEUP_F interrupt */ 204bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri#define AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ (1 << 1) 205bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri/* Register VBUS_DET_F interrupt */ 206bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri#define AB8500_USB_FLAG_USE_VBUS_DET_IRQ (1 << 2) 207bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri/* Driver is using the ab-iddet driver*/ 208bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri#define AB8500_USB_FLAG_USE_AB_IDDET (1 << 3) 209bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri/* Enable setting regulators voltage */ 210bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri#define AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE (1 << 4) 2110c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri/* Enable the check_vbus_status workaround */ 2120c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8500_USB_FLAG_USE_CHECK_VBUS_STATUS (1 << 5) 2130c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri/* Enable the vbus host workaround */ 2140c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri#define AB8500_USB_FLAG_USE_VBUS_HOST_QUIRK (1 << 6) 215bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri 216969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstruct ab8500_usb { 217144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_phy phy; 218969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct device *dev; 21973f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri struct ab8500 *ab8500; 220969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab unsigned vbus_draw; 221969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct work_struct phy_dis_work; 2220c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri struct work_struct vbus_event_work; 223af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_mode mode; 224d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab struct clk *sysclk; 225e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ape; 226e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_musb; 227e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri struct regulator *v_ulpi; 22854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int saved_v_ulpi; 229af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int previous_link_status_state; 230899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard struct pinctrl *pinctrl; 231899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard struct pinctrl_state *pins_sleep; 2320c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri bool enabled_charging_detection; 233bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri unsigned int flags; 234969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 235969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 236144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic inline struct ab8500_usb *phy_to_ab(struct usb_phy *x) 237969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 238144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return container_of(x, struct ab8500_usb, phy); 239969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 240969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 241969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_wd_workaround(struct ab8500_usb *ab) 242969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 243969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 244969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 245969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 246969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_BIT_WD_CTRL_ENABLE); 247969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 248969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab udelay(AB8500_WD_KICK_DELAY_US); 249969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 250969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 251969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 252969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 253969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab (AB8500_BIT_WD_CTRL_ENABLE 254969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab | AB8500_BIT_WD_CTRL_KICK)); 255969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 25673f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri udelay(AB8500_WD_V11_DISABLE_DELAY_US); 257969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 258969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab abx500_set_register_interruptible(ab->dev, 259969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_SYS_CTRL2_BLOCK, 260969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab AB8500_MAIN_WD_CTRL_REG, 261969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 0); 262969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 263969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 26454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_enable(struct ab8500_usb *ab) 26554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 26654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret, volt; 26754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 26888b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri ret = regulator_enable(ab->v_ape); 26988b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri if (ret) 27088b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri dev_err(ab->dev, "Failed to enable v-ape\n"); 27154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 272bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { 27354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi); 27454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ab->saved_v_ulpi < 0) 27554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to get v_ulpi voltage\n"); 27654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 27754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 1300000, 1350000); 27854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 27954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n", 28054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 28154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 28254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_optimum_mode(ab->v_ulpi, 28000); 28354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 28454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", 28554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 28654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 28754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 28888b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri ret = regulator_enable(ab->v_ulpi); 28988b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri if (ret) 29088b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri dev_err(ab->dev, "Failed to enable vddulpivio18\n"); 29154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 292bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { 29354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt = regulator_get_voltage(ab->v_ulpi); 29454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if ((volt != 1300000) && (volt != 1350000)) 29554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n", 29654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri volt); 29754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 29854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 29988b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri ret = regulator_enable(ab->v_musb); 30088b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri if (ret) 30188b1c78db32782041d9548e3c4ab405f9e9eab59Fabio Baltieri dev_err(ab->dev, "Failed to enable musb_1v8\n"); 30254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 30354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 30454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieristatic void ab8500_usb_regulator_disable(struct ab8500_usb *ab) 30554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri{ 30654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri int ret; 30754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 30854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_musb); 30954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 31054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ulpi); 31154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 31254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri /* USB is not the only consumer of Vintcore, restore old settings */ 313bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) { 31454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ab->saved_v_ulpi > 0) { 31554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 31654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ab->saved_v_ulpi); 31754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 31854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to %duV, ret=%d\n", 31954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab->saved_v_ulpi, ret); 32054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 32154dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 32254dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret = regulator_set_optimum_mode(ab->v_ulpi, 0); 32354dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri if (ret < 0) 32454dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n", 32554dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ret); 32654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri } 32754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 32854dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri regulator_disable(ab->v_ape); 32954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri} 33054dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 331af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit) 332af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 333af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Workaround for v2.0 bug # 31952 */ 334af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 335af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 336af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 337af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri bit, bit); 338af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri udelay(AB8500_V20_31952_DISABLE_DELAY_US); 339af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 340af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 341af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 342c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host) 343969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 344c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 345c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 346c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 347969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 348899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard /* mux and configure USB pins to DEFAULT state */ 349899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard ab->pinctrl = pinctrl_get_select(ab->dev, PINCTRL_STATE_DEFAULT); 350899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (IS_ERR(ab->pinctrl)) 351899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_err(ab->dev, "could not get/set default pinstate\n"); 352899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 353d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab if (clk_prepare_enable(ab->sysclk)) 354d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab dev_err(ab->dev, "can't prepare/enable clock\n"); 355d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab 35654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_enable(ab); 35754dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 358c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 359c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 360c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, bit); 3610c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 3620c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_VBUS_HOST_QUIRK) { 3630c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (sel_host) 3640c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_set_register_interruptible(ab->dev, 3650c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB, AB8540_USB_OTG_CTL_REG, 3660c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_BIT_OTG_CTL_VBUS_VALID_ENA | 3670c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_BIT_OTG_CTL_ID_HOST_ENA | 3680c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_BIT_OTG_CTL_ID_DEV_ENA); 3690c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 370c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri} 371c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 372c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieristatic void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host) 373c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri{ 374c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri u8 bit; 375c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN : 376c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN; 377c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 378c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_linkstatus(ab, bit); 379c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri 380c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 381c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 382c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri bit, 0); 383969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 384c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri /* Needed to disable the phy.*/ 385c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri ab8500_usb_wd_workaround(ab); 38654dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri 387d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab clk_disable_unprepare(ab->sysclk); 388d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab 38954dfbb08051c2fa666bd4ce6cb7626b9e2a80655Fabio Baltieri ab8500_usb_regulator_disable(ab); 390899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 391899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (!IS_ERR(ab->pinctrl)) { 392899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard /* configure USB pins to SLEEP state */ 393899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard ab->pins_sleep = pinctrl_lookup_state(ab->pinctrl, 394899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard PINCTRL_STATE_SLEEP); 395899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 396899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard if (IS_ERR(ab->pins_sleep)) 397899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_dbg(ab->dev, "could not get sleep pinstate\n"); 398899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard else if (pinctrl_select_state(ab->pinctrl, ab->pins_sleep)) 399899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard dev_err(ab->dev, "could not set pins to sleep state\n"); 400899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard 4013147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri /* 4023147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri * as USB pins are shared with iddet, release them to allow 403899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard * iddet to request them 404899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard */ 405899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard pinctrl_put(ab->pinctrl); 406899f0f561b51506f40eb78c9c4aaeeabf97cf35cPatrice Chotard } 407969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 408969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 409c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_enable(ab, true) 410c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_disable(ab, true) 411c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_enable(ab, false) 412c0ea70646ad66a83f09562621babae4700c2f322Fabio Baltieri#define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_disable(ab, false) 413969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 414f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieristatic int ab9540_usb_link_status_update(struct ab8500_usb *ab, 415f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri enum ab9540_usb_link_status lsts) 416f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri{ 417f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri enum ux500_musb_vbus_id_status event = 0; 418f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 419f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri dev_dbg(ab->dev, "ab9540_usb_link_status_update %d\n", lsts); 420f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 421f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->previous_link_status_state == USB_LINK_HM_IDGND_9540 && 422f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri (lsts == USB_LINK_STD_HOST_C_NS_9540 || 423f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri lsts == USB_LINK_STD_HOST_NC_9540)) 424f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri return 0; 425f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 426f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_9540 && 427f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri (lsts == USB_LINK_STD_HOST_NC_9540)) 428f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri return 0; 429f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 430f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->previous_link_status_state = lsts; 431f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 432f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri switch (lsts) { 433f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_ACA_RID_B_9540: 434f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_RIDB; 435f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_NOT_CONFIGURED_9540: 436f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_RESERVED0_9540: 437f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_RESERVED1_9540: 438f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_RESERVED2_9540: 439f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_RESERVED3_9540: 440f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->mode == USB_PERIPHERAL) 441f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 442f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri UX500_MUSB_CLEAN, &ab->vbus_draw); 443f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_IDLE; 444f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->phy.otg->default_a = false; 445f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->vbus_draw = 0; 446f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (event != UX500_MUSB_RIDB) 447f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_NONE; 448f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri /* Fallback to default B_IDLE as nothing is connected. */ 449f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 450f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri break; 451f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 452f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_ACA_RID_C_NM_9540: 453f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_RIDC; 454f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_STD_HOST_NC_9540: 455f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_STD_HOST_C_NS_9540: 456f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_STD_HOST_C_S_9540: 457f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_CDP_9540: 458f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->mode == USB_HOST) { 459f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_PERIPHERAL; 460f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_host_phy_dis(ab); 461f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_peri_phy_en(ab); 462f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 463f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 464f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 465f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->mode == USB_IDLE) { 466f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_PERIPHERAL; 467f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_peri_phy_en(ab); 468f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 469f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 470f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 471f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (event != UX500_MUSB_RIDC) 472f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_VBUS; 473f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri break; 474f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 475f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_ACA_RID_A_9540: 476f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_RIDA; 477f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_HM_IDGND_9540: 478f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_STD_UPSTREAM_9540: 479f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->mode == USB_PERIPHERAL) { 480f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_HOST; 481f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_peri_phy_dis(ab); 482f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_host_phy_en(ab); 483f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 484f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 485f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 486f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->mode == USB_IDLE) { 487f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_HOST; 488f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_host_phy_en(ab); 489f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 490f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 491f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 492f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->phy.otg->default_a = true; 493f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (event != UX500_MUSB_RIDA) 494f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_ID; 495f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 496f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 497f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event, &ab->vbus_draw); 498f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri break; 499f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 500f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_DEDICATED_CHG_9540: 501f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_DEDICATED_CHG; 502f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_CHARGER; 503f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 504f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event, &ab->vbus_draw); 505f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri break; 506f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 507f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_PHYEN_NO_VBUS_NO_IDGND_9540: 508f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri case USB_LINK_STD_UPSTREAM_NO_IDGNG_VBUS_9540: 509f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (!(is_ab9540_2p0_or_earlier(ab->ab8500))) { 510f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event = UX500_MUSB_NONE; 511f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->mode == USB_HOST) { 512f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->phy.otg->default_a = false; 513f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->vbus_draw = 0; 514f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 515f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event, &ab->vbus_draw); 516f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_host_phy_dis(ab); 517f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_IDLE; 518f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 519f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (ab->mode == USB_PERIPHERAL) { 520f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 521f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri event, &ab->vbus_draw); 522f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_peri_phy_dis(ab); 523f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 524f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri UX500_MUSB_CLEAN, 525f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri &ab->vbus_draw); 526f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->mode = USB_IDLE; 527f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->phy.otg->default_a = false; 528f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->vbus_draw = 0; 529f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 530f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 531f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri break; 532f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 533f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri default: 534f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri break; 535f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } 536f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 537f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri return 0; 538f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri} 539f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 5400c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieristatic int ab8540_usb_link_status_update(struct ab8500_usb *ab, 5410c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri enum ab8540_usb_link_status lsts) 5420c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri{ 5430c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 5440c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 5450c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri dev_dbg(ab->dev, "ab8540_usb_link_status_update %d\n", lsts); 5460c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 5470c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->enabled_charging_detection) { 5480c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* Disable USB Charger detection */ 5490c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 5500c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB, AB8540_VBUS_CTRL_REG, 5510c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_BIT_VBUS_CTRL_CHARG_DET_ENA, 0x00); 5520c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->enabled_charging_detection = false; 5530c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 5540c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 5550c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* 5560c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri * Spurious link_status interrupts are seen in case of a 5570c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri * disconnection of a device in IDGND and RIDA stage 5580c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri */ 5590c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8540 && 5600c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri (lsts == USB_LINK_STD_HOST_C_NS_8540 || 5610c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8540)) 5620c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri return 0; 5630c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 5640c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8540 && 5650c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri (lsts == USB_LINK_STD_HOST_NC_8540)) 5660c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri return 0; 5670c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 5680c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->previous_link_status_state = lsts; 5690c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 5700c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri switch (lsts) { 5710c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_ACA_RID_B_8540: 5720c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_RIDB; 5730c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8540: 5740c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_RESERVED0_8540: 5750c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_RESERVED1_8540: 5760c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_RESERVED2_8540: 5770c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_RESERVED3_8540: 5780c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->mode = USB_IDLE; 5790c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->phy.otg->default_a = false; 5800c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->vbus_draw = 0; 5810c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (event != UX500_MUSB_RIDB) 5820c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_NONE; 5830c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* 5840c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri * Fallback to default B_IDLE as nothing 5850c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri * is connected 5860c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri */ 5870c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 5880c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri break; 5890c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 5900c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8540: 5910c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_RIDC; 5920c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_STD_HOST_NC_8540: 5930c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8540: 5940c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_STD_HOST_C_S_8540: 5950c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_CDP_8540: 5960c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->mode == USB_IDLE) { 5970c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->mode = USB_PERIPHERAL; 5980c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab8500_usb_peri_phy_en(ab); 5990c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 6000c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 6010c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 6020c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (event != UX500_MUSB_RIDC) 6030c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_VBUS; 6040c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri break; 6050c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 6060c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_ACA_RID_A_8540: 6070c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_ACA_DOCK_CHGR_8540: 6080c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_RIDA; 6090c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_HM_IDGND_8540: 6100c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_STD_UPSTREAM_8540: 6110c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->mode == USB_IDLE) { 6120c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->mode = USB_HOST; 6130c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab8500_usb_host_phy_en(ab); 6140c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 6150c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 6160c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 6170c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->phy.otg->default_a = true; 6180c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (event != UX500_MUSB_RIDA) 6190c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_ID; 6200c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 6210c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event, &ab->vbus_draw); 6220c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri break; 6230c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 6240c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_DEDICATED_CHG_8540: 6250c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 6260c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_CHARGER; 6270c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 6280c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event, &ab->vbus_draw); 6290c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri break; 6300c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 6310c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8540: 6320c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri case USB_LINK_STD_UPSTREAM_NO_IDGNG_VBUS_8540: 6330c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_NONE; 6340c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->mode == USB_HOST) { 6350c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->phy.otg->default_a = false; 6360c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->vbus_draw = 0; 6370c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 6380c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event, &ab->vbus_draw); 6390c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab8500_usb_host_phy_dis(ab); 6400c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->mode = USB_IDLE; 6410c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 6420c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->mode == USB_PERIPHERAL) { 6430c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 6440c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event, &ab->vbus_draw); 6450c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab8500_usb_peri_phy_dis(ab); 6460c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 6470c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri UX500_MUSB_CLEAN, &ab->vbus_draw); 6480c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->mode = USB_IDLE; 6490c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->phy.otg->default_a = false; 6500c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->vbus_draw = 0; 6510c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 6520c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri break; 6530c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 6540c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri default: 6550c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri event = UX500_MUSB_NONE; 6560c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri break; 6570c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 6580c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 6590c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri return 0; 6600c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri} 6610c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 662af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8505_usb_link_status_update(struct ab8500_usb *ab, 663af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts) 664969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 665af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 666969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 667af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts); 668969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 669af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 670af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen at the time of 671af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in RIDA state 672af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 673af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 && 674af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_NC_8505)) 675af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 676af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 677af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 678969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 679969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab switch (lsts) { 680af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8505: 681af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 682af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8505: 683af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED0_8505: 684af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED1_8505: 685af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED2_8505: 686af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED3_8505: 687af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 688144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = false; 689969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = 0; 690af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 691af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 692af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 693af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Fallback to default B_IDLE as nothing 694af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * is connected 695af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 696af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 697969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 698969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 699af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8505: 700af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 701af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8505: 702af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8505: 703af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8505: 704af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_CDP_8505: 705af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 706af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 707969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_en(ab); 708af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 709af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 710969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 711af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 712af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 713969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 714969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 715af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8505: 716af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_DOCK_CHGR_8505: 717af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 718af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8505: 719af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 720af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 721969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_en(ab); 722af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 723af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 724969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 725144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg->default_a = true; 726af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 727af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 728af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 729af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 730969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 731969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 732af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8505: 733af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 734af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 735af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 736af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 737af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 738af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 739af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri default: 740969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab break; 741969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 742969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 743af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 744af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 745af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 746af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_link_status_update(struct ab8500_usb *ab, 747af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts) 748af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 749af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ux500_musb_vbus_id_status event = 0; 750af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 751af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts); 752af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 753af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* 754af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Spurious link_status interrupts are seen in case of a 755af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * disconnection of a device in IDGND and RIDA stage 756af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 757af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 && 758af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri (lsts == USB_LINK_STD_HOST_C_NS_8500 || 759af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500)) 760af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 761af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 762af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 && 763af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500) 764af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return 0; 765af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 766af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->previous_link_status_state = lsts; 767af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 768af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri switch (lsts) { 769af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_B_8500: 770af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDB; 771af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_CONFIGURED_8500: 772af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_NOT_VALID_LINK_8500: 773af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 774af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 775af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 776af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDB) 777af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_NONE; 778af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Fallback to default B_IDLE as nothing is connected */ 779af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.state = OTG_STATE_B_IDLE; 780af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 781af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 782af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_NM_8500: 783af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_8500: 784af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_C_HS_CHIRP_8500: 785af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDC; 786af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_NC_8500: 787af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_NS_8500: 788af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_STD_HOST_C_S_8500: 789af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_NM_8500: 790af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_8500: 791af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HOST_CHG_HS_CHIRP_8500: 792af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 793af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_PERIPHERAL; 794af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_en(ab); 795af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 796af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 797af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 798af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDC) 799af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_VBUS; 800af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 801af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 802af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_ACA_RID_A_8500: 803af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_RIDA; 804af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_HM_IDGND_8500: 805af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_IDLE) { 806af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_HOST; 807af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_en(ab); 808af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 809af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw); 810af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 811af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = true; 812af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (event != UX500_MUSB_RIDA) 813af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_ID; 814af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 815af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 816af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 817af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 818af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_DEDICATED_CHG_8500: 819af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_DEDICATED_CHG; 820af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event = UX500_MUSB_CHARGER; 821af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 822af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 823af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 824af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 825af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri case USB_LINK_RESERVED_8500: 826af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri break; 827af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 828969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 829969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 830969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 831969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 832af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 833af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Connection Sequence: 834af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Link Status Interrupt 835af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Enable AB clock 836af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Enable AB regulators 837af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Enable USB phy 838af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Reset the musb controller 839af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Switch the ULPI GPIO pins to fucntion mode 840af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 7. Enable the musb Peripheral5 clock 841af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 8. Restore MUSB context 842af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 843af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int abx500_usb_link_status_update(struct ab8500_usb *ab) 844969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 845af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri u8 reg; 846af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int ret = 0; 847af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 848af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500(ab->ab8500)) { 849af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8500_usb_link_status lsts; 850af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 851af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 852af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_LINE_STAT_REG, ®); 853af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x0F; 854af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8500_usb_link_status_update(ab, lsts); 855af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } else if (is_ab8505(ab->ab8500)) { 856af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum ab8505_usb_link_status lsts; 857af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 858af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_get_register_interruptible(ab->dev, 859af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8505_USB_LINE_STAT_REG, ®); 860af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri lsts = (reg >> 3) & 0x1F; 861af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ret = ab8505_usb_link_status_update(ab, lsts); 8620c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } else if (is_ab8540(ab->ab8500)) { 8630c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri enum ab8540_usb_link_status lsts; 8640c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 8650c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_get_register_interruptible(ab->dev, 8660c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB, AB8540_USB_LINK_STAT_REG, ®); 8670c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri lsts = (reg >> 3) & 0xFF; 8680c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ret = ab8540_usb_link_status_update(ab, lsts); 869f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } else if (is_ab9540(ab->ab8500)) { 870f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri enum ab9540_usb_link_status lsts; 871f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 872f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri abx500_get_register_interruptible(ab->dev, 873f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_USB, AB9540_USB_LINK_STAT_REG, ®); 874f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri lsts = (reg >> 3) & 0xFF; 875f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ret = ab9540_usb_link_status_update(ab, lsts); 876af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 877af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 878af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return ret; 879af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri} 880af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 881af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri/* 882af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * Disconnection Sequence: 883af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 1. Disconect Interrupt 884af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 2. Disable regulators 885af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 3. Disable AB clock 886af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 4. Disable the Phy 887af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 5. Link Status Interrupt 888af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri * 6. Disable Musb Clock 889af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri */ 890af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data) 891af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri{ 892af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *) data; 893af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri enum usb_phy_events event = UX500_MUSB_NONE; 894af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 895af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Link status will not be updated till phy is disabled. */ 896af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_HOST) { 897af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 898af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 899af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 900af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 901af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_host_phy_dis(ab); 902af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 903af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 904af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 905af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_PERIPHERAL) { 906af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 907af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri event, &ab->vbus_draw); 908af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_peri_phy_dis(ab); 909af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 910af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri UX500_MUSB_CLEAN, &ab->vbus_draw); 911af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->mode = USB_IDLE; 912af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->phy.otg->default_a = false; 913af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab->vbus_draw = 0; 914af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 915af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 916af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (is_ab8500_2p0(ab->ab8500)) { 917af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri if (ab->mode == USB_DEDICATED_CHG) { 918af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_wd_linkstatus(ab, 919af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN); 920af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 921af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG, 922af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN, 0); 923af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 924af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 925969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 926af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri return IRQ_HANDLED; 927969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 928969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 929af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic irqreturn_t ab8500_usb_link_status_irq(int irq, void *data) 930969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 9313147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *)data; 932969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 933af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri abx500_usb_link_status_update(ab); 934969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 935969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return IRQ_HANDLED; 936969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 937969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 938969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void ab8500_usb_phy_disable_work(struct work_struct *work) 939969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 940969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = container_of(work, struct ab8500_usb, 941969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab phy_dis_work); 942969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 943144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->host) 944969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 945969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 946144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!ab->phy.otg->gadget) 947969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 948969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 949969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 9500c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri/* Check if VBUS is set and linkstatus has not detected a cable. */ 9510c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieristatic bool ab8500_usb_check_vbus_status(struct ab8500_usb *ab) 9520c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri{ 9530c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri u8 isource2; 9540c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri u8 reg; 9550c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri enum ab8540_usb_link_status lsts; 9560c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9570c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_get_register_interruptible(ab->dev, 9580c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_INTERRUPT, AB8500_IT_SOURCE2_REG, 9590c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri &isource2); 9600c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9610c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* If Vbus is below 3.6V abort */ 9620c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (!(isource2 & AB8500_BIT_SOURCE2_VBUSDET)) 9630c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri return false; 9640c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9650c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_get_register_interruptible(ab->dev, 9660c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB, AB8540_USB_LINK_STAT_REG, 9670c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ®); 9680c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9690c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri lsts = (reg >> 3) & 0xFF; 9700c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9710c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* Check if linkstatus has detected a cable */ 9720c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (lsts) 9730c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri return false; 9740c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9750c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri return true; 9760c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri} 9770c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9780c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri/* re-trigger charger detection again with watchdog re-kick. */ 9790c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieristatic void ab8500_usb_vbus_turn_on_event_work(struct work_struct *work) 9800c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri{ 9810c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri struct ab8500_usb *ab = container_of(work, struct ab8500_usb, 9820c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri vbus_event_work); 9830c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9840c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->mode != USB_IDLE) 9850c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri return; 9860c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9870c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_set_register_interruptible(ab->dev, 9880c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_SYS_CTRL2_BLOCK, AB8500_MAIN_WD_CTRL_REG, 9890c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_BIT_WD_CTRL_ENABLE); 9900c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9910c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri udelay(100); 9920c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9930c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_set_register_interruptible(ab->dev, 9940c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_SYS_CTRL2_BLOCK, AB8500_MAIN_WD_CTRL_REG, 9950c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_BIT_WD_CTRL_ENABLE | AB8500_BIT_WD_CTRL_KICK); 9960c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9970c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri udelay(100); 9980c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 9990c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* Disable Main watchdog */ 10000c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_set_register_interruptible(ab->dev, 10010c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_SYS_CTRL2_BLOCK, AB8500_MAIN_WD_CTRL_REG, 10020c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 0x0); 10030c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 10040c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* Enable USB Charger detection */ 10050c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev, 10060c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB, AB8540_VBUS_CTRL_REG, 10070c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_BIT_VBUS_CTRL_CHARG_DET_ENA, 10080c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_BIT_VBUS_CTRL_CHARG_DET_ENA); 10090c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 10100c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->enabled_charging_detection = true; 10110c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri} 10120c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 1013c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisettistatic unsigned ab8500_eyediagram_workaroud(struct ab8500_usb *ab, unsigned mA) 1014c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti{ 1015c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti /* 1016c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * AB8500 V2 has eye diagram issues when drawing more than 100mA from 1017c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti * VBUS. Set charging current to 100mA in case of standard host 1018c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti */ 1019c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (is_ab8500_2p0_or_earlier(ab->ab8500)) 1020c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti if (mA > 100) 1021c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = 100; 1022c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 1023c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti return mA; 1024c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti} 1025c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 1026144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA) 1027969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1028969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 1029969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1030144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus if (!phy) 1031969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 1032969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1033144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(phy); 1034969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1035c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti mA = ab8500_eyediagram_workaroud(ab, mA); 1036c2a0ab6bd5ccf031f87bc678152fb70befea5786Sakethram Bommisetti 1037969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->vbus_draw = mA; 1038969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 103977f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier, 104077f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri UX500_MUSB_VBUS, &ab->vbus_draw); 104177f4396ecb3396e518da60f915bbd4726732fd70Fabio Baltieri 1042969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 1043969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1044969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 10458675381109b0eb1c948a423c2b35e3f4509cb25eHeikki Krogerusstatic int ab8500_usb_set_suspend(struct usb_phy *x, int suspend) 1046969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1047969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* TODO */ 1048969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 1049969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1050969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1051144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_peripheral(struct usb_otg *otg, 1052144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_gadget *gadget) 1053969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1054969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 1055969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1056969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 1057969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 1058969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1059144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 1060969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1061588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->phy.otg->gadget = gadget; 1062588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti 1063969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 1064969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 1065969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 1066969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 1067969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 10683147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri if ((ab->mode != USB_IDLE) && !gadget) { 1069588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->mode = USB_IDLE; 1070969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 1071969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 1072969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1073969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 1074969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1075969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1076144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerusstatic int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host) 1077969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1078969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 1079969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1080969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!otg) 1081969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 1082969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1083144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab = phy_to_ab(otg->phy); 1084969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1085588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->phy.otg->host = host; 1086588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti 1087969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* Some drivers call this function in atomic context. 1088969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * Do not update ab8500 registers directly till this 1089969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab * is fixed. 1090969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab */ 1091969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 10923147dad6fa457e0bb7edaab36f6d290c7048b49eFabio Baltieri if ((ab->mode != USB_IDLE) && !host) { 1093588233733804aeaf16335a32904aaa4d15b9bdddSakethram Bommisetti ab->mode = USB_IDLE; 1094969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab schedule_work(&ab->phy_dis_work); 1095969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 1096969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1097969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 1098969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1099969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1100fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisettistatic void ab8500_usb_restart_phy(struct ab8500_usb *ab) 1101fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti{ 1102fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev, 1103fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG, 1104fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_BIT_PHY_CTRL_DEVICE_EN, 1105fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_BIT_PHY_CTRL_DEVICE_EN); 1106fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 1107fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti udelay(100); 1108fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 1109fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev, 1110fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG, 1111fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_BIT_PHY_CTRL_DEVICE_EN, 1112fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 0); 1113fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 1114fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev, 1115fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG, 1116fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_BIT_PHY_CTRL_HOST_EN, 1117fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_BIT_PHY_CTRL_HOST_EN); 1118fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 1119fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti udelay(100); 1120fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 1121fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev, 1122fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG, 1123fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti AB8500_BIT_PHY_CTRL_HOST_EN, 1124fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 0); 1125fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti} 1126fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 1127e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieristatic int ab8500_usb_regulator_get(struct ab8500_usb *ab) 1128e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri{ 1129e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri int err; 1130e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 1131e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ape = devm_regulator_get(ab->dev, "v-ape"); 1132e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ape)) { 1133e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get v-ape supply\n"); 1134e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ape); 1135e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 1136e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 1137e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 1138e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_ulpi = devm_regulator_get(ab->dev, "vddulpivio18"); 1139e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_ulpi)) { 1140e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get vddulpivio18 supply\n"); 1141e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_ulpi); 1142e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 1143e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 1144e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 1145e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri ab->v_musb = devm_regulator_get(ab->dev, "musb_1v8"); 1146e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (IS_ERR(ab->v_musb)) { 1147e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri dev_err(ab->dev, "Could not get musb_1v8 supply\n"); 1148e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = PTR_ERR(ab->v_musb); 1149e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 1150e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri } 1151e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 1152e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return 0; 1153e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri} 1154e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 1155af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieristatic int ab8500_usb_irq_setup(struct platform_device *pdev, 1156af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri struct ab8500_usb *ab) 1157969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1158969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 1159af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri int irq; 1160969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1161bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_LINK_STATUS_IRQ) { 1162bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS"); 1163bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (irq < 0) { 1164bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri dev_err(&pdev->dev, "Link status irq not found\n"); 1165bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri return irq; 1166bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } 1167bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 1168bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri ab8500_usb_link_status_irq, 1169bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, 1170bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri "usb-link-status", ab); 1171bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (err < 0) { 1172bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri dev_err(ab->dev, "request_irq failed for link status irq\n"); 1173bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri return err; 1174bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } 1175969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 1176969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1177bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ) { 1178bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); 1179bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (irq < 0) { 1180bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri dev_err(&pdev->dev, "ID fall irq not found\n"); 1181bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri return irq; 1182bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } 1183bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 1184bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri ab8500_usb_disconnect_irq, 1185bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, 1186bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri "usb-id-fall", ab); 1187bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (err < 0) { 1188bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri dev_err(ab->dev, "request_irq failed for ID fall irq\n"); 1189bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri return err; 1190bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } 1191af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri } 1192af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 1193bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_VBUS_DET_IRQ) { 1194bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri irq = platform_get_irq_byname(pdev, "VBUS_DET_F"); 1195bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (irq < 0) { 1196bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri dev_err(&pdev->dev, "VBUS fall irq not found\n"); 1197bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri return irq; 1198bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } 1199bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL, 1200bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri ab8500_usb_disconnect_irq, 1201bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri IRQF_NO_SUSPEND | IRQF_SHARED, 1202bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri "usb-vbus-fall", ab); 1203bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (err < 0) { 1204bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); 1205bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri return err; 1206bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } 1207969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 1208969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1209969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 1210969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1211969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 121216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieristatic void ab8500_usb_set_ab8500_tuning_values(struct ab8500_usb *ab) 121316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri{ 121416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri int err; 121516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 121616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri /* Enable the PBT/Bank 0x12 access */ 121716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 121816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01); 121916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 122016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", 122116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 122216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 122316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 122416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8); 122516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 122616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", 122716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 122816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 122916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 123016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00); 123116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 123216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", 123316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 123416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 123516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 123616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); 123716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 123816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", 123916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 124016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 124116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri /* Switch to normal mode/disable Bank 0x12 access */ 124216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 124316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x00); 124416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 124516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", 124616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 124716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri} 124816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 124916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieristatic void ab8500_usb_set_ab8505_tuning_values(struct ab8500_usb *ab) 125016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri{ 125116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri int err; 125216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 125316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri /* Enable the PBT/Bank 0x12 access */ 125416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev, 125516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 125616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 0x01, 0x01); 125716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 125816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", 125916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 126016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 126116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev, 126216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 126316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 0xC8, 0xC8); 126416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 126516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", 126616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 126716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 126816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev, 126916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 127016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 0x60, 0x60); 127116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 127216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", 127316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 127416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 127516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev, 127616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 127716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 0xFC, 0x80); 127816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 127916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 128016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", 128116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 128216604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 128316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri /* Switch to normal mode/disable Bank 0x12 access */ 128416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev, 128516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 128616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 0x00, 0x00); 128716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (err < 0) 128816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", 128916604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri err); 129016604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri} 129116604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri 12920c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieristatic void ab8500_usb_set_ab8540_tuning_values(struct ab8500_usb *ab) 12930c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri{ 12940c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri int err; 12950c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 12960c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri err = abx500_set_register_interruptible(ab->dev, 12970c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_DEBUG, AB8500_USB_PHY_TUNE1, 0xCC); 12980c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (err < 0) 12990c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE1 register ret=%d\n", 13000c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri err); 13010c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 13020c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri err = abx500_set_register_interruptible(ab->dev, 13030c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_DEBUG, AB8500_USB_PHY_TUNE2, 0x60); 13040c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (err < 0) 13050c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE2 register ret=%d\n", 13060c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri err); 13070c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 13080c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri err = abx500_set_register_interruptible(ab->dev, 13090c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8540_DEBUG, AB8500_USB_PHY_TUNE3, 0x90); 13100c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (err < 0) 13110c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE3 regester ret=%d\n", 13120c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri err); 13130c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri} 13140c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 1315f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieristatic void ab8500_usb_set_ab9540_tuning_values(struct ab8500_usb *ab) 1316f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri{ 1317f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri int err; 1318f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 1319f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri /* Enable the PBT/Bank 0x12 access */ 1320f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 1321f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01); 1322f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (err < 0) 1323f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri dev_err(ab->dev, "Failed to enable bank12 access err=%d\n", 1324f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err); 1325f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 1326f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 1327f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8); 1328f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (err < 0) 1329f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n", 1330f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err); 1331f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 1332f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 1333f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x60); 1334f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (err < 0) 1335f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n", 1336f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err); 1337f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 1338f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 1339f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x80); 1340f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (err < 0) 1341f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", 1342f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err); 1343f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 1344f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri /* Switch to normal mode/disable Bank 0x12 access */ 1345f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err = abx500_set_register_interruptible(ab->dev, 1346f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x00); 1347f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (err < 0) 1348f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri dev_err(ab->dev, "Failed to switch bank12 access err=%d\n", 1349f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri err); 1350f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri} 1351f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri 135241ac7b3ab7fe1d6175839947a877fdf95cbd2211Bill Pembertonstatic int ab8500_usb_probe(struct platform_device *pdev) 1353969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1354969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab; 135573f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri struct ab8500 *ab8500; 1356144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus struct usb_otg *otg; 1357969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int err; 1358969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab int rev; 1359969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 136073f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab8500 = dev_get_drvdata(pdev->dev.parent); 1361969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab rev = abx500_get_chip_id(&pdev->dev); 136273f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri 136373f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri if (is_ab8500_1p1_or_earlier(ab8500)) { 136473f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev); 1365969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENODEV; 1366969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 1367969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 136881ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri ab = devm_kzalloc(&pdev->dev, sizeof(*ab), GFP_KERNEL); 1369969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (!ab) 1370969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return -ENOMEM; 1371969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 137281ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); 137381ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri if (!otg) 1374144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus return -ENOMEM; 1375144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 1376969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab ab->dev = &pdev->dev; 137773f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri ab->ab8500 = ab8500; 1378144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.dev = ab->dev; 1379144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.otg = otg; 1380144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.label = "ab8500"; 1381144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_suspend = ab8500_usb_set_suspend; 1382144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.set_power = ab8500_usb_set_power; 1383144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus ab->phy.state = OTG_STATE_UNDEFINED; 1384144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus 1385144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->phy = &ab->phy; 1386144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_host = ab8500_usb_set_host; 1387144713f34727801d55d8858e0f549118b9f691c4Heikki Krogerus otg->set_peripheral = ab8500_usb_set_peripheral; 1388969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1389bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (is_ab8500(ab->ab8500)) { 1390bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | 1391bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ | 1392bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri AB8500_USB_FLAG_USE_VBUS_DET_IRQ | 1393bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; 1394bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } else if (is_ab8505(ab->ab8500)) { 1395bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | 1396bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ | 1397bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri AB8500_USB_FLAG_USE_VBUS_DET_IRQ | 1398bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; 13990c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } else if (is_ab8540(ab->ab8500)) { 14000c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | 14010c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB_FLAG_USE_CHECK_VBUS_STATUS | 14020c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB_FLAG_USE_VBUS_HOST_QUIRK | 14030c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; 1404f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri } else if (is_ab9540(ab->ab8500)) { 1405f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ | 1406f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; 1407f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri if (is_ab9540_2p0_or_earlier(ab->ab8500)) 1408f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab->flags |= AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ | 1409f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri AB8500_USB_FLAG_USE_VBUS_DET_IRQ; 1410bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri } 1411bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri 1412bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri /* Disable regulator voltage setting for AB8500 <= v2.0 */ 1413bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri if (is_ab8500_2p0_or_earlier(ab->ab8500)) 1414bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri ab->flags &= ~AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE; 1415bd4c9f0278338585024db55f2ff74d6e0a6a1f6bFabio Baltieri 1416969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_set_drvdata(pdev, ab); 1417969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1418969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab /* all: Disable phy when called from set_host and set_peripheral */ 1419969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); 1420969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 14210c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri INIT_WORK(&ab->vbus_event_work, ab8500_usb_vbus_turn_on_event_work); 14220c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 1423e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri err = ab8500_usb_regulator_get(ab); 1424e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri if (err) 1425e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri return err; 1426e65b36c02613764aa703ef0be0a3c2c57ea91625Fabio Baltieri 1427d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab ab->sysclk = devm_clk_get(ab->dev, "sysclk"); 1428d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab if (IS_ERR(ab->sysclk)) { 1429d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab dev_err(ab->dev, "Could not get sysclk.\n"); 1430d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab return PTR_ERR(ab->sysclk); 1431d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab } 1432d0ed0645a5cfb0cccca6baa84b459eb2078e7fb1Mian Yousaf Kaukab 1433af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri err = ab8500_usb_irq_setup(pdev, ab); 1434969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err < 0) 143581ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri return err; 1436969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1437662dca54ca67c92b7aa14b9a2ec54acacf33ce45Kishon Vijay Abraham I err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); 1438969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab if (err) { 1439969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab dev_err(&pdev->dev, "Can't register transceiver\n"); 144081ef6724302e0c7ba3f087403de24760601b1839Fabio Baltieri return err; 1441969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab } 1442969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 144316604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri if (is_ab8500(ab->ab8500) && !is_ab8500_2p0_or_earlier(ab->ab8500)) 144416604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri /* Phy tuning values for AB8500 > v2.0 */ 144516604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri ab8500_usb_set_ab8500_tuning_values(ab); 144616604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri else if (is_ab8505(ab->ab8500)) 144716604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri /* Phy tuning values for AB8505 */ 144816604a3c27f4a43588069ae9a77a9961a485d53fFabio Baltieri ab8500_usb_set_ab8505_tuning_values(ab); 14490c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri else if (is_ab8540(ab->ab8500)) 14500c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri /* Phy tuning values for AB8540 */ 14510c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri ab8500_usb_set_ab8540_tuning_values(ab); 1452f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri else if (is_ab9540(ab->ab8500)) 1453f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri /* Phy tuning values for AB9540 */ 1454f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri ab8500_usb_set_ab9540_tuning_values(ab); 14557124631aa892712fc8b317ff34d25c14dee6f63dSakethram Bommisetti 1456af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri /* Needed to enable ID detection. */ 1457af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri ab8500_usb_wd_workaround(ab); 1458af6882be363d3a7bf0f72dd17ac2a639c4da0059Fabio Baltieri 1459fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti /* 1460fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti * This is required for usb-link-status to work properly when a 1461fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti * cable is connected at boot time. 1462fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti */ 1463fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti ab8500_usb_restart_phy(ab); 1464fb21f37a5249374ed63f763455a0b07b80c1e50cSakethram Bommisetti 14650c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_CHECK_VBUS_STATUS) { 14660c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri if (ab8500_usb_check_vbus_status(ab)) 14670c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri schedule_work(&ab->vbus_event_work); 14680c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri } 14690c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri 14708db12231bccc5ebf414b267af68c5a8c1e4432ddSakethram Bommisetti abx500_usb_link_status_update(ab); 14718db12231bccc5ebf414b267af68c5a8c1e4432ddSakethram Bommisetti 147273f226cbd79adb5f3f25ee14c18900bb4a9acd15Fabio Baltieri dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev); 1473969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1474969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 1475969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1476969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1477fb4e98ab63433c4d3a1588ea91c73f1cd7ebaa00Bill Pembertonstatic int ab8500_usb_remove(struct platform_device *pdev) 1478969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1479969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab struct ab8500_usb *ab = platform_get_drvdata(pdev); 1480969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1481969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab cancel_work_sync(&ab->phy_dis_work); 14820c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri cancel_work_sync(&ab->vbus_event_work); 1483969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1484662dca54ca67c92b7aa14b9a2ec54acacf33ce45Kishon Vijay Abraham I usb_remove_phy(&ab->phy); 1485969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1486f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab if (ab->mode == USB_HOST) 1487f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab ab8500_usb_host_phy_dis(ab); 1488f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab else if (ab->mode == USB_PERIPHERAL) 1489f5ef7b42823945d979ebd957e79bf66dc6a5e3d1Mian Yousaf Kaukab ab8500_usb_peri_phy_dis(ab); 1490969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1491969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return 0; 1492969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1493969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1494b3affc399183eb0c548626daa9daad3d0e100906Fabio Baltieristatic struct platform_device_id ab8500_usb_devtype[] = { 1495b3affc399183eb0c548626daa9daad3d0e100906Fabio Baltieri { .name = "ab8500-usb", }, 14960c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio Baltieri { .name = "ab8540-usb", }, 1497f85bff5d1ece92017a57129877573e0fa4b1050cFabio Baltieri { .name = "ab9540-usb", }, 1498b3affc399183eb0c548626daa9daad3d0e100906Fabio Baltieri { /* sentinel */ } 1499b3affc399183eb0c548626daa9daad3d0e100906Fabio Baltieri}; 1500b3affc399183eb0c548626daa9daad3d0e100906Fabio BaltieriMODULE_DEVICE_TABLE(platform, ab8500_usb_devtype); 1501b3affc399183eb0c548626daa9daad3d0e100906Fabio Baltieri 1502969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic struct platform_driver ab8500_usb_driver = { 1503969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .probe = ab8500_usb_probe, 15047690417db5085f0de03aa70b8ca01b0118e8a1b4Bill Pemberton .remove = ab8500_usb_remove, 1505b3affc399183eb0c548626daa9daad3d0e100906Fabio Baltieri .id_table = ab8500_usb_devtype, 1506969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .driver = { 1507b3affc399183eb0c548626daa9daad3d0e100906Fabio Baltieri .name = "abx5x0-usb", 1508969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab .owner = THIS_MODULE, 1509969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab }, 1510969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab}; 1511969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1512969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic int __init ab8500_usb_init(void) 1513969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1514969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab return platform_driver_register(&ab8500_usb_driver); 1515969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1516969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabsubsys_initcall(ab8500_usb_init); 1517969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1518969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabstatic void __exit ab8500_usb_exit(void) 1519969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab{ 1520969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab platform_driver_unregister(&ab8500_usb_driver); 1521969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab} 1522969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukabmodule_exit(ab8500_usb_exit); 1523969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf Kaukab 1524969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_AUTHOR("ST-Ericsson AB"); 15250c380c0ee03c4465f45f19c1c3fc49edd299c922Fabio BaltieriMODULE_DESCRIPTION("AB8500 family usb transceiver driver"); 1526969152341e852ae7a5e1b11c33ef6244f3cb3579Mian Yousaf KaukabMODULE_LICENSE("GPL"); 1527