15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+
294ae9843SFelipe Balbi /*
30c380c0eSFabio Baltieri * USB transceiver driver for AB8500 family chips
494ae9843SFelipe Balbi *
50c380c0eSFabio Baltieri * Copyright (C) 2010-2013 ST-Ericsson AB
694ae9843SFelipe Balbi * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
70c380c0eSFabio Baltieri * Avinash Kumar <avinash.kumar@stericsson.com>
8f85bff5dSFabio Baltieri * Thirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.com>
994ae9843SFelipe Balbi */
1094ae9843SFelipe Balbi
1194ae9843SFelipe Balbi #include <linux/module.h>
1294ae9843SFelipe Balbi #include <linux/platform_device.h>
1394ae9843SFelipe Balbi #include <linux/usb/otg.h>
1494ae9843SFelipe Balbi #include <linux/slab.h>
1594ae9843SFelipe Balbi #include <linux/notifier.h>
1694ae9843SFelipe Balbi #include <linux/interrupt.h>
1794ae9843SFelipe Balbi #include <linux/delay.h>
18d0ed0645SMian Yousaf Kaukab #include <linux/clk.h>
19d0ed0645SMian Yousaf Kaukab #include <linux/err.h>
2094ae9843SFelipe Balbi #include <linux/mfd/abx500.h>
2194ae9843SFelipe Balbi #include <linux/mfd/abx500/ab8500.h>
22af6882beSFabio Baltieri #include <linux/usb/musb-ux500.h>
23e65b36c0SFabio Baltieri #include <linux/regulator/consumer.h>
24899f0f56SPatrice Chotard #include <linux/pinctrl/consumer.h>
2594ae9843SFelipe Balbi
267124631aSSakethram Bommisetti /* Bank AB8500_SYS_CTRL2_BLOCK */
2794ae9843SFelipe Balbi #define AB8500_MAIN_WD_CTRL_REG 0x01
287124631aSSakethram Bommisetti
297124631aSSakethram Bommisetti /* Bank AB8500_USB */
3094ae9843SFelipe Balbi #define AB8500_USB_LINE_STAT_REG 0x80
31af6882beSFabio Baltieri #define AB8505_USB_LINE_STAT_REG 0x94
3294ae9843SFelipe Balbi #define AB8500_USB_PHY_CTRL_REG 0x8A
3394ae9843SFelipe Balbi
347124631aSSakethram Bommisetti /* Bank AB8500_DEVELOPMENT */
357124631aSSakethram Bommisetti #define AB8500_BANK12_ACCESS 0x00
367124631aSSakethram Bommisetti
377124631aSSakethram Bommisetti /* Bank AB8500_DEBUG */
387124631aSSakethram Bommisetti #define AB8500_USB_PHY_TUNE1 0x05
397124631aSSakethram Bommisetti #define AB8500_USB_PHY_TUNE2 0x06
407124631aSSakethram Bommisetti #define AB8500_USB_PHY_TUNE3 0x07
417124631aSSakethram Bommisetti
420c380c0eSFabio Baltieri /* Bank AB8500_INTERRUPT */
430c380c0eSFabio Baltieri #define AB8500_IT_SOURCE2_REG 0x01
440c380c0eSFabio Baltieri
4594ae9843SFelipe Balbi #define AB8500_BIT_OTG_STAT_ID (1 << 0)
4694ae9843SFelipe Balbi #define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0)
4794ae9843SFelipe Balbi #define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1)
4894ae9843SFelipe Balbi #define AB8500_BIT_WD_CTRL_ENABLE (1 << 0)
4994ae9843SFelipe Balbi #define AB8500_BIT_WD_CTRL_KICK (1 << 1)
500c380c0eSFabio Baltieri #define AB8500_BIT_SOURCE2_VBUSDET (1 << 7)
5194ae9843SFelipe Balbi
5294ae9843SFelipe Balbi #define AB8500_WD_KICK_DELAY_US 100 /* usec */
5394ae9843SFelipe Balbi #define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */
54af6882beSFabio Baltieri #define AB8500_V20_31952_DISABLE_DELAY_US 100 /* usec */
5594ae9843SFelipe Balbi
5694ae9843SFelipe Balbi /* Usb line status register */
5794ae9843SFelipe Balbi enum ab8500_usb_link_status {
58af6882beSFabio Baltieri USB_LINK_NOT_CONFIGURED_8500 = 0,
59af6882beSFabio Baltieri USB_LINK_STD_HOST_NC_8500,
60af6882beSFabio Baltieri USB_LINK_STD_HOST_C_NS_8500,
61af6882beSFabio Baltieri USB_LINK_STD_HOST_C_S_8500,
62af6882beSFabio Baltieri USB_LINK_HOST_CHG_NM_8500,
63af6882beSFabio Baltieri USB_LINK_HOST_CHG_HS_8500,
64af6882beSFabio Baltieri USB_LINK_HOST_CHG_HS_CHIRP_8500,
65af6882beSFabio Baltieri USB_LINK_DEDICATED_CHG_8500,
66af6882beSFabio Baltieri USB_LINK_ACA_RID_A_8500,
67af6882beSFabio Baltieri USB_LINK_ACA_RID_B_8500,
68af6882beSFabio Baltieri USB_LINK_ACA_RID_C_NM_8500,
69af6882beSFabio Baltieri USB_LINK_ACA_RID_C_HS_8500,
70af6882beSFabio Baltieri USB_LINK_ACA_RID_C_HS_CHIRP_8500,
71af6882beSFabio Baltieri USB_LINK_HM_IDGND_8500,
72af6882beSFabio Baltieri USB_LINK_RESERVED_8500,
73af6882beSFabio Baltieri USB_LINK_NOT_VALID_LINK_8500,
74af6882beSFabio Baltieri };
75af6882beSFabio Baltieri
76af6882beSFabio Baltieri enum ab8505_usb_link_status {
77af6882beSFabio Baltieri USB_LINK_NOT_CONFIGURED_8505 = 0,
78af6882beSFabio Baltieri USB_LINK_STD_HOST_NC_8505,
79af6882beSFabio Baltieri USB_LINK_STD_HOST_C_NS_8505,
80af6882beSFabio Baltieri USB_LINK_STD_HOST_C_S_8505,
81af6882beSFabio Baltieri USB_LINK_CDP_8505,
82af6882beSFabio Baltieri USB_LINK_RESERVED0_8505,
83af6882beSFabio Baltieri USB_LINK_RESERVED1_8505,
84af6882beSFabio Baltieri USB_LINK_DEDICATED_CHG_8505,
85af6882beSFabio Baltieri USB_LINK_ACA_RID_A_8505,
86af6882beSFabio Baltieri USB_LINK_ACA_RID_B_8505,
87af6882beSFabio Baltieri USB_LINK_ACA_RID_C_NM_8505,
88af6882beSFabio Baltieri USB_LINK_RESERVED2_8505,
89af6882beSFabio Baltieri USB_LINK_RESERVED3_8505,
90af6882beSFabio Baltieri USB_LINK_HM_IDGND_8505,
91af6882beSFabio Baltieri USB_LINK_CHARGERPORT_NOT_OK_8505,
92af6882beSFabio Baltieri USB_LINK_CHARGER_DM_HIGH_8505,
93af6882beSFabio Baltieri USB_LINK_PHYEN_NO_VBUS_NO_IDGND_8505,
94af6882beSFabio Baltieri USB_LINK_STD_UPSTREAM_NO_IDGNG_NO_VBUS_8505,
95af6882beSFabio Baltieri USB_LINK_STD_UPSTREAM_8505,
96af6882beSFabio Baltieri USB_LINK_CHARGER_SE1_8505,
97af6882beSFabio Baltieri USB_LINK_CARKIT_CHGR_1_8505,
98af6882beSFabio Baltieri USB_LINK_CARKIT_CHGR_2_8505,
99af6882beSFabio Baltieri USB_LINK_ACA_DOCK_CHGR_8505,
100af6882beSFabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_EN_8505,
101af6882beSFabio Baltieri USB_LINK_SAMSUNG_BOOT_CBL_PHY_DISB_8505,
102af6882beSFabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505,
103af6882beSFabio Baltieri USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505,
104af6882beSFabio Baltieri USB_LINK_MOTOROLA_FACTORY_CBL_PHY_EN_8505,
105af6882beSFabio Baltieri };
106af6882beSFabio Baltieri
107af6882beSFabio Baltieri enum ab8500_usb_mode {
108af6882beSFabio Baltieri USB_IDLE = 0,
109af6882beSFabio Baltieri USB_PERIPHERAL,
110af6882beSFabio Baltieri USB_HOST,
111c4a68b4dSStephan Gerhold USB_DEDICATED_CHG,
112c4a68b4dSStephan Gerhold USB_UART
11394ae9843SFelipe Balbi };
11494ae9843SFelipe Balbi
115bd4c9f02SFabio Baltieri /* Register USB_LINK_STATUS interrupt */
116bd4c9f02SFabio Baltieri #define AB8500_USB_FLAG_USE_LINK_STATUS_IRQ (1 << 0)
117bd4c9f02SFabio Baltieri /* Register ID_WAKEUP_F interrupt */
118bd4c9f02SFabio Baltieri #define AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ (1 << 1)
119bd4c9f02SFabio Baltieri /* Register VBUS_DET_F interrupt */
120bd4c9f02SFabio Baltieri #define AB8500_USB_FLAG_USE_VBUS_DET_IRQ (1 << 2)
121bd4c9f02SFabio Baltieri /* Driver is using the ab-iddet driver*/
122bd4c9f02SFabio Baltieri #define AB8500_USB_FLAG_USE_AB_IDDET (1 << 3)
123bd4c9f02SFabio Baltieri /* Enable setting regulators voltage */
124bd4c9f02SFabio Baltieri #define AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE (1 << 4)
125bd4c9f02SFabio Baltieri
12694ae9843SFelipe Balbi struct ab8500_usb {
12794ae9843SFelipe Balbi struct usb_phy phy;
12894ae9843SFelipe Balbi struct device *dev;
12973f226cbSFabio Baltieri struct ab8500 *ab8500;
13094ae9843SFelipe Balbi unsigned vbus_draw;
13194ae9843SFelipe Balbi struct work_struct phy_dis_work;
132af6882beSFabio Baltieri enum ab8500_usb_mode mode;
133d0ed0645SMian Yousaf Kaukab struct clk *sysclk;
134e65b36c0SFabio Baltieri struct regulator *v_ape;
135e65b36c0SFabio Baltieri struct regulator *v_musb;
136e65b36c0SFabio Baltieri struct regulator *v_ulpi;
13754dfbb08SFabio Baltieri int saved_v_ulpi;
138af6882beSFabio Baltieri int previous_link_status_state;
139899f0f56SPatrice Chotard struct pinctrl *pinctrl;
140899f0f56SPatrice Chotard struct pinctrl_state *pins_sleep;
1410c380c0eSFabio Baltieri bool enabled_charging_detection;
142bd4c9f02SFabio Baltieri unsigned int flags;
14394ae9843SFelipe Balbi };
14494ae9843SFelipe Balbi
phy_to_ab(struct usb_phy * x)14594ae9843SFelipe Balbi static inline struct ab8500_usb *phy_to_ab(struct usb_phy *x)
14694ae9843SFelipe Balbi {
14794ae9843SFelipe Balbi return container_of(x, struct ab8500_usb, phy);
14894ae9843SFelipe Balbi }
14994ae9843SFelipe Balbi
ab8500_usb_wd_workaround(struct ab8500_usb * ab)15094ae9843SFelipe Balbi static void ab8500_usb_wd_workaround(struct ab8500_usb *ab)
15194ae9843SFelipe Balbi {
15294ae9843SFelipe Balbi abx500_set_register_interruptible(ab->dev,
15394ae9843SFelipe Balbi AB8500_SYS_CTRL2_BLOCK,
15494ae9843SFelipe Balbi AB8500_MAIN_WD_CTRL_REG,
15594ae9843SFelipe Balbi AB8500_BIT_WD_CTRL_ENABLE);
15694ae9843SFelipe Balbi
15794ae9843SFelipe Balbi udelay(AB8500_WD_KICK_DELAY_US);
15894ae9843SFelipe Balbi
15994ae9843SFelipe Balbi abx500_set_register_interruptible(ab->dev,
16094ae9843SFelipe Balbi AB8500_SYS_CTRL2_BLOCK,
16194ae9843SFelipe Balbi AB8500_MAIN_WD_CTRL_REG,
16294ae9843SFelipe Balbi (AB8500_BIT_WD_CTRL_ENABLE
16394ae9843SFelipe Balbi | AB8500_BIT_WD_CTRL_KICK));
16494ae9843SFelipe Balbi
16594ae9843SFelipe Balbi udelay(AB8500_WD_V11_DISABLE_DELAY_US);
16694ae9843SFelipe Balbi
16794ae9843SFelipe Balbi abx500_set_register_interruptible(ab->dev,
16894ae9843SFelipe Balbi AB8500_SYS_CTRL2_BLOCK,
16994ae9843SFelipe Balbi AB8500_MAIN_WD_CTRL_REG,
17094ae9843SFelipe Balbi 0);
17194ae9843SFelipe Balbi }
17294ae9843SFelipe Balbi
ab8500_usb_regulator_enable(struct ab8500_usb * ab)17354dfbb08SFabio Baltieri static void ab8500_usb_regulator_enable(struct ab8500_usb *ab)
17454dfbb08SFabio Baltieri {
17554dfbb08SFabio Baltieri int ret, volt;
17654dfbb08SFabio Baltieri
17788b1c78dSFabio Baltieri ret = regulator_enable(ab->v_ape);
17888b1c78dSFabio Baltieri if (ret)
17988b1c78dSFabio Baltieri dev_err(ab->dev, "Failed to enable v-ape\n");
18054dfbb08SFabio Baltieri
181bd4c9f02SFabio Baltieri if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) {
18254dfbb08SFabio Baltieri ab->saved_v_ulpi = regulator_get_voltage(ab->v_ulpi);
18354dfbb08SFabio Baltieri if (ab->saved_v_ulpi < 0)
18454dfbb08SFabio Baltieri dev_err(ab->dev, "Failed to get v_ulpi voltage\n");
18554dfbb08SFabio Baltieri
18654dfbb08SFabio Baltieri ret = regulator_set_voltage(ab->v_ulpi, 1300000, 1350000);
18754dfbb08SFabio Baltieri if (ret < 0)
18854dfbb08SFabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n",
18954dfbb08SFabio Baltieri ret);
19054dfbb08SFabio Baltieri
1911d61a694SBjorn Andersson ret = regulator_set_load(ab->v_ulpi, 28000);
19254dfbb08SFabio Baltieri if (ret < 0)
19354dfbb08SFabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n",
19454dfbb08SFabio Baltieri ret);
19554dfbb08SFabio Baltieri }
19654dfbb08SFabio Baltieri
19788b1c78dSFabio Baltieri ret = regulator_enable(ab->v_ulpi);
19888b1c78dSFabio Baltieri if (ret)
19988b1c78dSFabio Baltieri dev_err(ab->dev, "Failed to enable vddulpivio18\n");
20054dfbb08SFabio Baltieri
201bd4c9f02SFabio Baltieri if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) {
20254dfbb08SFabio Baltieri volt = regulator_get_voltage(ab->v_ulpi);
20354dfbb08SFabio Baltieri if ((volt != 1300000) && (volt != 1350000))
20454dfbb08SFabio Baltieri dev_err(ab->dev, "Vintcore is not set to 1.3V volt=%d\n",
20554dfbb08SFabio Baltieri volt);
20654dfbb08SFabio Baltieri }
20754dfbb08SFabio Baltieri
20888b1c78dSFabio Baltieri ret = regulator_enable(ab->v_musb);
20988b1c78dSFabio Baltieri if (ret)
21088b1c78dSFabio Baltieri dev_err(ab->dev, "Failed to enable musb_1v8\n");
21154dfbb08SFabio Baltieri }
21254dfbb08SFabio Baltieri
ab8500_usb_regulator_disable(struct ab8500_usb * ab)21354dfbb08SFabio Baltieri static void ab8500_usb_regulator_disable(struct ab8500_usb *ab)
21454dfbb08SFabio Baltieri {
21554dfbb08SFabio Baltieri int ret;
21654dfbb08SFabio Baltieri
21754dfbb08SFabio Baltieri regulator_disable(ab->v_musb);
21854dfbb08SFabio Baltieri
21954dfbb08SFabio Baltieri regulator_disable(ab->v_ulpi);
22054dfbb08SFabio Baltieri
22154dfbb08SFabio Baltieri /* USB is not the only consumer of Vintcore, restore old settings */
222bd4c9f02SFabio Baltieri if (ab->flags & AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE) {
22354dfbb08SFabio Baltieri if (ab->saved_v_ulpi > 0) {
22454dfbb08SFabio Baltieri ret = regulator_set_voltage(ab->v_ulpi,
22554dfbb08SFabio Baltieri ab->saved_v_ulpi, ab->saved_v_ulpi);
22654dfbb08SFabio Baltieri if (ret < 0)
22754dfbb08SFabio Baltieri dev_err(ab->dev, "Failed to set the Vintcore to %duV, ret=%d\n",
22854dfbb08SFabio Baltieri ab->saved_v_ulpi, ret);
22954dfbb08SFabio Baltieri }
23054dfbb08SFabio Baltieri
2311d61a694SBjorn Andersson ret = regulator_set_load(ab->v_ulpi, 0);
23254dfbb08SFabio Baltieri if (ret < 0)
23354dfbb08SFabio Baltieri dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n",
23454dfbb08SFabio Baltieri ret);
23554dfbb08SFabio Baltieri }
23654dfbb08SFabio Baltieri
23754dfbb08SFabio Baltieri regulator_disable(ab->v_ape);
23854dfbb08SFabio Baltieri }
23954dfbb08SFabio Baltieri
ab8500_usb_wd_linkstatus(struct ab8500_usb * ab,u8 bit)240af6882beSFabio Baltieri static void ab8500_usb_wd_linkstatus(struct ab8500_usb *ab, u8 bit)
241af6882beSFabio Baltieri {
242af6882beSFabio Baltieri /* Workaround for v2.0 bug # 31952 */
243af6882beSFabio Baltieri if (is_ab8500_2p0(ab->ab8500)) {
244af6882beSFabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev,
245af6882beSFabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG,
246af6882beSFabio Baltieri bit, bit);
247af6882beSFabio Baltieri udelay(AB8500_V20_31952_DISABLE_DELAY_US);
248af6882beSFabio Baltieri }
249af6882beSFabio Baltieri }
250af6882beSFabio Baltieri
ab8500_usb_phy_enable(struct ab8500_usb * ab,bool sel_host)251c0ea7064SFabio Baltieri static void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host)
25294ae9843SFelipe Balbi {
253c0ea7064SFabio Baltieri u8 bit;
254c0ea7064SFabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN :
255c0ea7064SFabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN;
256c0ea7064SFabio Baltieri
257899f0f56SPatrice Chotard /* mux and configure USB pins to DEFAULT state */
258899f0f56SPatrice Chotard ab->pinctrl = pinctrl_get_select(ab->dev, PINCTRL_STATE_DEFAULT);
259899f0f56SPatrice Chotard if (IS_ERR(ab->pinctrl))
260899f0f56SPatrice Chotard dev_err(ab->dev, "could not get/set default pinstate\n");
261899f0f56SPatrice Chotard
262d0ed0645SMian Yousaf Kaukab if (clk_prepare_enable(ab->sysclk))
263d0ed0645SMian Yousaf Kaukab dev_err(ab->dev, "can't prepare/enable clock\n");
264d0ed0645SMian Yousaf Kaukab
26554dfbb08SFabio Baltieri ab8500_usb_regulator_enable(ab);
26654dfbb08SFabio Baltieri
267c0ea7064SFabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev,
268c0ea7064SFabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG,
269c0ea7064SFabio Baltieri bit, bit);
27094ae9843SFelipe Balbi }
27194ae9843SFelipe Balbi
ab8500_usb_phy_disable(struct ab8500_usb * ab,bool sel_host)272c0ea7064SFabio Baltieri static void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host)
273c0ea7064SFabio Baltieri {
274c0ea7064SFabio Baltieri u8 bit;
275c0ea7064SFabio Baltieri bit = sel_host ? AB8500_BIT_PHY_CTRL_HOST_EN :
276c0ea7064SFabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN;
27794ae9843SFelipe Balbi
278c0ea7064SFabio Baltieri ab8500_usb_wd_linkstatus(ab, bit);
279c0ea7064SFabio Baltieri
280c0ea7064SFabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev,
281c0ea7064SFabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG,
282c0ea7064SFabio Baltieri bit, 0);
283c0ea7064SFabio Baltieri
284c0ea7064SFabio Baltieri /* Needed to disable the phy.*/
28594ae9843SFelipe Balbi ab8500_usb_wd_workaround(ab);
28654dfbb08SFabio Baltieri
287d0ed0645SMian Yousaf Kaukab clk_disable_unprepare(ab->sysclk);
288d0ed0645SMian Yousaf Kaukab
28954dfbb08SFabio Baltieri ab8500_usb_regulator_disable(ab);
290899f0f56SPatrice Chotard
291899f0f56SPatrice Chotard if (!IS_ERR(ab->pinctrl)) {
292899f0f56SPatrice Chotard /* configure USB pins to SLEEP state */
293899f0f56SPatrice Chotard ab->pins_sleep = pinctrl_lookup_state(ab->pinctrl,
294899f0f56SPatrice Chotard PINCTRL_STATE_SLEEP);
295899f0f56SPatrice Chotard
296899f0f56SPatrice Chotard if (IS_ERR(ab->pins_sleep))
297899f0f56SPatrice Chotard dev_dbg(ab->dev, "could not get sleep pinstate\n");
298899f0f56SPatrice Chotard else if (pinctrl_select_state(ab->pinctrl, ab->pins_sleep))
299899f0f56SPatrice Chotard dev_err(ab->dev, "could not set pins to sleep state\n");
300899f0f56SPatrice Chotard
3013147dad6SFabio Baltieri /*
3023147dad6SFabio Baltieri * as USB pins are shared with iddet, release them to allow
303899f0f56SPatrice Chotard * iddet to request them
304899f0f56SPatrice Chotard */
305899f0f56SPatrice Chotard pinctrl_put(ab->pinctrl);
306899f0f56SPatrice Chotard }
30794ae9843SFelipe Balbi }
30894ae9843SFelipe Balbi
309c0ea7064SFabio Baltieri #define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_enable(ab, true)
310c0ea7064SFabio Baltieri #define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_disable(ab, true)
311c0ea7064SFabio Baltieri #define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_enable(ab, false)
312c0ea7064SFabio Baltieri #define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_disable(ab, false)
31394ae9843SFelipe Balbi
ab8505_usb_link_status_update(struct ab8500_usb * ab,enum ab8505_usb_link_status lsts)314af6882beSFabio Baltieri static int ab8505_usb_link_status_update(struct ab8500_usb *ab,
315af6882beSFabio Baltieri enum ab8505_usb_link_status lsts)
31694ae9843SFelipe Balbi {
317af6882beSFabio Baltieri enum ux500_musb_vbus_id_status event = 0;
31894ae9843SFelipe Balbi
319af6882beSFabio Baltieri dev_dbg(ab->dev, "ab8505_usb_link_status_update %d\n", lsts);
32094ae9843SFelipe Balbi
321af6882beSFabio Baltieri /*
322af6882beSFabio Baltieri * Spurious link_status interrupts are seen at the time of
323af6882beSFabio Baltieri * disconnection of a device in RIDA state
324af6882beSFabio Baltieri */
325af6882beSFabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8505 &&
326af6882beSFabio Baltieri (lsts == USB_LINK_STD_HOST_NC_8505))
327af6882beSFabio Baltieri return 0;
328af6882beSFabio Baltieri
329af6882beSFabio Baltieri ab->previous_link_status_state = lsts;
33094ae9843SFelipe Balbi
33194ae9843SFelipe Balbi switch (lsts) {
332af6882beSFabio Baltieri case USB_LINK_ACA_RID_B_8505:
333af6882beSFabio Baltieri event = UX500_MUSB_RIDB;
3344e71e079SGustavo A. R. Silva fallthrough;
335af6882beSFabio Baltieri case USB_LINK_NOT_CONFIGURED_8505:
336af6882beSFabio Baltieri case USB_LINK_RESERVED0_8505:
337af6882beSFabio Baltieri case USB_LINK_RESERVED1_8505:
338af6882beSFabio Baltieri case USB_LINK_RESERVED2_8505:
339af6882beSFabio Baltieri case USB_LINK_RESERVED3_8505:
340af6882beSFabio Baltieri ab->mode = USB_IDLE;
34194ae9843SFelipe Balbi ab->phy.otg->default_a = false;
34294ae9843SFelipe Balbi ab->vbus_draw = 0;
343af6882beSFabio Baltieri if (event != UX500_MUSB_RIDB)
344af6882beSFabio Baltieri event = UX500_MUSB_NONE;
345af6882beSFabio Baltieri /*
346af6882beSFabio Baltieri * Fallback to default B_IDLE as nothing
347af6882beSFabio Baltieri * is connected
348af6882beSFabio Baltieri */
349e47d9254SAntoine Tenart ab->phy.otg->state = OTG_STATE_B_IDLE;
350b20f3f9eSKiran Raparthy usb_phy_set_event(&ab->phy, USB_EVENT_NONE);
35194ae9843SFelipe Balbi break;
35294ae9843SFelipe Balbi
353af6882beSFabio Baltieri case USB_LINK_ACA_RID_C_NM_8505:
354af6882beSFabio Baltieri event = UX500_MUSB_RIDC;
3554e71e079SGustavo A. R. Silva fallthrough;
356af6882beSFabio Baltieri case USB_LINK_STD_HOST_NC_8505:
357af6882beSFabio Baltieri case USB_LINK_STD_HOST_C_NS_8505:
358af6882beSFabio Baltieri case USB_LINK_STD_HOST_C_S_8505:
359af6882beSFabio Baltieri case USB_LINK_CDP_8505:
360af6882beSFabio Baltieri if (ab->mode == USB_IDLE) {
361af6882beSFabio Baltieri ab->mode = USB_PERIPHERAL;
36294ae9843SFelipe Balbi ab8500_usb_peri_phy_en(ab);
363af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
364af6882beSFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw);
365b20f3f9eSKiran Raparthy usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED);
36694ae9843SFelipe Balbi }
367af6882beSFabio Baltieri if (event != UX500_MUSB_RIDC)
368af6882beSFabio Baltieri event = UX500_MUSB_VBUS;
36994ae9843SFelipe Balbi break;
37094ae9843SFelipe Balbi
371af6882beSFabio Baltieri case USB_LINK_ACA_RID_A_8505:
372af6882beSFabio Baltieri case USB_LINK_ACA_DOCK_CHGR_8505:
373af6882beSFabio Baltieri event = UX500_MUSB_RIDA;
3744e71e079SGustavo A. R. Silva fallthrough;
375af6882beSFabio Baltieri case USB_LINK_HM_IDGND_8505:
376af6882beSFabio Baltieri if (ab->mode == USB_IDLE) {
377af6882beSFabio Baltieri ab->mode = USB_HOST;
37894ae9843SFelipe Balbi ab8500_usb_host_phy_en(ab);
379af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
380af6882beSFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw);
38194ae9843SFelipe Balbi }
38294ae9843SFelipe Balbi ab->phy.otg->default_a = true;
383af6882beSFabio Baltieri if (event != UX500_MUSB_RIDA)
384af6882beSFabio Baltieri event = UX500_MUSB_ID;
385af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
386af6882beSFabio Baltieri event, &ab->vbus_draw);
38794ae9843SFelipe Balbi break;
38894ae9843SFelipe Balbi
389af6882beSFabio Baltieri case USB_LINK_DEDICATED_CHG_8505:
390af6882beSFabio Baltieri ab->mode = USB_DEDICATED_CHG;
391af6882beSFabio Baltieri event = UX500_MUSB_CHARGER;
392af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
393af6882beSFabio Baltieri event, &ab->vbus_draw);
394b20f3f9eSKiran Raparthy usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER);
395af6882beSFabio Baltieri break;
396af6882beSFabio Baltieri
397c4a68b4dSStephan Gerhold /*
398c4a68b4dSStephan Gerhold * FIXME: For now we rely on the boot firmware to set up the necessary
399c4a68b4dSStephan Gerhold * PHY/pin configuration for UART mode.
400c4a68b4dSStephan Gerhold *
401c4a68b4dSStephan Gerhold * AB8505 does not seem to report any status change for UART cables,
402c4a68b4dSStephan Gerhold * possibly because it cannot detect them autonomously.
403c4a68b4dSStephan Gerhold * We may need to measure the ID resistance manually to reliably
404c4a68b4dSStephan Gerhold * detect UART cables after bootup.
405c4a68b4dSStephan Gerhold */
406c4a68b4dSStephan Gerhold case USB_LINK_SAMSUNG_UART_CBL_PHY_EN_8505:
407c4a68b4dSStephan Gerhold case USB_LINK_SAMSUNG_UART_CBL_PHY_DISB_8505:
408c4a68b4dSStephan Gerhold if (ab->mode == USB_IDLE) {
409c4a68b4dSStephan Gerhold ab->mode = USB_UART;
410c4a68b4dSStephan Gerhold ab8500_usb_peri_phy_en(ab);
411c4a68b4dSStephan Gerhold }
412c4a68b4dSStephan Gerhold
413c4a68b4dSStephan Gerhold break;
414c4a68b4dSStephan Gerhold
415af6882beSFabio Baltieri default:
41694ae9843SFelipe Balbi break;
41794ae9843SFelipe Balbi }
41894ae9843SFelipe Balbi
41994ae9843SFelipe Balbi return 0;
42094ae9843SFelipe Balbi }
42194ae9843SFelipe Balbi
ab8500_usb_link_status_update(struct ab8500_usb * ab,enum ab8500_usb_link_status lsts)422af6882beSFabio Baltieri static int ab8500_usb_link_status_update(struct ab8500_usb *ab,
423af6882beSFabio Baltieri enum ab8500_usb_link_status lsts)
424af6882beSFabio Baltieri {
425af6882beSFabio Baltieri enum ux500_musb_vbus_id_status event = 0;
426af6882beSFabio Baltieri
427af6882beSFabio Baltieri dev_dbg(ab->dev, "ab8500_usb_link_status_update %d\n", lsts);
428af6882beSFabio Baltieri
429af6882beSFabio Baltieri /*
430af6882beSFabio Baltieri * Spurious link_status interrupts are seen in case of a
431af6882beSFabio Baltieri * disconnection of a device in IDGND and RIDA stage
432af6882beSFabio Baltieri */
433af6882beSFabio Baltieri if (ab->previous_link_status_state == USB_LINK_HM_IDGND_8500 &&
434af6882beSFabio Baltieri (lsts == USB_LINK_STD_HOST_C_NS_8500 ||
435af6882beSFabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500))
436af6882beSFabio Baltieri return 0;
437af6882beSFabio Baltieri
438af6882beSFabio Baltieri if (ab->previous_link_status_state == USB_LINK_ACA_RID_A_8500 &&
439af6882beSFabio Baltieri lsts == USB_LINK_STD_HOST_NC_8500)
440af6882beSFabio Baltieri return 0;
441af6882beSFabio Baltieri
442af6882beSFabio Baltieri ab->previous_link_status_state = lsts;
443af6882beSFabio Baltieri
444af6882beSFabio Baltieri switch (lsts) {
445af6882beSFabio Baltieri case USB_LINK_ACA_RID_B_8500:
446af6882beSFabio Baltieri event = UX500_MUSB_RIDB;
4474e71e079SGustavo A. R. Silva fallthrough;
448af6882beSFabio Baltieri case USB_LINK_NOT_CONFIGURED_8500:
449af6882beSFabio Baltieri case USB_LINK_NOT_VALID_LINK_8500:
450af6882beSFabio Baltieri ab->mode = USB_IDLE;
451af6882beSFabio Baltieri ab->phy.otg->default_a = false;
452af6882beSFabio Baltieri ab->vbus_draw = 0;
453af6882beSFabio Baltieri if (event != UX500_MUSB_RIDB)
454af6882beSFabio Baltieri event = UX500_MUSB_NONE;
455af6882beSFabio Baltieri /* Fallback to default B_IDLE as nothing is connected */
456e47d9254SAntoine Tenart ab->phy.otg->state = OTG_STATE_B_IDLE;
457b20f3f9eSKiran Raparthy usb_phy_set_event(&ab->phy, USB_EVENT_NONE);
458af6882beSFabio Baltieri break;
459af6882beSFabio Baltieri
460af6882beSFabio Baltieri case USB_LINK_ACA_RID_C_NM_8500:
461af6882beSFabio Baltieri case USB_LINK_ACA_RID_C_HS_8500:
462af6882beSFabio Baltieri case USB_LINK_ACA_RID_C_HS_CHIRP_8500:
463af6882beSFabio Baltieri event = UX500_MUSB_RIDC;
4644e71e079SGustavo A. R. Silva fallthrough;
465af6882beSFabio Baltieri case USB_LINK_STD_HOST_NC_8500:
466af6882beSFabio Baltieri case USB_LINK_STD_HOST_C_NS_8500:
467af6882beSFabio Baltieri case USB_LINK_STD_HOST_C_S_8500:
468af6882beSFabio Baltieri case USB_LINK_HOST_CHG_NM_8500:
469af6882beSFabio Baltieri case USB_LINK_HOST_CHG_HS_8500:
470af6882beSFabio Baltieri case USB_LINK_HOST_CHG_HS_CHIRP_8500:
471af6882beSFabio Baltieri if (ab->mode == USB_IDLE) {
472af6882beSFabio Baltieri ab->mode = USB_PERIPHERAL;
473af6882beSFabio Baltieri ab8500_usb_peri_phy_en(ab);
474af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
475af6882beSFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw);
476b20f3f9eSKiran Raparthy usb_phy_set_event(&ab->phy, USB_EVENT_ENUMERATED);
477af6882beSFabio Baltieri }
478af6882beSFabio Baltieri if (event != UX500_MUSB_RIDC)
479af6882beSFabio Baltieri event = UX500_MUSB_VBUS;
480af6882beSFabio Baltieri break;
481af6882beSFabio Baltieri
482af6882beSFabio Baltieri case USB_LINK_ACA_RID_A_8500:
483af6882beSFabio Baltieri event = UX500_MUSB_RIDA;
4844e71e079SGustavo A. R. Silva fallthrough;
485af6882beSFabio Baltieri case USB_LINK_HM_IDGND_8500:
486af6882beSFabio Baltieri if (ab->mode == USB_IDLE) {
487af6882beSFabio Baltieri ab->mode = USB_HOST;
488af6882beSFabio Baltieri ab8500_usb_host_phy_en(ab);
489af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
490af6882beSFabio Baltieri UX500_MUSB_PREPARE, &ab->vbus_draw);
491af6882beSFabio Baltieri }
492af6882beSFabio Baltieri ab->phy.otg->default_a = true;
493af6882beSFabio Baltieri if (event != UX500_MUSB_RIDA)
494af6882beSFabio Baltieri event = UX500_MUSB_ID;
495af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
496af6882beSFabio Baltieri event, &ab->vbus_draw);
497af6882beSFabio Baltieri break;
498af6882beSFabio Baltieri
499af6882beSFabio Baltieri case USB_LINK_DEDICATED_CHG_8500:
500af6882beSFabio Baltieri ab->mode = USB_DEDICATED_CHG;
501af6882beSFabio Baltieri event = UX500_MUSB_CHARGER;
502af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
503af6882beSFabio Baltieri event, &ab->vbus_draw);
504b20f3f9eSKiran Raparthy usb_phy_set_event(&ab->phy, USB_EVENT_CHARGER);
505af6882beSFabio Baltieri break;
506af6882beSFabio Baltieri
507af6882beSFabio Baltieri case USB_LINK_RESERVED_8500:
508af6882beSFabio Baltieri break;
509af6882beSFabio Baltieri }
510af6882beSFabio Baltieri
511af6882beSFabio Baltieri return 0;
512af6882beSFabio Baltieri }
513af6882beSFabio Baltieri
514af6882beSFabio Baltieri /*
515af6882beSFabio Baltieri * Connection Sequence:
516af6882beSFabio Baltieri * 1. Link Status Interrupt
517af6882beSFabio Baltieri * 2. Enable AB clock
518af6882beSFabio Baltieri * 3. Enable AB regulators
519af6882beSFabio Baltieri * 4. Enable USB phy
520af6882beSFabio Baltieri * 5. Reset the musb controller
521f5f875b5SRandy Dunlap * 6. Switch the ULPI GPIO pins to function mode
522af6882beSFabio Baltieri * 7. Enable the musb Peripheral5 clock
523af6882beSFabio Baltieri * 8. Restore MUSB context
524af6882beSFabio Baltieri */
abx500_usb_link_status_update(struct ab8500_usb * ab)525af6882beSFabio Baltieri static int abx500_usb_link_status_update(struct ab8500_usb *ab)
526af6882beSFabio Baltieri {
527af6882beSFabio Baltieri u8 reg;
528af6882beSFabio Baltieri int ret = 0;
529af6882beSFabio Baltieri
530af6882beSFabio Baltieri if (is_ab8500(ab->ab8500)) {
531af6882beSFabio Baltieri enum ab8500_usb_link_status lsts;
532af6882beSFabio Baltieri
533b8d9ee24SDan Carpenter ret = abx500_get_register_interruptible(ab->dev,
534af6882beSFabio Baltieri AB8500_USB, AB8500_USB_LINE_STAT_REG, ®);
535b8d9ee24SDan Carpenter if (ret < 0)
536b8d9ee24SDan Carpenter return ret;
537af6882beSFabio Baltieri lsts = (reg >> 3) & 0x0F;
538af6882beSFabio Baltieri ret = ab8500_usb_link_status_update(ab, lsts);
539af6882beSFabio Baltieri } else if (is_ab8505(ab->ab8500)) {
540af6882beSFabio Baltieri enum ab8505_usb_link_status lsts;
541af6882beSFabio Baltieri
542b8d9ee24SDan Carpenter ret = abx500_get_register_interruptible(ab->dev,
543af6882beSFabio Baltieri AB8500_USB, AB8505_USB_LINE_STAT_REG, ®);
544b8d9ee24SDan Carpenter if (ret < 0)
545b8d9ee24SDan Carpenter return ret;
546af6882beSFabio Baltieri lsts = (reg >> 3) & 0x1F;
547af6882beSFabio Baltieri ret = ab8505_usb_link_status_update(ab, lsts);
548af6882beSFabio Baltieri }
549af6882beSFabio Baltieri
550af6882beSFabio Baltieri return ret;
551af6882beSFabio Baltieri }
552af6882beSFabio Baltieri
553af6882beSFabio Baltieri /*
554af6882beSFabio Baltieri * Disconnection Sequence:
5552b08977bSMickael Maison * 1. Disconnect Interrupt
556af6882beSFabio Baltieri * 2. Disable regulators
557af6882beSFabio Baltieri * 3. Disable AB clock
558af6882beSFabio Baltieri * 4. Disable the Phy
559af6882beSFabio Baltieri * 5. Link Status Interrupt
560af6882beSFabio Baltieri * 6. Disable Musb Clock
561af6882beSFabio Baltieri */
ab8500_usb_disconnect_irq(int irq,void * data)562af6882beSFabio Baltieri static irqreturn_t ab8500_usb_disconnect_irq(int irq, void *data)
563af6882beSFabio Baltieri {
564af6882beSFabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *) data;
5656eb5ac2eSStefan Agner enum usb_phy_events event = USB_EVENT_NONE;
566af6882beSFabio Baltieri
567af6882beSFabio Baltieri /* Link status will not be updated till phy is disabled. */
568af6882beSFabio Baltieri if (ab->mode == USB_HOST) {
569af6882beSFabio Baltieri ab->phy.otg->default_a = false;
570af6882beSFabio Baltieri ab->vbus_draw = 0;
571af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
572af6882beSFabio Baltieri event, &ab->vbus_draw);
573af6882beSFabio Baltieri ab8500_usb_host_phy_dis(ab);
574af6882beSFabio Baltieri ab->mode = USB_IDLE;
575af6882beSFabio Baltieri }
576af6882beSFabio Baltieri
577af6882beSFabio Baltieri if (ab->mode == USB_PERIPHERAL) {
578af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
579af6882beSFabio Baltieri event, &ab->vbus_draw);
580af6882beSFabio Baltieri ab8500_usb_peri_phy_dis(ab);
581af6882beSFabio Baltieri atomic_notifier_call_chain(&ab->phy.notifier,
582af6882beSFabio Baltieri UX500_MUSB_CLEAN, &ab->vbus_draw);
583af6882beSFabio Baltieri ab->mode = USB_IDLE;
584af6882beSFabio Baltieri ab->phy.otg->default_a = false;
585af6882beSFabio Baltieri ab->vbus_draw = 0;
586af6882beSFabio Baltieri }
587af6882beSFabio Baltieri
588c4a68b4dSStephan Gerhold if (ab->mode == USB_UART) {
589c4a68b4dSStephan Gerhold ab8500_usb_peri_phy_dis(ab);
590c4a68b4dSStephan Gerhold ab->mode = USB_IDLE;
591c4a68b4dSStephan Gerhold }
592c4a68b4dSStephan Gerhold
593af6882beSFabio Baltieri if (is_ab8500_2p0(ab->ab8500)) {
594af6882beSFabio Baltieri if (ab->mode == USB_DEDICATED_CHG) {
595af6882beSFabio Baltieri ab8500_usb_wd_linkstatus(ab,
596af6882beSFabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN);
597af6882beSFabio Baltieri abx500_mask_and_set_register_interruptible(ab->dev,
598af6882beSFabio Baltieri AB8500_USB, AB8500_USB_PHY_CTRL_REG,
599af6882beSFabio Baltieri AB8500_BIT_PHY_CTRL_DEVICE_EN, 0);
600af6882beSFabio Baltieri }
601af6882beSFabio Baltieri }
602af6882beSFabio Baltieri
603af6882beSFabio Baltieri return IRQ_HANDLED;
604af6882beSFabio Baltieri }
605af6882beSFabio Baltieri
ab8500_usb_link_status_irq(int irq,void * data)606af6882beSFabio Baltieri static irqreturn_t ab8500_usb_link_status_irq(int irq, void *data)
607af6882beSFabio Baltieri {
608af6882beSFabio Baltieri struct ab8500_usb *ab = (struct ab8500_usb *)data;
609af6882beSFabio Baltieri
610af6882beSFabio Baltieri abx500_usb_link_status_update(ab);
611af6882beSFabio Baltieri
612af6882beSFabio Baltieri return IRQ_HANDLED;
613af6882beSFabio Baltieri }
614af6882beSFabio Baltieri
ab8500_usb_phy_disable_work(struct work_struct * work)61594ae9843SFelipe Balbi static void ab8500_usb_phy_disable_work(struct work_struct *work)
61694ae9843SFelipe Balbi {
61794ae9843SFelipe Balbi struct ab8500_usb *ab = container_of(work, struct ab8500_usb,
61894ae9843SFelipe Balbi phy_dis_work);
61994ae9843SFelipe Balbi
62094ae9843SFelipe Balbi if (!ab->phy.otg->host)
62194ae9843SFelipe Balbi ab8500_usb_host_phy_dis(ab);
62294ae9843SFelipe Balbi
62394ae9843SFelipe Balbi if (!ab->phy.otg->gadget)
62494ae9843SFelipe Balbi ab8500_usb_peri_phy_dis(ab);
62594ae9843SFelipe Balbi }
62694ae9843SFelipe Balbi
ab8500_usb_set_suspend(struct usb_phy * x,int suspend)62794ae9843SFelipe Balbi static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend)
62894ae9843SFelipe Balbi {
62994ae9843SFelipe Balbi /* TODO */
63094ae9843SFelipe Balbi return 0;
63194ae9843SFelipe Balbi }
63294ae9843SFelipe Balbi
ab8500_usb_set_peripheral(struct usb_otg * otg,struct usb_gadget * gadget)63394ae9843SFelipe Balbi static int ab8500_usb_set_peripheral(struct usb_otg *otg,
63494ae9843SFelipe Balbi struct usb_gadget *gadget)
63594ae9843SFelipe Balbi {
63694ae9843SFelipe Balbi struct ab8500_usb *ab;
63794ae9843SFelipe Balbi
63894ae9843SFelipe Balbi if (!otg)
63994ae9843SFelipe Balbi return -ENODEV;
64094ae9843SFelipe Balbi
64119c1eac2SAntoine Tenart ab = phy_to_ab(otg->usb_phy);
64294ae9843SFelipe Balbi
64358823373SSakethram Bommisetti ab->phy.otg->gadget = gadget;
64458823373SSakethram Bommisetti
64594ae9843SFelipe Balbi /* Some drivers call this function in atomic context.
64694ae9843SFelipe Balbi * Do not update ab8500 registers directly till this
64794ae9843SFelipe Balbi * is fixed.
64894ae9843SFelipe Balbi */
64994ae9843SFelipe Balbi
6503147dad6SFabio Baltieri if ((ab->mode != USB_IDLE) && !gadget) {
65158823373SSakethram Bommisetti ab->mode = USB_IDLE;
65294ae9843SFelipe Balbi schedule_work(&ab->phy_dis_work);
65394ae9843SFelipe Balbi }
65494ae9843SFelipe Balbi
65594ae9843SFelipe Balbi return 0;
65694ae9843SFelipe Balbi }
65794ae9843SFelipe Balbi
ab8500_usb_set_host(struct usb_otg * otg,struct usb_bus * host)65894ae9843SFelipe Balbi static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
65994ae9843SFelipe Balbi {
66094ae9843SFelipe Balbi struct ab8500_usb *ab;
66194ae9843SFelipe Balbi
66294ae9843SFelipe Balbi if (!otg)
66394ae9843SFelipe Balbi return -ENODEV;
66494ae9843SFelipe Balbi
66519c1eac2SAntoine Tenart ab = phy_to_ab(otg->usb_phy);
66694ae9843SFelipe Balbi
66758823373SSakethram Bommisetti ab->phy.otg->host = host;
66858823373SSakethram Bommisetti
66994ae9843SFelipe Balbi /* Some drivers call this function in atomic context.
67094ae9843SFelipe Balbi * Do not update ab8500 registers directly till this
67194ae9843SFelipe Balbi * is fixed.
67294ae9843SFelipe Balbi */
67394ae9843SFelipe Balbi
6743147dad6SFabio Baltieri if ((ab->mode != USB_IDLE) && !host) {
67558823373SSakethram Bommisetti ab->mode = USB_IDLE;
67694ae9843SFelipe Balbi schedule_work(&ab->phy_dis_work);
67794ae9843SFelipe Balbi }
67894ae9843SFelipe Balbi
67994ae9843SFelipe Balbi return 0;
68094ae9843SFelipe Balbi }
68194ae9843SFelipe Balbi
ab8500_usb_restart_phy(struct ab8500_usb * ab)682fb21f37aSSakethram Bommisetti static void ab8500_usb_restart_phy(struct ab8500_usb *ab)
683fb21f37aSSakethram Bommisetti {
684fb21f37aSSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev,
685fb21f37aSSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG,
686fb21f37aSSakethram Bommisetti AB8500_BIT_PHY_CTRL_DEVICE_EN,
687fb21f37aSSakethram Bommisetti AB8500_BIT_PHY_CTRL_DEVICE_EN);
688fb21f37aSSakethram Bommisetti
689fb21f37aSSakethram Bommisetti udelay(100);
690fb21f37aSSakethram Bommisetti
691fb21f37aSSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev,
692fb21f37aSSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG,
693fb21f37aSSakethram Bommisetti AB8500_BIT_PHY_CTRL_DEVICE_EN,
694fb21f37aSSakethram Bommisetti 0);
695fb21f37aSSakethram Bommisetti
696fb21f37aSSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev,
697fb21f37aSSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG,
698fb21f37aSSakethram Bommisetti AB8500_BIT_PHY_CTRL_HOST_EN,
699fb21f37aSSakethram Bommisetti AB8500_BIT_PHY_CTRL_HOST_EN);
700fb21f37aSSakethram Bommisetti
701fb21f37aSSakethram Bommisetti udelay(100);
702fb21f37aSSakethram Bommisetti
703fb21f37aSSakethram Bommisetti abx500_mask_and_set_register_interruptible(ab->dev,
704fb21f37aSSakethram Bommisetti AB8500_USB, AB8500_USB_PHY_CTRL_REG,
705fb21f37aSSakethram Bommisetti AB8500_BIT_PHY_CTRL_HOST_EN,
706fb21f37aSSakethram Bommisetti 0);
707fb21f37aSSakethram Bommisetti }
708fb21f37aSSakethram Bommisetti
ab8500_usb_regulator_get(struct ab8500_usb * ab)709e65b36c0SFabio Baltieri static int ab8500_usb_regulator_get(struct ab8500_usb *ab)
710e65b36c0SFabio Baltieri {
711e65b36c0SFabio Baltieri int err;
712e65b36c0SFabio Baltieri
713e65b36c0SFabio Baltieri ab->v_ape = devm_regulator_get(ab->dev, "v-ape");
714e65b36c0SFabio Baltieri if (IS_ERR(ab->v_ape)) {
715e65b36c0SFabio Baltieri dev_err(ab->dev, "Could not get v-ape supply\n");
716e65b36c0SFabio Baltieri err = PTR_ERR(ab->v_ape);
717e65b36c0SFabio Baltieri return err;
718e65b36c0SFabio Baltieri }
719e65b36c0SFabio Baltieri
720e65b36c0SFabio Baltieri ab->v_ulpi = devm_regulator_get(ab->dev, "vddulpivio18");
721e65b36c0SFabio Baltieri if (IS_ERR(ab->v_ulpi)) {
722e65b36c0SFabio Baltieri dev_err(ab->dev, "Could not get vddulpivio18 supply\n");
723e65b36c0SFabio Baltieri err = PTR_ERR(ab->v_ulpi);
724e65b36c0SFabio Baltieri return err;
725e65b36c0SFabio Baltieri }
726e65b36c0SFabio Baltieri
727e65b36c0SFabio Baltieri ab->v_musb = devm_regulator_get(ab->dev, "musb_1v8");
728e65b36c0SFabio Baltieri if (IS_ERR(ab->v_musb)) {
729e65b36c0SFabio Baltieri dev_err(ab->dev, "Could not get musb_1v8 supply\n");
730e65b36c0SFabio Baltieri err = PTR_ERR(ab->v_musb);
731e65b36c0SFabio Baltieri return err;
732e65b36c0SFabio Baltieri }
733e65b36c0SFabio Baltieri
734e65b36c0SFabio Baltieri return 0;
735e65b36c0SFabio Baltieri }
736e65b36c0SFabio Baltieri
ab8500_usb_irq_setup(struct platform_device * pdev,struct ab8500_usb * ab)737af6882beSFabio Baltieri static int ab8500_usb_irq_setup(struct platform_device *pdev,
73894ae9843SFelipe Balbi struct ab8500_usb *ab)
73994ae9843SFelipe Balbi {
74094ae9843SFelipe Balbi int err;
741af6882beSFabio Baltieri int irq;
74294ae9843SFelipe Balbi
743bd4c9f02SFabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_LINK_STATUS_IRQ) {
744af6882beSFabio Baltieri irq = platform_get_irq_byname(pdev, "USB_LINK_STATUS");
745b33f3706SStephen Boyd if (irq < 0)
746af6882beSFabio Baltieri return irq;
747af6882beSFabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
748af6882beSFabio Baltieri ab8500_usb_link_status_irq,
7492b129789SFabio Estevam IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,
750bd4c9f02SFabio Baltieri "usb-link-status", ab);
751af6882beSFabio Baltieri if (err < 0) {
752af6882beSFabio Baltieri dev_err(ab->dev, "request_irq failed for link status irq\n");
753af6882beSFabio Baltieri return err;
75494ae9843SFelipe Balbi }
755bd4c9f02SFabio Baltieri }
75694ae9843SFelipe Balbi
757bd4c9f02SFabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ) {
758af6882beSFabio Baltieri irq = platform_get_irq_byname(pdev, "ID_WAKEUP_F");
759b33f3706SStephen Boyd if (irq < 0)
760af6882beSFabio Baltieri return irq;
761af6882beSFabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
762af6882beSFabio Baltieri ab8500_usb_disconnect_irq,
7632b129789SFabio Estevam IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,
764bd4c9f02SFabio Baltieri "usb-id-fall", ab);
76594ae9843SFelipe Balbi if (err < 0) {
766af6882beSFabio Baltieri dev_err(ab->dev, "request_irq failed for ID fall irq\n");
767af6882beSFabio Baltieri return err;
768af6882beSFabio Baltieri }
769bd4c9f02SFabio Baltieri }
770af6882beSFabio Baltieri
771bd4c9f02SFabio Baltieri if (ab->flags & AB8500_USB_FLAG_USE_VBUS_DET_IRQ) {
772af6882beSFabio Baltieri irq = platform_get_irq_byname(pdev, "VBUS_DET_F");
773b33f3706SStephen Boyd if (irq < 0)
774af6882beSFabio Baltieri return irq;
775af6882beSFabio Baltieri err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
776af6882beSFabio Baltieri ab8500_usb_disconnect_irq,
7772b129789SFabio Estevam IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,
778bd4c9f02SFabio Baltieri "usb-vbus-fall", ab);
779af6882beSFabio Baltieri if (err < 0) {
780af6882beSFabio Baltieri dev_err(ab->dev, "request_irq failed for Vbus fall irq\n");
78194ae9843SFelipe Balbi return err;
78294ae9843SFelipe Balbi }
783bd4c9f02SFabio Baltieri }
78494ae9843SFelipe Balbi
78594ae9843SFelipe Balbi return 0;
78694ae9843SFelipe Balbi }
78794ae9843SFelipe Balbi
ab8500_usb_set_ab8500_tuning_values(struct ab8500_usb * ab)78816604a3cSFabio Baltieri static void ab8500_usb_set_ab8500_tuning_values(struct ab8500_usb *ab)
78916604a3cSFabio Baltieri {
79016604a3cSFabio Baltieri int err;
79116604a3cSFabio Baltieri
79216604a3cSFabio Baltieri /* Enable the PBT/Bank 0x12 access */
79316604a3cSFabio Baltieri err = abx500_set_register_interruptible(ab->dev,
79416604a3cSFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01);
79516604a3cSFabio Baltieri if (err < 0)
79616604a3cSFabio Baltieri dev_err(ab->dev, "Failed to enable bank12 access err=%d\n",
79716604a3cSFabio Baltieri err);
79816604a3cSFabio Baltieri
79916604a3cSFabio Baltieri err = abx500_set_register_interruptible(ab->dev,
80016604a3cSFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8);
80116604a3cSFabio Baltieri if (err < 0)
80216604a3cSFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n",
80316604a3cSFabio Baltieri err);
80416604a3cSFabio Baltieri
80516604a3cSFabio Baltieri err = abx500_set_register_interruptible(ab->dev,
80616604a3cSFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00);
80716604a3cSFabio Baltieri if (err < 0)
80816604a3cSFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n",
80916604a3cSFabio Baltieri err);
81016604a3cSFabio Baltieri
81116604a3cSFabio Baltieri err = abx500_set_register_interruptible(ab->dev,
81216604a3cSFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78);
81316604a3cSFabio Baltieri if (err < 0)
8147eee236cSColin Ian King dev_err(ab->dev, "Failed to set PHY_TUNE3 register err=%d\n",
81516604a3cSFabio Baltieri err);
81616604a3cSFabio Baltieri
81716604a3cSFabio Baltieri /* Switch to normal mode/disable Bank 0x12 access */
81816604a3cSFabio Baltieri err = abx500_set_register_interruptible(ab->dev,
81916604a3cSFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x00);
82016604a3cSFabio Baltieri if (err < 0)
82116604a3cSFabio Baltieri dev_err(ab->dev, "Failed to switch bank12 access err=%d\n",
82216604a3cSFabio Baltieri err);
82316604a3cSFabio Baltieri }
82416604a3cSFabio Baltieri
ab8500_usb_set_ab8505_tuning_values(struct ab8500_usb * ab)82516604a3cSFabio Baltieri static void ab8500_usb_set_ab8505_tuning_values(struct ab8500_usb *ab)
82616604a3cSFabio Baltieri {
82716604a3cSFabio Baltieri int err;
82816604a3cSFabio Baltieri
82916604a3cSFabio Baltieri /* Enable the PBT/Bank 0x12 access */
83016604a3cSFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev,
83116604a3cSFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS,
83216604a3cSFabio Baltieri 0x01, 0x01);
83316604a3cSFabio Baltieri if (err < 0)
83416604a3cSFabio Baltieri dev_err(ab->dev, "Failed to enable bank12 access err=%d\n",
83516604a3cSFabio Baltieri err);
83616604a3cSFabio Baltieri
83716604a3cSFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev,
83816604a3cSFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE1,
83916604a3cSFabio Baltieri 0xC8, 0xC8);
84016604a3cSFabio Baltieri if (err < 0)
84116604a3cSFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE1 register err=%d\n",
84216604a3cSFabio Baltieri err);
84316604a3cSFabio Baltieri
84416604a3cSFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev,
84516604a3cSFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE2,
84616604a3cSFabio Baltieri 0x60, 0x60);
84716604a3cSFabio Baltieri if (err < 0)
84816604a3cSFabio Baltieri dev_err(ab->dev, "Failed to set PHY_TUNE2 register err=%d\n",
84916604a3cSFabio Baltieri err);
85016604a3cSFabio Baltieri
85116604a3cSFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev,
85216604a3cSFabio Baltieri AB8500_DEBUG, AB8500_USB_PHY_TUNE3,
85316604a3cSFabio Baltieri 0xFC, 0x80);
85416604a3cSFabio Baltieri
85516604a3cSFabio Baltieri if (err < 0)
8567eee236cSColin Ian King dev_err(ab->dev, "Failed to set PHY_TUNE3 register err=%d\n",
85716604a3cSFabio Baltieri err);
85816604a3cSFabio Baltieri
85916604a3cSFabio Baltieri /* Switch to normal mode/disable Bank 0x12 access */
86016604a3cSFabio Baltieri err = abx500_mask_and_set_register_interruptible(ab->dev,
86116604a3cSFabio Baltieri AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS,
86216604a3cSFabio Baltieri 0x00, 0x00);
86316604a3cSFabio Baltieri if (err < 0)
86416604a3cSFabio Baltieri dev_err(ab->dev, "Failed to switch bank12 access err=%d\n",
86516604a3cSFabio Baltieri err);
86616604a3cSFabio Baltieri }
86716604a3cSFabio Baltieri
ab8500_usb_probe(struct platform_device * pdev)86894ae9843SFelipe Balbi static int ab8500_usb_probe(struct platform_device *pdev)
86994ae9843SFelipe Balbi {
87094ae9843SFelipe Balbi struct ab8500_usb *ab;
87173f226cbSFabio Baltieri struct ab8500 *ab8500;
87294ae9843SFelipe Balbi struct usb_otg *otg;
87394ae9843SFelipe Balbi int err;
87494ae9843SFelipe Balbi int rev;
87594ae9843SFelipe Balbi
87673f226cbSFabio Baltieri ab8500 = dev_get_drvdata(pdev->dev.parent);
87794ae9843SFelipe Balbi rev = abx500_get_chip_id(&pdev->dev);
87873f226cbSFabio Baltieri
87973f226cbSFabio Baltieri if (is_ab8500_1p1_or_earlier(ab8500)) {
88073f226cbSFabio Baltieri dev_err(&pdev->dev, "Unsupported AB8500 chip rev=%d\n", rev);
88194ae9843SFelipe Balbi return -ENODEV;
88294ae9843SFelipe Balbi }
88394ae9843SFelipe Balbi
88481ef6724SFabio Baltieri ab = devm_kzalloc(&pdev->dev, sizeof(*ab), GFP_KERNEL);
88594ae9843SFelipe Balbi if (!ab)
88694ae9843SFelipe Balbi return -ENOMEM;
88794ae9843SFelipe Balbi
88881ef6724SFabio Baltieri otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
88981ef6724SFabio Baltieri if (!otg)
89094ae9843SFelipe Balbi return -ENOMEM;
89194ae9843SFelipe Balbi
89294ae9843SFelipe Balbi ab->dev = &pdev->dev;
89373f226cbSFabio Baltieri ab->ab8500 = ab8500;
89494ae9843SFelipe Balbi ab->phy.dev = ab->dev;
89594ae9843SFelipe Balbi ab->phy.otg = otg;
89694ae9843SFelipe Balbi ab->phy.label = "ab8500";
89794ae9843SFelipe Balbi ab->phy.set_suspend = ab8500_usb_set_suspend;
898e47d9254SAntoine Tenart ab->phy.otg->state = OTG_STATE_UNDEFINED;
89994ae9843SFelipe Balbi
90019c1eac2SAntoine Tenart otg->usb_phy = &ab->phy;
90194ae9843SFelipe Balbi otg->set_host = ab8500_usb_set_host;
90294ae9843SFelipe Balbi otg->set_peripheral = ab8500_usb_set_peripheral;
90394ae9843SFelipe Balbi
904bd4c9f02SFabio Baltieri if (is_ab8500(ab->ab8500)) {
905bd4c9f02SFabio Baltieri ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ |
906bd4c9f02SFabio Baltieri AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ |
907bd4c9f02SFabio Baltieri AB8500_USB_FLAG_USE_VBUS_DET_IRQ |
908bd4c9f02SFabio Baltieri AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE;
909bd4c9f02SFabio Baltieri } else if (is_ab8505(ab->ab8500)) {
910bd4c9f02SFabio Baltieri ab->flags |= AB8500_USB_FLAG_USE_LINK_STATUS_IRQ |
911bd4c9f02SFabio Baltieri AB8500_USB_FLAG_USE_ID_WAKEUP_IRQ |
912bd4c9f02SFabio Baltieri AB8500_USB_FLAG_USE_VBUS_DET_IRQ |
913bd4c9f02SFabio Baltieri AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE;
914bd4c9f02SFabio Baltieri }
915bd4c9f02SFabio Baltieri
916bd4c9f02SFabio Baltieri /* Disable regulator voltage setting for AB8500 <= v2.0 */
917bd4c9f02SFabio Baltieri if (is_ab8500_2p0_or_earlier(ab->ab8500))
918bd4c9f02SFabio Baltieri ab->flags &= ~AB8500_USB_FLAG_REGULATOR_SET_VOLTAGE;
919bd4c9f02SFabio Baltieri
92094ae9843SFelipe Balbi platform_set_drvdata(pdev, ab);
92194ae9843SFelipe Balbi
92294ae9843SFelipe Balbi /* all: Disable phy when called from set_host and set_peripheral */
92394ae9843SFelipe Balbi INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work);
92494ae9843SFelipe Balbi
925e65b36c0SFabio Baltieri err = ab8500_usb_regulator_get(ab);
926e65b36c0SFabio Baltieri if (err)
927e65b36c0SFabio Baltieri return err;
928e65b36c0SFabio Baltieri
929d0ed0645SMian Yousaf Kaukab ab->sysclk = devm_clk_get(ab->dev, "sysclk");
930d0ed0645SMian Yousaf Kaukab if (IS_ERR(ab->sysclk)) {
931d0ed0645SMian Yousaf Kaukab dev_err(ab->dev, "Could not get sysclk.\n");
932d0ed0645SMian Yousaf Kaukab return PTR_ERR(ab->sysclk);
933d0ed0645SMian Yousaf Kaukab }
934d0ed0645SMian Yousaf Kaukab
935af6882beSFabio Baltieri err = ab8500_usb_irq_setup(pdev, ab);
93694ae9843SFelipe Balbi if (err < 0)
93781ef6724SFabio Baltieri return err;
93894ae9843SFelipe Balbi
93994ae9843SFelipe Balbi err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2);
94094ae9843SFelipe Balbi if (err) {
94194ae9843SFelipe Balbi dev_err(&pdev->dev, "Can't register transceiver\n");
94281ef6724SFabio Baltieri return err;
94394ae9843SFelipe Balbi }
94494ae9843SFelipe Balbi
94516604a3cSFabio Baltieri if (is_ab8500(ab->ab8500) && !is_ab8500_2p0_or_earlier(ab->ab8500))
946a96afc6bSFabio Baltieri /* Phy tuning values for AB8500 > v2.0 */
94716604a3cSFabio Baltieri ab8500_usb_set_ab8500_tuning_values(ab);
94816604a3cSFabio Baltieri else if (is_ab8505(ab->ab8500))
9497124631aSSakethram Bommisetti /* Phy tuning values for AB8505 */
95016604a3cSFabio Baltieri ab8500_usb_set_ab8505_tuning_values(ab);
9517124631aSSakethram Bommisetti
952af6882beSFabio Baltieri /* Needed to enable ID detection. */
953af6882beSFabio Baltieri ab8500_usb_wd_workaround(ab);
954af6882beSFabio Baltieri
955fb21f37aSSakethram Bommisetti /*
956fb21f37aSSakethram Bommisetti * This is required for usb-link-status to work properly when a
957fb21f37aSSakethram Bommisetti * cable is connected at boot time.
958fb21f37aSSakethram Bommisetti */
959fb21f37aSSakethram Bommisetti ab8500_usb_restart_phy(ab);
960fb21f37aSSakethram Bommisetti
9618db12231SSakethram Bommisetti abx500_usb_link_status_update(ab);
9628db12231SSakethram Bommisetti
96373f226cbSFabio Baltieri dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", rev);
96494ae9843SFelipe Balbi
96594ae9843SFelipe Balbi return 0;
96694ae9843SFelipe Balbi }
96794ae9843SFelipe Balbi
ab8500_usb_remove(struct platform_device * pdev)968*fe70f2c8SUwe Kleine-König static void ab8500_usb_remove(struct platform_device *pdev)
96994ae9843SFelipe Balbi {
97094ae9843SFelipe Balbi struct ab8500_usb *ab = platform_get_drvdata(pdev);
97194ae9843SFelipe Balbi
97294ae9843SFelipe Balbi cancel_work_sync(&ab->phy_dis_work);
97394ae9843SFelipe Balbi
97494ae9843SFelipe Balbi usb_remove_phy(&ab->phy);
97594ae9843SFelipe Balbi
976f5ef7b42SMian Yousaf Kaukab if (ab->mode == USB_HOST)
97794ae9843SFelipe Balbi ab8500_usb_host_phy_dis(ab);
978f5ef7b42SMian Yousaf Kaukab else if (ab->mode == USB_PERIPHERAL)
97994ae9843SFelipe Balbi ab8500_usb_peri_phy_dis(ab);
98094ae9843SFelipe Balbi }
98194ae9843SFelipe Balbi
9821cb39e25SKrzysztof Kozlowski static const struct platform_device_id ab8500_usb_devtype[] = {
983b3affc39SFabio Baltieri { .name = "ab8500-usb", },
984b3affc39SFabio Baltieri { /* sentinel */ }
985b3affc39SFabio Baltieri };
986b3affc39SFabio Baltieri MODULE_DEVICE_TABLE(platform, ab8500_usb_devtype);
987b3affc39SFabio Baltieri
98894ae9843SFelipe Balbi static struct platform_driver ab8500_usb_driver = {
98994ae9843SFelipe Balbi .probe = ab8500_usb_probe,
990*fe70f2c8SUwe Kleine-König .remove_new = ab8500_usb_remove,
991b3affc39SFabio Baltieri .id_table = ab8500_usb_devtype,
99294ae9843SFelipe Balbi .driver = {
993b3affc39SFabio Baltieri .name = "abx5x0-usb",
99494ae9843SFelipe Balbi },
99594ae9843SFelipe Balbi };
99694ae9843SFelipe Balbi
ab8500_usb_init(void)99794ae9843SFelipe Balbi static int __init ab8500_usb_init(void)
99894ae9843SFelipe Balbi {
99994ae9843SFelipe Balbi return platform_driver_register(&ab8500_usb_driver);
100094ae9843SFelipe Balbi }
100194ae9843SFelipe Balbi subsys_initcall(ab8500_usb_init);
100294ae9843SFelipe Balbi
ab8500_usb_exit(void)100394ae9843SFelipe Balbi static void __exit ab8500_usb_exit(void)
100494ae9843SFelipe Balbi {
100594ae9843SFelipe Balbi platform_driver_unregister(&ab8500_usb_driver);
100694ae9843SFelipe Balbi }
100794ae9843SFelipe Balbi module_exit(ab8500_usb_exit);
100894ae9843SFelipe Balbi
100994ae9843SFelipe Balbi MODULE_AUTHOR("ST-Ericsson AB");
10100c380c0eSFabio Baltieri MODULE_DESCRIPTION("AB8500 family usb transceiver driver");
101194ae9843SFelipe Balbi MODULE_LICENSE("GPL");
1012