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, &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, &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, &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, &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			&reg);
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