1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2012 Freescale Semiconductor, Inc. 4 */ 5 6 #include <linux/module.h> 7 #include <linux/of_platform.h> 8 #include <linux/err.h> 9 #include <linux/io.h> 10 #include <linux/delay.h> 11 #include <linux/usb/otg.h> 12 13 #include "ci_hdrc_imx.h" 14 15 #define MX25_USB_PHY_CTRL_OFFSET 0x08 16 #define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23) 17 18 #define MX25_EHCI_INTERFACE_SINGLE_UNI (2 << 0) 19 #define MX25_EHCI_INTERFACE_DIFF_UNI (0 << 0) 20 #define MX25_EHCI_INTERFACE_MASK (0xf) 21 22 #define MX25_OTG_SIC_SHIFT 29 23 #define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT) 24 #define MX25_OTG_PM_BIT BIT(24) 25 #define MX25_OTG_PP_BIT BIT(11) 26 #define MX25_OTG_OCPOL_BIT BIT(3) 27 28 #define MX25_H1_SIC_SHIFT 21 29 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) 30 #define MX25_H1_PP_BIT BIT(18) 31 #define MX25_H1_PM_BIT BIT(16) 32 #define MX25_H1_IPPUE_UP_BIT BIT(7) 33 #define MX25_H1_IPPUE_DOWN_BIT BIT(6) 34 #define MX25_H1_TLL_BIT BIT(5) 35 #define MX25_H1_USBTE_BIT BIT(4) 36 #define MX25_H1_OCPOL_BIT BIT(2) 37 38 #define MX27_H1_PM_BIT BIT(8) 39 #define MX27_H2_PM_BIT BIT(16) 40 #define MX27_OTG_PM_BIT BIT(24) 41 42 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08 43 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET 0x0c 44 #define MX53_USB_CTRL_1_OFFSET 0x10 45 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2) 46 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2) 47 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6) 48 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6) 49 #define MX53_USB_UH2_CTRL_OFFSET 0x14 50 #define MX53_USB_UH3_CTRL_OFFSET 0x18 51 #define MX53_USB_CLKONOFF_CTRL_OFFSET 0x24 52 #define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21) 53 #define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22) 54 #define MX53_BM_OVER_CUR_DIS_H1 BIT(5) 55 #define MX53_BM_OVER_CUR_DIS_OTG BIT(8) 56 #define MX53_BM_OVER_CUR_DIS_UHx BIT(30) 57 #define MX53_USB_CTRL_1_UH2_ULPI_EN BIT(26) 58 #define MX53_USB_CTRL_1_UH3_ULPI_EN BIT(27) 59 #define MX53_USB_UHx_CTRL_WAKE_UP_EN BIT(7) 60 #define MX53_USB_UHx_CTRL_ULPI_INT_EN BIT(8) 61 #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 62 #define MX53_USB_PLL_DIV_24_MHZ 0x01 63 64 #define MX6_BM_NON_BURST_SETTING BIT(1) 65 #define MX6_BM_OVER_CUR_DIS BIT(7) 66 #define MX6_BM_OVER_CUR_POLARITY BIT(8) 67 #define MX6_BM_PWR_POLARITY BIT(9) 68 #define MX6_BM_WAKEUP_ENABLE BIT(10) 69 #define MX6_BM_UTMI_ON_CLOCK BIT(13) 70 #define MX6_BM_ID_WAKEUP BIT(16) 71 #define MX6_BM_VBUS_WAKEUP BIT(17) 72 #define MX6SX_BM_DPDM_WAKEUP_EN BIT(29) 73 #define MX6_BM_WAKEUP_INTR BIT(31) 74 75 #define MX6_USB_HSIC_CTRL_OFFSET 0x10 76 /* Send resume signal without 480Mhz PHY clock */ 77 #define MX6SX_BM_HSIC_AUTO_RESUME BIT(23) 78 /* set before portsc.suspendM = 1 */ 79 #define MX6_BM_HSIC_DEV_CONN BIT(21) 80 /* HSIC enable */ 81 #define MX6_BM_HSIC_EN BIT(12) 82 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */ 83 #define MX6_BM_HSIC_CLK_ON BIT(11) 84 85 #define MX6_USB_OTG1_PHY_CTRL 0x18 86 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */ 87 #define MX6_USB_OTG2_PHY_CTRL 0x1c 88 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v) (v << 8) 89 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS MX6SX_USB_VBUS_WAKEUP_SOURCE(0) 90 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(1) 91 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(2) 92 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END MX6SX_USB_VBUS_WAKEUP_SOURCE(3) 93 94 #define VF610_OVER_CUR_DIS BIT(7) 95 96 #define MX7D_USBNC_USB_CTRL2 0x4 97 #define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK 0x3 98 #define MX7D_USB_VBUS_WAKEUP_SOURCE(v) (v << 0) 99 #define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS MX7D_USB_VBUS_WAKEUP_SOURCE(0) 100 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1) 101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2) 102 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3) 103 #define MX7D_USBNC_AUTO_RESUME BIT(2) 104 /* The default DM/DP value is pull-down */ 105 #define MX7D_USBNC_USB_CTRL2_OPMODE(v) (v << 6) 106 #define MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING MX7D_USBNC_USB_CTRL2_OPMODE(1) 107 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK (BIT(7) | BIT(6)) 108 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN BIT(8) 109 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_VAL BIT(12) 110 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN BIT(13) 111 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_VAL BIT(14) 112 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN BIT(15) 113 #define MX7D_USBNC_USB_CTRL2_DP_DM_MASK (BIT(12) | BIT(13) | \ 114 BIT(14) | BIT(15)) 115 116 #define MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL BIT(0) 117 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 BIT(1) 118 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 BIT(2) 119 #define MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB BIT(3) 120 #define MX7D_USB_OTG_PHY_CFG2_DRVVBUS0 BIT(16) 121 122 #define MX7D_USB_OTG_PHY_CFG2 0x34 123 124 #define MX7D_USB_OTG_PHY_STATUS 0x3c 125 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE0 BIT(0) 126 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE1 BIT(1) 127 #define MX7D_USB_OTG_PHY_STATUS_VBUS_VLD BIT(3) 128 #define MX7D_USB_OTG_PHY_STATUS_CHRGDET BIT(29) 129 130 #define MX7D_USB_OTG_PHY_CFG1 0x30 131 #define TXPREEMPAMPTUNE0_BIT 28 132 #define TXPREEMPAMPTUNE0_MASK (3 << 28) 133 #define TXVREFTUNE0_BIT 20 134 #define TXVREFTUNE0_MASK (0xf << 20) 135 136 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \ 137 MX6_BM_ID_WAKEUP) 138 139 struct usbmisc_ops { 140 /* It's called once when probe a usb device */ 141 int (*init)(struct imx_usbmisc_data *data); 142 /* It's called once after adding a usb device */ 143 int (*post)(struct imx_usbmisc_data *data); 144 /* It's called when we need to enable/disable usb wakeup */ 145 int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled); 146 /* It's called before setting portsc.suspendM */ 147 int (*hsic_set_connect)(struct imx_usbmisc_data *data); 148 /* It's called during suspend/resume */ 149 int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled); 150 /* usb charger detection */ 151 int (*charger_detection)(struct imx_usbmisc_data *data); 152 /* It's called when system resume from usb power lost */ 153 int (*power_lost_check)(struct imx_usbmisc_data *data); 154 }; 155 156 struct imx_usbmisc { 157 void __iomem *base; 158 spinlock_t lock; 159 const struct usbmisc_ops *ops; 160 }; 161 162 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data); 163 164 static int usbmisc_imx25_init(struct imx_usbmisc_data *data) 165 { 166 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 167 unsigned long flags; 168 u32 val = 0; 169 170 if (data->index > 1) 171 return -EINVAL; 172 173 spin_lock_irqsave(&usbmisc->lock, flags); 174 switch (data->index) { 175 case 0: 176 val = readl(usbmisc->base); 177 val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT); 178 val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT; 179 val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT); 180 181 /* 182 * If the polarity is not configured assume active high for 183 * historical reasons. 184 */ 185 if (data->oc_pol_configured && data->oc_pol_active_low) 186 val &= ~MX25_OTG_OCPOL_BIT; 187 188 writel(val, usbmisc->base); 189 break; 190 case 1: 191 val = readl(usbmisc->base); 192 val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT | MX25_H1_IPPUE_UP_BIT); 193 val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT; 194 val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT | 195 MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT); 196 197 /* 198 * If the polarity is not configured assume active high for 199 * historical reasons. 200 */ 201 if (data->oc_pol_configured && data->oc_pol_active_low) 202 val &= ~MX25_H1_OCPOL_BIT; 203 204 writel(val, usbmisc->base); 205 206 break; 207 } 208 spin_unlock_irqrestore(&usbmisc->lock, flags); 209 210 return 0; 211 } 212 213 static int usbmisc_imx25_post(struct imx_usbmisc_data *data) 214 { 215 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 216 void __iomem *reg; 217 unsigned long flags; 218 u32 val; 219 220 if (data->index > 2) 221 return -EINVAL; 222 223 if (data->index) 224 return 0; 225 226 spin_lock_irqsave(&usbmisc->lock, flags); 227 reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; 228 val = readl(reg); 229 230 if (data->evdo) 231 val |= MX25_BM_EXTERNAL_VBUS_DIVIDER; 232 else 233 val &= ~MX25_BM_EXTERNAL_VBUS_DIVIDER; 234 235 writel(val, reg); 236 spin_unlock_irqrestore(&usbmisc->lock, flags); 237 usleep_range(5000, 10000); /* needed to stabilize voltage */ 238 239 return 0; 240 } 241 242 static int usbmisc_imx27_init(struct imx_usbmisc_data *data) 243 { 244 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 245 unsigned long flags; 246 u32 val; 247 248 switch (data->index) { 249 case 0: 250 val = MX27_OTG_PM_BIT; 251 break; 252 case 1: 253 val = MX27_H1_PM_BIT; 254 break; 255 case 2: 256 val = MX27_H2_PM_BIT; 257 break; 258 default: 259 return -EINVAL; 260 } 261 262 spin_lock_irqsave(&usbmisc->lock, flags); 263 if (data->disable_oc) 264 val = readl(usbmisc->base) | val; 265 else 266 val = readl(usbmisc->base) & ~val; 267 writel(val, usbmisc->base); 268 spin_unlock_irqrestore(&usbmisc->lock, flags); 269 270 return 0; 271 } 272 273 static int usbmisc_imx53_init(struct imx_usbmisc_data *data) 274 { 275 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 276 void __iomem *reg = NULL; 277 unsigned long flags; 278 u32 val = 0; 279 280 if (data->index > 3) 281 return -EINVAL; 282 283 /* Select a 24 MHz reference clock for the PHY */ 284 val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 285 val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK; 286 val |= MX53_USB_PLL_DIV_24_MHZ; 287 writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 288 289 spin_lock_irqsave(&usbmisc->lock, flags); 290 291 switch (data->index) { 292 case 0: 293 if (data->disable_oc) { 294 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 295 val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG; 296 writel(val, reg); 297 } 298 break; 299 case 1: 300 if (data->disable_oc) { 301 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 302 val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1; 303 writel(val, reg); 304 } 305 break; 306 case 2: 307 if (data->ulpi) { 308 /* set USBH2 into ULPI-mode. */ 309 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 310 val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN; 311 /* select ULPI clock */ 312 val &= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK; 313 val |= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI; 314 writel(val, reg); 315 /* Set interrupt wake up enable */ 316 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 317 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 318 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 319 writel(val, reg); 320 if (is_imx53_usbmisc(data)) { 321 /* Disable internal 60Mhz clock */ 322 reg = usbmisc->base + 323 MX53_USB_CLKONOFF_CTRL_OFFSET; 324 val = readl(reg) | 325 MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; 326 writel(val, reg); 327 } 328 329 } 330 if (data->disable_oc) { 331 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 332 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 333 writel(val, reg); 334 } 335 break; 336 case 3: 337 if (data->ulpi) { 338 /* set USBH3 into ULPI-mode. */ 339 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 340 val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN; 341 /* select ULPI clock */ 342 val &= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK; 343 val |= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI; 344 writel(val, reg); 345 /* Set interrupt wake up enable */ 346 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 347 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 348 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 349 writel(val, reg); 350 351 if (is_imx53_usbmisc(data)) { 352 /* Disable internal 60Mhz clock */ 353 reg = usbmisc->base + 354 MX53_USB_CLKONOFF_CTRL_OFFSET; 355 val = readl(reg) | 356 MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; 357 writel(val, reg); 358 } 359 } 360 if (data->disable_oc) { 361 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 362 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 363 writel(val, reg); 364 } 365 break; 366 } 367 368 spin_unlock_irqrestore(&usbmisc->lock, flags); 369 370 return 0; 371 } 372 373 static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data) 374 { 375 u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS; 376 377 if (data->ext_id || data->available_role != USB_DR_MODE_OTG) 378 wakeup_setting &= ~MX6_BM_ID_WAKEUP; 379 380 if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST) 381 wakeup_setting &= ~MX6_BM_VBUS_WAKEUP; 382 383 return wakeup_setting; 384 } 385 386 static int usbmisc_imx6q_set_wakeup 387 (struct imx_usbmisc_data *data, bool enabled) 388 { 389 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 390 unsigned long flags; 391 u32 val; 392 int ret = 0; 393 394 if (data->index > 3) 395 return -EINVAL; 396 397 spin_lock_irqsave(&usbmisc->lock, flags); 398 val = readl(usbmisc->base + data->index * 4); 399 if (enabled) { 400 val &= ~MX6_USB_OTG_WAKEUP_BITS; 401 val |= usbmisc_wakeup_setting(data); 402 } else { 403 if (val & MX6_BM_WAKEUP_INTR) 404 pr_debug("wakeup int at ci_hdrc.%d\n", data->index); 405 val &= ~MX6_USB_OTG_WAKEUP_BITS; 406 } 407 writel(val, usbmisc->base + data->index * 4); 408 spin_unlock_irqrestore(&usbmisc->lock, flags); 409 410 return ret; 411 } 412 413 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) 414 { 415 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 416 unsigned long flags; 417 u32 reg; 418 419 if (data->index > 3) 420 return -EINVAL; 421 422 spin_lock_irqsave(&usbmisc->lock, flags); 423 424 reg = readl(usbmisc->base + data->index * 4); 425 if (data->disable_oc) { 426 reg |= MX6_BM_OVER_CUR_DIS; 427 } else { 428 reg &= ~MX6_BM_OVER_CUR_DIS; 429 430 /* 431 * If the polarity is not configured keep it as setup by the 432 * bootloader. 433 */ 434 if (data->oc_pol_configured && data->oc_pol_active_low) 435 reg |= MX6_BM_OVER_CUR_POLARITY; 436 else if (data->oc_pol_configured) 437 reg &= ~MX6_BM_OVER_CUR_POLARITY; 438 } 439 /* If the polarity is not set keep it as setup by the bootlader */ 440 if (data->pwr_pol == 1) 441 reg |= MX6_BM_PWR_POLARITY; 442 writel(reg, usbmisc->base + data->index * 4); 443 444 /* SoC non-burst setting */ 445 reg = readl(usbmisc->base + data->index * 4); 446 writel(reg | MX6_BM_NON_BURST_SETTING, 447 usbmisc->base + data->index * 4); 448 449 /* For HSIC controller */ 450 if (data->hsic) { 451 reg = readl(usbmisc->base + data->index * 4); 452 writel(reg | MX6_BM_UTMI_ON_CLOCK, 453 usbmisc->base + data->index * 4); 454 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 455 + (data->index - 2) * 4); 456 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 457 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 458 + (data->index - 2) * 4); 459 } 460 461 spin_unlock_irqrestore(&usbmisc->lock, flags); 462 463 usbmisc_imx6q_set_wakeup(data, false); 464 465 return 0; 466 } 467 468 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data *data) 469 { 470 int offset, ret = 0; 471 472 if (data->index == 2 || data->index == 3) { 473 offset = (data->index - 2) * 4; 474 } else if (data->index == 0) { 475 /* 476 * For SoCs like i.MX7D and later, each USB controller has 477 * its own non-core register region. For SoCs before i.MX7D, 478 * the first two USB controllers are non-HSIC controllers. 479 */ 480 offset = 0; 481 } else { 482 dev_err(data->dev, "index is error for usbmisc\n"); 483 ret = -EINVAL; 484 } 485 486 return ret ? ret : offset; 487 } 488 489 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data) 490 { 491 unsigned long flags; 492 u32 val; 493 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 494 int offset; 495 496 spin_lock_irqsave(&usbmisc->lock, flags); 497 offset = usbmisc_imx6_hsic_get_reg_offset(data); 498 if (offset < 0) { 499 spin_unlock_irqrestore(&usbmisc->lock, flags); 500 return offset; 501 } 502 503 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 504 if (!(val & MX6_BM_HSIC_DEV_CONN)) 505 writel(val | MX6_BM_HSIC_DEV_CONN, 506 usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 507 508 spin_unlock_irqrestore(&usbmisc->lock, flags); 509 510 return 0; 511 } 512 513 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on) 514 { 515 unsigned long flags; 516 u32 val; 517 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 518 int offset; 519 520 spin_lock_irqsave(&usbmisc->lock, flags); 521 offset = usbmisc_imx6_hsic_get_reg_offset(data); 522 if (offset < 0) { 523 spin_unlock_irqrestore(&usbmisc->lock, flags); 524 return offset; 525 } 526 527 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 528 val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 529 if (on) 530 val |= MX6_BM_HSIC_CLK_ON; 531 else 532 val &= ~MX6_BM_HSIC_CLK_ON; 533 534 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 535 spin_unlock_irqrestore(&usbmisc->lock, flags); 536 537 return 0; 538 } 539 540 541 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data) 542 { 543 void __iomem *reg = NULL; 544 unsigned long flags; 545 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 546 u32 val; 547 548 usbmisc_imx6q_init(data); 549 550 if (data->index == 0 || data->index == 1) { 551 reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4; 552 spin_lock_irqsave(&usbmisc->lock, flags); 553 /* Set vbus wakeup source as bvalid */ 554 val = readl(reg); 555 writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg); 556 /* 557 * Disable dp/dm wakeup in device mode when vbus is 558 * not there. 559 */ 560 val = readl(usbmisc->base + data->index * 4); 561 writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN, 562 usbmisc->base + data->index * 4); 563 spin_unlock_irqrestore(&usbmisc->lock, flags); 564 } 565 566 /* For HSIC controller */ 567 if (data->hsic) { 568 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 569 val |= MX6SX_BM_HSIC_AUTO_RESUME; 570 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 571 } 572 573 return 0; 574 } 575 576 static int usbmisc_vf610_init(struct imx_usbmisc_data *data) 577 { 578 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 579 u32 reg; 580 581 /* 582 * Vybrid only has one misc register set, but in two different 583 * areas. These is reflected in two instances of this driver. 584 */ 585 if (data->index >= 1) 586 return -EINVAL; 587 588 if (data->disable_oc) { 589 reg = readl(usbmisc->base); 590 writel(reg | VF610_OVER_CUR_DIS, usbmisc->base); 591 } 592 593 return 0; 594 } 595 596 static int usbmisc_imx7d_set_wakeup 597 (struct imx_usbmisc_data *data, bool enabled) 598 { 599 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 600 unsigned long flags; 601 u32 val; 602 603 spin_lock_irqsave(&usbmisc->lock, flags); 604 val = readl(usbmisc->base); 605 if (enabled) { 606 val &= ~MX6_USB_OTG_WAKEUP_BITS; 607 val |= usbmisc_wakeup_setting(data); 608 writel(val, usbmisc->base); 609 } else { 610 if (val & MX6_BM_WAKEUP_INTR) 611 dev_dbg(data->dev, "wakeup int\n"); 612 writel(val & ~MX6_USB_OTG_WAKEUP_BITS, usbmisc->base); 613 } 614 spin_unlock_irqrestore(&usbmisc->lock, flags); 615 616 return 0; 617 } 618 619 static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) 620 { 621 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 622 unsigned long flags; 623 u32 reg; 624 625 if (data->index >= 1) 626 return -EINVAL; 627 628 spin_lock_irqsave(&usbmisc->lock, flags); 629 reg = readl(usbmisc->base); 630 if (data->disable_oc) { 631 reg |= MX6_BM_OVER_CUR_DIS; 632 } else { 633 reg &= ~MX6_BM_OVER_CUR_DIS; 634 635 /* 636 * If the polarity is not configured keep it as setup by the 637 * bootloader. 638 */ 639 if (data->oc_pol_configured && data->oc_pol_active_low) 640 reg |= MX6_BM_OVER_CUR_POLARITY; 641 else if (data->oc_pol_configured) 642 reg &= ~MX6_BM_OVER_CUR_POLARITY; 643 } 644 /* If the polarity is not set keep it as setup by the bootlader */ 645 if (data->pwr_pol == 1) 646 reg |= MX6_BM_PWR_POLARITY; 647 writel(reg, usbmisc->base); 648 649 /* SoC non-burst setting */ 650 reg = readl(usbmisc->base); 651 writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); 652 653 if (!data->hsic) { 654 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 655 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 656 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID 657 | MX7D_USBNC_AUTO_RESUME, 658 usbmisc->base + MX7D_USBNC_USB_CTRL2); 659 /* PHY tuning for signal quality */ 660 reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1); 661 if (data->emp_curr_control && data->emp_curr_control <= 662 (TXPREEMPAMPTUNE0_MASK >> TXPREEMPAMPTUNE0_BIT)) { 663 reg &= ~TXPREEMPAMPTUNE0_MASK; 664 reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT); 665 } 666 667 if (data->dc_vol_level_adjust && data->dc_vol_level_adjust <= 668 (TXVREFTUNE0_MASK >> TXVREFTUNE0_BIT)) { 669 reg &= ~TXVREFTUNE0_MASK; 670 reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT); 671 } 672 673 writel(reg, usbmisc->base + MX7D_USB_OTG_PHY_CFG1); 674 } 675 676 spin_unlock_irqrestore(&usbmisc->lock, flags); 677 678 usbmisc_imx7d_set_wakeup(data, false); 679 680 return 0; 681 } 682 683 static int imx7d_charger_secondary_detection(struct imx_usbmisc_data *data) 684 { 685 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 686 struct usb_phy *usb_phy = data->usb_phy; 687 int val; 688 unsigned long flags; 689 690 /* Clear VDATSRCENB0 to disable VDP_SRC and IDM_SNK required by BC 1.2 spec */ 691 spin_lock_irqsave(&usbmisc->lock, flags); 692 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 693 val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0; 694 writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 695 spin_unlock_irqrestore(&usbmisc->lock, flags); 696 697 /* TVDMSRC_DIS */ 698 msleep(20); 699 700 /* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */ 701 spin_lock_irqsave(&usbmisc->lock, flags); 702 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 703 writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 704 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 | 705 MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL, 706 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 707 spin_unlock_irqrestore(&usbmisc->lock, flags); 708 709 /* TVDMSRC_ON */ 710 msleep(40); 711 712 /* 713 * Per BC 1.2, check voltage of D+: 714 * DCP: if greater than VDAT_REF; 715 * CDP: if less than VDAT_REF. 716 */ 717 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 718 if (val & MX7D_USB_OTG_PHY_STATUS_CHRGDET) { 719 dev_dbg(data->dev, "It is a dedicate charging port\n"); 720 usb_phy->chg_type = DCP_TYPE; 721 } else { 722 dev_dbg(data->dev, "It is a charging downstream port\n"); 723 usb_phy->chg_type = CDP_TYPE; 724 } 725 726 return 0; 727 } 728 729 static void imx7_disable_charger_detector(struct imx_usbmisc_data *data) 730 { 731 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 732 unsigned long flags; 733 u32 val; 734 735 spin_lock_irqsave(&usbmisc->lock, flags); 736 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 737 val &= ~(MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB | 738 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 739 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 | 740 MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL); 741 writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 742 743 /* Set OPMODE to be 2'b00 and disable its override */ 744 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 745 val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 746 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 747 748 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 749 writel(val & ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN, 750 usbmisc->base + MX7D_USBNC_USB_CTRL2); 751 spin_unlock_irqrestore(&usbmisc->lock, flags); 752 } 753 754 static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data *data) 755 { 756 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 757 unsigned long flags; 758 u32 val; 759 int i, data_pin_contact_count = 0; 760 761 /* Enable Data Contact Detect (DCD) per the USB BC 1.2 */ 762 spin_lock_irqsave(&usbmisc->lock, flags); 763 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 764 writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB, 765 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 766 spin_unlock_irqrestore(&usbmisc->lock, flags); 767 768 for (i = 0; i < 100; i = i + 1) { 769 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 770 if (!(val & MX7D_USB_OTG_PHY_STATUS_LINE_STATE0)) { 771 if (data_pin_contact_count++ > 5) 772 /* Data pin makes contact */ 773 break; 774 usleep_range(5000, 10000); 775 } else { 776 data_pin_contact_count = 0; 777 usleep_range(5000, 6000); 778 } 779 } 780 781 /* Disable DCD after finished data contact check */ 782 spin_lock_irqsave(&usbmisc->lock, flags); 783 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 784 writel(val & ~MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB, 785 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 786 spin_unlock_irqrestore(&usbmisc->lock, flags); 787 788 if (i == 100) { 789 dev_err(data->dev, 790 "VBUS is coming from a dedicated power supply.\n"); 791 return -ENXIO; 792 } 793 794 return 0; 795 } 796 797 static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data) 798 { 799 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 800 struct usb_phy *usb_phy = data->usb_phy; 801 unsigned long flags; 802 u32 val; 803 804 /* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */ 805 spin_lock_irqsave(&usbmisc->lock, flags); 806 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 807 val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL; 808 writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 809 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0, 810 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 811 spin_unlock_irqrestore(&usbmisc->lock, flags); 812 813 /* TVDPSRC_ON */ 814 msleep(40); 815 816 /* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */ 817 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 818 if (!(val & MX7D_USB_OTG_PHY_STATUS_CHRGDET)) { 819 dev_dbg(data->dev, "It is a standard downstream port\n"); 820 usb_phy->chg_type = SDP_TYPE; 821 } 822 823 return 0; 824 } 825 826 /* 827 * Whole charger detection process: 828 * 1. OPMODE override to be non-driving 829 * 2. Data contact check 830 * 3. Primary detection 831 * 4. Secondary detection 832 * 5. Disable charger detection 833 */ 834 static int imx7d_charger_detection(struct imx_usbmisc_data *data) 835 { 836 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 837 struct usb_phy *usb_phy = data->usb_phy; 838 unsigned long flags; 839 u32 val; 840 int ret; 841 842 /* Check if vbus is valid */ 843 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 844 if (!(val & MX7D_USB_OTG_PHY_STATUS_VBUS_VLD)) { 845 dev_err(data->dev, "vbus is error\n"); 846 return -EINVAL; 847 } 848 849 /* 850 * Keep OPMODE to be non-driving mode during the whole 851 * charger detection process. 852 */ 853 spin_lock_irqsave(&usbmisc->lock, flags); 854 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 855 val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 856 val |= MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING; 857 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 858 859 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 860 writel(val | MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN, 861 usbmisc->base + MX7D_USBNC_USB_CTRL2); 862 spin_unlock_irqrestore(&usbmisc->lock, flags); 863 864 ret = imx7d_charger_data_contact_detect(data); 865 if (ret) 866 return ret; 867 868 ret = imx7d_charger_primary_detection(data); 869 if (!ret && usb_phy->chg_type != SDP_TYPE) 870 ret = imx7d_charger_secondary_detection(data); 871 872 imx7_disable_charger_detector(data); 873 874 return ret; 875 } 876 877 static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) 878 { 879 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 880 unsigned long flags; 881 u32 reg; 882 883 if (data->index >= 1) 884 return -EINVAL; 885 886 spin_lock_irqsave(&usbmisc->lock, flags); 887 reg = readl(usbmisc->base); 888 if (data->disable_oc) { 889 reg |= MX6_BM_OVER_CUR_DIS; 890 } else { 891 reg &= ~MX6_BM_OVER_CUR_DIS; 892 893 /* 894 * If the polarity is not configured keep it as setup by the 895 * bootloader. 896 */ 897 if (data->oc_pol_configured && data->oc_pol_active_low) 898 reg |= MX6_BM_OVER_CUR_POLARITY; 899 else if (data->oc_pol_configured) 900 reg &= ~MX6_BM_OVER_CUR_POLARITY; 901 } 902 /* If the polarity is not set keep it as setup by the bootlader */ 903 if (data->pwr_pol == 1) 904 reg |= MX6_BM_PWR_POLARITY; 905 906 writel(reg, usbmisc->base); 907 908 /* SoC non-burst setting */ 909 reg = readl(usbmisc->base); 910 writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); 911 912 if (data->hsic) { 913 reg = readl(usbmisc->base); 914 writel(reg | MX6_BM_UTMI_ON_CLOCK, usbmisc->base); 915 916 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 917 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 918 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 919 920 /* 921 * For non-HSIC controller, the autoresume is enabled 922 * at MXS PHY driver (usbphy_ctrl bit18). 923 */ 924 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 925 writel(reg | MX7D_USBNC_AUTO_RESUME, 926 usbmisc->base + MX7D_USBNC_USB_CTRL2); 927 } else { 928 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 929 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 930 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, 931 usbmisc->base + MX7D_USBNC_USB_CTRL2); 932 } 933 934 spin_unlock_irqrestore(&usbmisc->lock, flags); 935 936 usbmisc_imx7d_set_wakeup(data, false); 937 938 return 0; 939 } 940 941 static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data *data) 942 { 943 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 944 unsigned long flags; 945 u32 val; 946 947 spin_lock_irqsave(&usbmisc->lock, flags); 948 val = readl(usbmisc->base); 949 spin_unlock_irqrestore(&usbmisc->lock, flags); 950 /* 951 * Here use a power on reset value to judge 952 * if the controller experienced a power lost 953 */ 954 if (val == 0x30001000) 955 return 1; 956 else 957 return 0; 958 } 959 960 static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data) 961 { 962 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 963 unsigned long flags; 964 u32 val; 965 966 spin_lock_irqsave(&usbmisc->lock, flags); 967 val = readl(usbmisc->base + data->index * 4); 968 spin_unlock_irqrestore(&usbmisc->lock, flags); 969 /* 970 * Here use a power on reset value to judge 971 * if the controller experienced a power lost 972 */ 973 if (val == 0x30001000) 974 return 1; 975 else 976 return 0; 977 } 978 979 static const struct usbmisc_ops imx25_usbmisc_ops = { 980 .init = usbmisc_imx25_init, 981 .post = usbmisc_imx25_post, 982 }; 983 984 static const struct usbmisc_ops imx27_usbmisc_ops = { 985 .init = usbmisc_imx27_init, 986 }; 987 988 static const struct usbmisc_ops imx51_usbmisc_ops = { 989 .init = usbmisc_imx53_init, 990 }; 991 992 static const struct usbmisc_ops imx53_usbmisc_ops = { 993 .init = usbmisc_imx53_init, 994 }; 995 996 static const struct usbmisc_ops imx6q_usbmisc_ops = { 997 .set_wakeup = usbmisc_imx6q_set_wakeup, 998 .init = usbmisc_imx6q_init, 999 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 1000 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 1001 }; 1002 1003 static const struct usbmisc_ops vf610_usbmisc_ops = { 1004 .init = usbmisc_vf610_init, 1005 }; 1006 1007 static const struct usbmisc_ops imx6sx_usbmisc_ops = { 1008 .set_wakeup = usbmisc_imx6q_set_wakeup, 1009 .init = usbmisc_imx6sx_init, 1010 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 1011 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 1012 .power_lost_check = usbmisc_imx6sx_power_lost_check, 1013 }; 1014 1015 static const struct usbmisc_ops imx7d_usbmisc_ops = { 1016 .init = usbmisc_imx7d_init, 1017 .set_wakeup = usbmisc_imx7d_set_wakeup, 1018 .charger_detection = imx7d_charger_detection, 1019 .power_lost_check = usbmisc_imx7d_power_lost_check, 1020 }; 1021 1022 static const struct usbmisc_ops imx7ulp_usbmisc_ops = { 1023 .init = usbmisc_imx7ulp_init, 1024 .set_wakeup = usbmisc_imx7d_set_wakeup, 1025 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 1026 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 1027 .power_lost_check = usbmisc_imx7d_power_lost_check, 1028 }; 1029 1030 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) 1031 { 1032 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 1033 1034 return usbmisc->ops == &imx53_usbmisc_ops; 1035 } 1036 1037 int imx_usbmisc_init(struct imx_usbmisc_data *data) 1038 { 1039 struct imx_usbmisc *usbmisc; 1040 1041 if (!data) 1042 return 0; 1043 1044 usbmisc = dev_get_drvdata(data->dev); 1045 if (!usbmisc->ops->init) 1046 return 0; 1047 return usbmisc->ops->init(data); 1048 } 1049 EXPORT_SYMBOL_GPL(imx_usbmisc_init); 1050 1051 int imx_usbmisc_init_post(struct imx_usbmisc_data *data) 1052 { 1053 struct imx_usbmisc *usbmisc; 1054 int ret = 0; 1055 1056 if (!data) 1057 return 0; 1058 1059 usbmisc = dev_get_drvdata(data->dev); 1060 if (usbmisc->ops->post) 1061 ret = usbmisc->ops->post(data); 1062 if (ret) { 1063 dev_err(data->dev, "post init failed, ret=%d\n", ret); 1064 return ret; 1065 } 1066 1067 if (usbmisc->ops->set_wakeup) 1068 ret = usbmisc->ops->set_wakeup(data, false); 1069 if (ret) { 1070 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1071 return ret; 1072 } 1073 1074 return 0; 1075 } 1076 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post); 1077 1078 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data) 1079 { 1080 struct imx_usbmisc *usbmisc; 1081 1082 if (!data) 1083 return 0; 1084 1085 usbmisc = dev_get_drvdata(data->dev); 1086 if (!usbmisc->ops->hsic_set_connect || !data->hsic) 1087 return 0; 1088 return usbmisc->ops->hsic_set_connect(data); 1089 } 1090 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect); 1091 1092 int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect) 1093 { 1094 struct imx_usbmisc *usbmisc; 1095 struct usb_phy *usb_phy; 1096 int ret = 0; 1097 1098 if (!data) 1099 return -EINVAL; 1100 1101 usbmisc = dev_get_drvdata(data->dev); 1102 usb_phy = data->usb_phy; 1103 if (!usbmisc->ops->charger_detection) 1104 return -ENOTSUPP; 1105 1106 if (connect) { 1107 ret = usbmisc->ops->charger_detection(data); 1108 if (ret) { 1109 dev_err(data->dev, 1110 "Error occurs during detection: %d\n", 1111 ret); 1112 usb_phy->chg_state = USB_CHARGER_ABSENT; 1113 } else { 1114 usb_phy->chg_state = USB_CHARGER_PRESENT; 1115 } 1116 } else { 1117 usb_phy->chg_state = USB_CHARGER_ABSENT; 1118 usb_phy->chg_type = UNKNOWN_TYPE; 1119 } 1120 return ret; 1121 } 1122 EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection); 1123 1124 int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup) 1125 { 1126 struct imx_usbmisc *usbmisc; 1127 int ret = 0; 1128 1129 if (!data) 1130 return 0; 1131 1132 usbmisc = dev_get_drvdata(data->dev); 1133 1134 if (wakeup && usbmisc->ops->set_wakeup) 1135 ret = usbmisc->ops->set_wakeup(data, true); 1136 if (ret) { 1137 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1138 return ret; 1139 } 1140 1141 if (usbmisc->ops->hsic_set_clk && data->hsic) 1142 ret = usbmisc->ops->hsic_set_clk(data, false); 1143 if (ret) { 1144 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1145 return ret; 1146 } 1147 1148 return ret; 1149 } 1150 EXPORT_SYMBOL_GPL(imx_usbmisc_suspend); 1151 1152 int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup) 1153 { 1154 struct imx_usbmisc *usbmisc; 1155 int ret = 0; 1156 1157 if (!data) 1158 return 0; 1159 1160 usbmisc = dev_get_drvdata(data->dev); 1161 1162 if (usbmisc->ops->power_lost_check) 1163 ret = usbmisc->ops->power_lost_check(data); 1164 if (ret > 0) { 1165 /* re-init if resume from power lost */ 1166 ret = imx_usbmisc_init(data); 1167 if (ret) { 1168 dev_err(data->dev, "re-init failed, ret=%d\n", ret); 1169 return ret; 1170 } 1171 } 1172 1173 if (wakeup && usbmisc->ops->set_wakeup) 1174 ret = usbmisc->ops->set_wakeup(data, false); 1175 if (ret) { 1176 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1177 return ret; 1178 } 1179 1180 if (usbmisc->ops->hsic_set_clk && data->hsic) 1181 ret = usbmisc->ops->hsic_set_clk(data, true); 1182 if (ret) { 1183 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1184 goto hsic_set_clk_fail; 1185 } 1186 1187 return 0; 1188 1189 hsic_set_clk_fail: 1190 if (wakeup && usbmisc->ops->set_wakeup) 1191 usbmisc->ops->set_wakeup(data, true); 1192 return ret; 1193 } 1194 EXPORT_SYMBOL_GPL(imx_usbmisc_resume); 1195 1196 static const struct of_device_id usbmisc_imx_dt_ids[] = { 1197 { 1198 .compatible = "fsl,imx25-usbmisc", 1199 .data = &imx25_usbmisc_ops, 1200 }, 1201 { 1202 .compatible = "fsl,imx35-usbmisc", 1203 .data = &imx25_usbmisc_ops, 1204 }, 1205 { 1206 .compatible = "fsl,imx27-usbmisc", 1207 .data = &imx27_usbmisc_ops, 1208 }, 1209 { 1210 .compatible = "fsl,imx51-usbmisc", 1211 .data = &imx51_usbmisc_ops, 1212 }, 1213 { 1214 .compatible = "fsl,imx53-usbmisc", 1215 .data = &imx53_usbmisc_ops, 1216 }, 1217 { 1218 .compatible = "fsl,imx6q-usbmisc", 1219 .data = &imx6q_usbmisc_ops, 1220 }, 1221 { 1222 .compatible = "fsl,vf610-usbmisc", 1223 .data = &vf610_usbmisc_ops, 1224 }, 1225 { 1226 .compatible = "fsl,imx6sx-usbmisc", 1227 .data = &imx6sx_usbmisc_ops, 1228 }, 1229 { 1230 .compatible = "fsl,imx6ul-usbmisc", 1231 .data = &imx6sx_usbmisc_ops, 1232 }, 1233 { 1234 .compatible = "fsl,imx7d-usbmisc", 1235 .data = &imx7d_usbmisc_ops, 1236 }, 1237 { 1238 .compatible = "fsl,imx7ulp-usbmisc", 1239 .data = &imx7ulp_usbmisc_ops, 1240 }, 1241 { /* sentinel */ } 1242 }; 1243 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); 1244 1245 static int usbmisc_imx_probe(struct platform_device *pdev) 1246 { 1247 struct imx_usbmisc *data; 1248 1249 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 1250 if (!data) 1251 return -ENOMEM; 1252 1253 spin_lock_init(&data->lock); 1254 1255 data->base = devm_platform_ioremap_resource(pdev, 0); 1256 if (IS_ERR(data->base)) 1257 return PTR_ERR(data->base); 1258 1259 data->ops = of_device_get_match_data(&pdev->dev); 1260 platform_set_drvdata(pdev, data); 1261 1262 return 0; 1263 } 1264 1265 static struct platform_driver usbmisc_imx_driver = { 1266 .probe = usbmisc_imx_probe, 1267 .driver = { 1268 .name = "usbmisc_imx", 1269 .of_match_table = usbmisc_imx_dt_ids, 1270 }, 1271 }; 1272 1273 module_platform_driver(usbmisc_imx_driver); 1274 1275 MODULE_ALIAS("platform:usbmisc-imx"); 1276 MODULE_LICENSE("GPL"); 1277 MODULE_DESCRIPTION("driver for imx usb non-core registers"); 1278 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>"); 1279