1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
6 #include <linux/bitops.h>
8 #include <linux/interrupt.h>
10 #include <linux/iopoll.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/slab.h>
16 #include <linux/sysfs.h>
17 #include <linux/usb/role.h>
19 #define EUD_REG_INT1_EN_MASK 0x0024
20 #define EUD_REG_INT_STATUS_1 0x0044
21 #define EUD_REG_CTL_OUT_1 0x0074
22 #define EUD_REG_VBUS_INT_CLR 0x0080
23 #define EUD_REG_CSR_EUD_EN 0x1014
24 #define EUD_REG_SW_ATTACH_DET 0x1018
25 #define EUD_REG_EUD_EN2 0x0000
27 #define EUD_ENABLE BIT(0)
28 #define EUD_INT_PET_EUD BIT(0)
29 #define EUD_INT_VBUS BIT(2)
30 #define EUD_INT_SAFE_MODE BIT(4)
31 #define EUD_INT_ALL (EUD_INT_VBUS | EUD_INT_SAFE_MODE)
35 struct usb_role_switch
*role_sw
;
37 void __iomem
*mode_mgr
;
38 unsigned int int_status
;
44 static int enable_eud(struct eud_chip
*priv
)
46 writel(EUD_ENABLE
, priv
->base
+ EUD_REG_CSR_EUD_EN
);
47 writel(EUD_INT_VBUS
| EUD_INT_SAFE_MODE
,
48 priv
->base
+ EUD_REG_INT1_EN_MASK
);
49 writel(1, priv
->mode_mgr
+ EUD_REG_EUD_EN2
);
51 return usb_role_switch_set_role(priv
->role_sw
, USB_ROLE_DEVICE
);
54 static void disable_eud(struct eud_chip
*priv
)
56 writel(0, priv
->base
+ EUD_REG_CSR_EUD_EN
);
57 writel(0, priv
->mode_mgr
+ EUD_REG_EUD_EN2
);
60 static ssize_t
enable_show(struct device
*dev
,
61 struct device_attribute
*attr
, char *buf
)
63 struct eud_chip
*chip
= dev_get_drvdata(dev
);
65 return sysfs_emit(buf
, "%d\n", chip
->enabled
);
68 static ssize_t
enable_store(struct device
*dev
,
69 struct device_attribute
*attr
,
70 const char *buf
, size_t count
)
72 struct eud_chip
*chip
= dev_get_drvdata(dev
);
76 if (kstrtobool(buf
, &enable
))
80 ret
= enable_eud(chip
);
82 chip
->enabled
= enable
;
92 static DEVICE_ATTR_RW(enable
);
94 static struct attribute
*eud_attrs
[] = {
95 &dev_attr_enable
.attr
,
98 ATTRIBUTE_GROUPS(eud
);
100 static void usb_attach_detach(struct eud_chip
*chip
)
104 /* read ctl_out_1[4] to find USB attach or detach event */
105 reg
= readl(chip
->base
+ EUD_REG_CTL_OUT_1
);
106 chip
->usb_attached
= reg
& EUD_INT_SAFE_MODE
;
109 static void pet_eud(struct eud_chip
*chip
)
114 /* When the EUD_INT_PET_EUD in SW_ATTACH_DET is set, the cable has been
115 * disconnected and we need to detach the pet to check if EUD is in safe
116 * mode before attaching again.
118 reg
= readl(chip
->base
+ EUD_REG_SW_ATTACH_DET
);
119 if (reg
& EUD_INT_PET_EUD
) {
120 /* Detach & Attach pet for EUD */
121 writel(0, chip
->base
+ EUD_REG_SW_ATTACH_DET
);
122 /* Delay to make sure detach pet is done before attach pet */
123 ret
= readl_poll_timeout(chip
->base
+ EUD_REG_SW_ATTACH_DET
,
124 reg
, (reg
== 0), 1, 100);
126 dev_err(chip
->dev
, "Detach pet failed\n");
130 /* Attach pet for EUD */
131 writel(EUD_INT_PET_EUD
, chip
->base
+ EUD_REG_SW_ATTACH_DET
);
134 static irqreturn_t
handle_eud_irq(int irq
, void *data
)
136 struct eud_chip
*chip
= data
;
139 reg
= readl(chip
->base
+ EUD_REG_INT_STATUS_1
);
140 switch (reg
& EUD_INT_ALL
) {
142 usb_attach_detach(chip
);
143 return IRQ_WAKE_THREAD
;
144 case EUD_INT_SAFE_MODE
:
152 static irqreturn_t
handle_eud_irq_thread(int irq
, void *data
)
154 struct eud_chip
*chip
= data
;
157 if (chip
->usb_attached
)
158 ret
= usb_role_switch_set_role(chip
->role_sw
, USB_ROLE_DEVICE
);
160 ret
= usb_role_switch_set_role(chip
->role_sw
, USB_ROLE_HOST
);
162 dev_err(chip
->dev
, "failed to set role switch\n");
164 /* set and clear vbus_int_clr[0] to clear interrupt */
165 writel(BIT(0), chip
->base
+ EUD_REG_VBUS_INT_CLR
);
166 writel(0, chip
->base
+ EUD_REG_VBUS_INT_CLR
);
171 static void eud_role_switch_release(void *data
)
173 struct eud_chip
*chip
= data
;
175 usb_role_switch_put(chip
->role_sw
);
178 static int eud_probe(struct platform_device
*pdev
)
180 struct eud_chip
*chip
;
183 chip
= devm_kzalloc(&pdev
->dev
, sizeof(*chip
), GFP_KERNEL
);
187 chip
->dev
= &pdev
->dev
;
189 chip
->role_sw
= usb_role_switch_get(&pdev
->dev
);
190 if (IS_ERR(chip
->role_sw
))
191 return dev_err_probe(chip
->dev
, PTR_ERR(chip
->role_sw
),
192 "failed to get role switch\n");
194 ret
= devm_add_action_or_reset(chip
->dev
, eud_role_switch_release
, chip
);
196 return dev_err_probe(chip
->dev
, ret
,
197 "failed to add role switch release action\n");
199 chip
->base
= devm_platform_ioremap_resource(pdev
, 0);
200 if (IS_ERR(chip
->base
))
201 return PTR_ERR(chip
->base
);
203 chip
->mode_mgr
= devm_platform_ioremap_resource(pdev
, 1);
204 if (IS_ERR(chip
->mode_mgr
))
205 return PTR_ERR(chip
->mode_mgr
);
207 chip
->irq
= platform_get_irq(pdev
, 0);
211 ret
= devm_request_threaded_irq(&pdev
->dev
, chip
->irq
, handle_eud_irq
,
212 handle_eud_irq_thread
, IRQF_ONESHOT
, NULL
, chip
);
214 return dev_err_probe(chip
->dev
, ret
, "failed to allocate irq\n");
216 enable_irq_wake(chip
->irq
);
218 platform_set_drvdata(pdev
, chip
);
223 static void eud_remove(struct platform_device
*pdev
)
225 struct eud_chip
*chip
= platform_get_drvdata(pdev
);
230 device_init_wakeup(&pdev
->dev
, false);
231 disable_irq_wake(chip
->irq
);
234 static const struct of_device_id eud_dt_match
[] = {
235 { .compatible
= "qcom,eud" },
238 MODULE_DEVICE_TABLE(of
, eud_dt_match
);
240 static struct platform_driver eud_driver
= {
242 .remove
= eud_remove
,
245 .dev_groups
= eud_groups
,
246 .of_match_table
= eud_dt_match
,
249 module_platform_driver(eud_driver
);
251 MODULE_DESCRIPTION("QTI EUD driver");
252 MODULE_LICENSE("GPL v2");