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