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 12 #include "ci_hdrc_imx.h" 13 14 #define MX25_USB_PHY_CTRL_OFFSET 0x08 15 #define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23) 16 17 #define MX25_EHCI_INTERFACE_SINGLE_UNI (2 << 0) 18 #define MX25_EHCI_INTERFACE_DIFF_UNI (0 << 0) 19 #define MX25_EHCI_INTERFACE_MASK (0xf) 20 21 #define MX25_OTG_SIC_SHIFT 29 22 #define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT) 23 #define MX25_OTG_PM_BIT BIT(24) 24 #define MX25_OTG_PP_BIT BIT(11) 25 #define MX25_OTG_OCPOL_BIT BIT(3) 26 27 #define MX25_H1_SIC_SHIFT 21 28 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) 29 #define MX25_H1_PP_BIT BIT(18) 30 #define MX25_H1_PM_BIT BIT(16) 31 #define MX25_H1_IPPUE_UP_BIT BIT(7) 32 #define MX25_H1_IPPUE_DOWN_BIT BIT(6) 33 #define MX25_H1_TLL_BIT BIT(5) 34 #define MX25_H1_USBTE_BIT BIT(4) 35 #define MX25_H1_OCPOL_BIT BIT(2) 36 37 #define MX27_H1_PM_BIT BIT(8) 38 #define MX27_H2_PM_BIT BIT(16) 39 #define MX27_OTG_PM_BIT BIT(24) 40 41 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08 42 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET 0x0c 43 #define MX53_USB_CTRL_1_OFFSET 0x10 44 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2) 45 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2) 46 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6) 47 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6) 48 #define MX53_USB_UH2_CTRL_OFFSET 0x14 49 #define MX53_USB_UH3_CTRL_OFFSET 0x18 50 #define MX53_USB_CLKONOFF_CTRL_OFFSET 0x24 51 #define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21) 52 #define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22) 53 #define MX53_BM_OVER_CUR_DIS_H1 BIT(5) 54 #define MX53_BM_OVER_CUR_DIS_OTG BIT(8) 55 #define MX53_BM_OVER_CUR_DIS_UHx BIT(30) 56 #define MX53_USB_CTRL_1_UH2_ULPI_EN BIT(26) 57 #define MX53_USB_CTRL_1_UH3_ULPI_EN BIT(27) 58 #define MX53_USB_UHx_CTRL_WAKE_UP_EN BIT(7) 59 #define MX53_USB_UHx_CTRL_ULPI_INT_EN BIT(8) 60 #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 61 #define MX53_USB_PLL_DIV_24_MHZ 0x01 62 63 #define MX6_BM_NON_BURST_SETTING BIT(1) 64 #define MX6_BM_OVER_CUR_DIS BIT(7) 65 #define MX6_BM_OVER_CUR_POLARITY BIT(8) 66 #define MX6_BM_PWR_POLARITY BIT(9) 67 #define MX6_BM_WAKEUP_ENABLE BIT(10) 68 #define MX6_BM_UTMI_ON_CLOCK BIT(13) 69 #define MX6_BM_ID_WAKEUP BIT(16) 70 #define MX6_BM_VBUS_WAKEUP BIT(17) 71 #define MX6SX_BM_DPDM_WAKEUP_EN BIT(29) 72 #define MX6_BM_WAKEUP_INTR BIT(31) 73 74 #define MX6_USB_HSIC_CTRL_OFFSET 0x10 75 /* Send resume signal without 480Mhz PHY clock */ 76 #define MX6SX_BM_HSIC_AUTO_RESUME BIT(23) 77 /* set before portsc.suspendM = 1 */ 78 #define MX6_BM_HSIC_DEV_CONN BIT(21) 79 /* HSIC enable */ 80 #define MX6_BM_HSIC_EN BIT(12) 81 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */ 82 #define MX6_BM_HSIC_CLK_ON BIT(11) 83 84 #define MX6_USB_OTG1_PHY_CTRL 0x18 85 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */ 86 #define MX6_USB_OTG2_PHY_CTRL 0x1c 87 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v) (v << 8) 88 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS MX6SX_USB_VBUS_WAKEUP_SOURCE(0) 89 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(1) 90 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(2) 91 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END MX6SX_USB_VBUS_WAKEUP_SOURCE(3) 92 93 #define VF610_OVER_CUR_DIS BIT(7) 94 95 #define MX7D_USBNC_USB_CTRL2 0x4 96 #define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK 0x3 97 #define MX7D_USB_VBUS_WAKEUP_SOURCE(v) (v << 0) 98 #define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS MX7D_USB_VBUS_WAKEUP_SOURCE(0) 99 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1) 100 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2) 101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3) 102 103 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \ 104 MX6_BM_ID_WAKEUP) 105 106 struct usbmisc_ops { 107 /* It's called once when probe a usb device */ 108 int (*init)(struct imx_usbmisc_data *data); 109 /* It's called once after adding a usb device */ 110 int (*post)(struct imx_usbmisc_data *data); 111 /* It's called when we need to enable/disable usb wakeup */ 112 int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled); 113 /* It's called before setting portsc.suspendM */ 114 int (*hsic_set_connect)(struct imx_usbmisc_data *data); 115 /* It's called during suspend/resume */ 116 int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled); 117 }; 118 119 struct imx_usbmisc { 120 void __iomem *base; 121 spinlock_t lock; 122 const struct usbmisc_ops *ops; 123 }; 124 125 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data); 126 127 static int usbmisc_imx25_init(struct imx_usbmisc_data *data) 128 { 129 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 130 unsigned long flags; 131 u32 val = 0; 132 133 if (data->index > 1) 134 return -EINVAL; 135 136 spin_lock_irqsave(&usbmisc->lock, flags); 137 switch (data->index) { 138 case 0: 139 val = readl(usbmisc->base); 140 val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT); 141 val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT; 142 val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT); 143 144 /* 145 * If the polarity is not configured assume active high for 146 * historical reasons. 147 */ 148 if (data->oc_pol_configured && data->oc_pol_active_low) 149 val &= ~MX25_OTG_OCPOL_BIT; 150 151 writel(val, usbmisc->base); 152 break; 153 case 1: 154 val = readl(usbmisc->base); 155 val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT | MX25_H1_IPPUE_UP_BIT); 156 val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT; 157 val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT | 158 MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT); 159 160 /* 161 * If the polarity is not configured assume active high for 162 * historical reasons. 163 */ 164 if (data->oc_pol_configured && data->oc_pol_active_low) 165 val &= ~MX25_H1_OCPOL_BIT; 166 167 writel(val, usbmisc->base); 168 169 break; 170 } 171 spin_unlock_irqrestore(&usbmisc->lock, flags); 172 173 return 0; 174 } 175 176 static int usbmisc_imx25_post(struct imx_usbmisc_data *data) 177 { 178 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 179 void __iomem *reg; 180 unsigned long flags; 181 u32 val; 182 183 if (data->index > 2) 184 return -EINVAL; 185 186 if (data->index) 187 return 0; 188 189 spin_lock_irqsave(&usbmisc->lock, flags); 190 reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; 191 val = readl(reg); 192 193 if (data->evdo) 194 val |= MX25_BM_EXTERNAL_VBUS_DIVIDER; 195 else 196 val &= ~MX25_BM_EXTERNAL_VBUS_DIVIDER; 197 198 writel(val, reg); 199 spin_unlock_irqrestore(&usbmisc->lock, flags); 200 usleep_range(5000, 10000); /* needed to stabilize voltage */ 201 202 return 0; 203 } 204 205 static int usbmisc_imx27_init(struct imx_usbmisc_data *data) 206 { 207 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 208 unsigned long flags; 209 u32 val; 210 211 switch (data->index) { 212 case 0: 213 val = MX27_OTG_PM_BIT; 214 break; 215 case 1: 216 val = MX27_H1_PM_BIT; 217 break; 218 case 2: 219 val = MX27_H2_PM_BIT; 220 break; 221 default: 222 return -EINVAL; 223 } 224 225 spin_lock_irqsave(&usbmisc->lock, flags); 226 if (data->disable_oc) 227 val = readl(usbmisc->base) | val; 228 else 229 val = readl(usbmisc->base) & ~val; 230 writel(val, usbmisc->base); 231 spin_unlock_irqrestore(&usbmisc->lock, flags); 232 233 return 0; 234 } 235 236 static int usbmisc_imx53_init(struct imx_usbmisc_data *data) 237 { 238 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 239 void __iomem *reg = NULL; 240 unsigned long flags; 241 u32 val = 0; 242 243 if (data->index > 3) 244 return -EINVAL; 245 246 /* Select a 24 MHz reference clock for the PHY */ 247 val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 248 val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK; 249 val |= MX53_USB_PLL_DIV_24_MHZ; 250 writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 251 252 spin_lock_irqsave(&usbmisc->lock, flags); 253 254 switch (data->index) { 255 case 0: 256 if (data->disable_oc) { 257 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 258 val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG; 259 writel(val, reg); 260 } 261 break; 262 case 1: 263 if (data->disable_oc) { 264 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 265 val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1; 266 writel(val, reg); 267 } 268 break; 269 case 2: 270 if (data->ulpi) { 271 /* set USBH2 into ULPI-mode. */ 272 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 273 val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN; 274 /* select ULPI clock */ 275 val &= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK; 276 val |= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI; 277 writel(val, reg); 278 /* Set interrupt wake up enable */ 279 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 280 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 281 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 282 writel(val, reg); 283 if (is_imx53_usbmisc(data)) { 284 /* Disable internal 60Mhz clock */ 285 reg = usbmisc->base + 286 MX53_USB_CLKONOFF_CTRL_OFFSET; 287 val = readl(reg) | 288 MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; 289 writel(val, reg); 290 } 291 292 } 293 if (data->disable_oc) { 294 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 295 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 296 writel(val, reg); 297 } 298 break; 299 case 3: 300 if (data->ulpi) { 301 /* set USBH3 into ULPI-mode. */ 302 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 303 val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN; 304 /* select ULPI clock */ 305 val &= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK; 306 val |= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI; 307 writel(val, reg); 308 /* Set interrupt wake up enable */ 309 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 310 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 311 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 312 writel(val, reg); 313 314 if (is_imx53_usbmisc(data)) { 315 /* Disable internal 60Mhz clock */ 316 reg = usbmisc->base + 317 MX53_USB_CLKONOFF_CTRL_OFFSET; 318 val = readl(reg) | 319 MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; 320 writel(val, reg); 321 } 322 } 323 if (data->disable_oc) { 324 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 325 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 326 writel(val, reg); 327 } 328 break; 329 } 330 331 spin_unlock_irqrestore(&usbmisc->lock, flags); 332 333 return 0; 334 } 335 336 static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data) 337 { 338 u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS; 339 340 if (data->ext_id) 341 wakeup_setting &= ~MX6_BM_ID_WAKEUP; 342 343 if (data->ext_vbus) 344 wakeup_setting &= ~MX6_BM_VBUS_WAKEUP; 345 346 return wakeup_setting; 347 } 348 349 static int usbmisc_imx6q_set_wakeup 350 (struct imx_usbmisc_data *data, bool enabled) 351 { 352 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 353 unsigned long flags; 354 u32 val; 355 int ret = 0; 356 357 if (data->index > 3) 358 return -EINVAL; 359 360 spin_lock_irqsave(&usbmisc->lock, flags); 361 val = readl(usbmisc->base + data->index * 4); 362 if (enabled) { 363 val &= ~MX6_USB_OTG_WAKEUP_BITS; 364 val |= usbmisc_wakeup_setting(data); 365 } else { 366 if (val & MX6_BM_WAKEUP_INTR) 367 pr_debug("wakeup int at ci_hdrc.%d\n", data->index); 368 val &= ~MX6_USB_OTG_WAKEUP_BITS; 369 } 370 writel(val, usbmisc->base + data->index * 4); 371 spin_unlock_irqrestore(&usbmisc->lock, flags); 372 373 return ret; 374 } 375 376 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) 377 { 378 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 379 unsigned long flags; 380 u32 reg; 381 382 if (data->index > 3) 383 return -EINVAL; 384 385 spin_lock_irqsave(&usbmisc->lock, flags); 386 387 reg = readl(usbmisc->base + data->index * 4); 388 if (data->disable_oc) { 389 reg |= MX6_BM_OVER_CUR_DIS; 390 } else { 391 reg &= ~MX6_BM_OVER_CUR_DIS; 392 393 /* 394 * If the polarity is not configured keep it as setup by the 395 * bootloader. 396 */ 397 if (data->oc_pol_configured && data->oc_pol_active_low) 398 reg |= MX6_BM_OVER_CUR_POLARITY; 399 else if (data->oc_pol_configured) 400 reg &= ~MX6_BM_OVER_CUR_POLARITY; 401 } 402 /* If the polarity is not set keep it as setup by the bootlader */ 403 if (data->pwr_pol == 1) 404 reg |= MX6_BM_PWR_POLARITY; 405 writel(reg, usbmisc->base + data->index * 4); 406 407 /* SoC non-burst setting */ 408 reg = readl(usbmisc->base + data->index * 4); 409 writel(reg | MX6_BM_NON_BURST_SETTING, 410 usbmisc->base + data->index * 4); 411 412 /* For HSIC controller */ 413 if (data->hsic) { 414 reg = readl(usbmisc->base + data->index * 4); 415 writel(reg | MX6_BM_UTMI_ON_CLOCK, 416 usbmisc->base + data->index * 4); 417 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 418 + (data->index - 2) * 4); 419 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 420 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 421 + (data->index - 2) * 4); 422 } 423 424 spin_unlock_irqrestore(&usbmisc->lock, flags); 425 426 usbmisc_imx6q_set_wakeup(data, false); 427 428 return 0; 429 } 430 431 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data *data) 432 { 433 int offset, ret = 0; 434 435 if (data->index == 2 || data->index == 3) { 436 offset = (data->index - 2) * 4; 437 } else if (data->index == 0) { 438 /* 439 * For SoCs like i.MX7D and later, each USB controller has 440 * its own non-core register region. For SoCs before i.MX7D, 441 * the first two USB controllers are non-HSIC controllers. 442 */ 443 offset = 0; 444 } else { 445 dev_err(data->dev, "index is error for usbmisc\n"); 446 ret = -EINVAL; 447 } 448 449 return ret ? ret : offset; 450 } 451 452 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data) 453 { 454 unsigned long flags; 455 u32 val; 456 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 457 int offset; 458 459 spin_lock_irqsave(&usbmisc->lock, flags); 460 offset = usbmisc_imx6_hsic_get_reg_offset(data); 461 if (offset < 0) { 462 spin_unlock_irqrestore(&usbmisc->lock, flags); 463 return offset; 464 } 465 466 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 467 if (!(val & MX6_BM_HSIC_DEV_CONN)) 468 writel(val | MX6_BM_HSIC_DEV_CONN, 469 usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 470 471 spin_unlock_irqrestore(&usbmisc->lock, flags); 472 473 return 0; 474 } 475 476 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on) 477 { 478 unsigned long flags; 479 u32 val; 480 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 481 int offset; 482 483 spin_lock_irqsave(&usbmisc->lock, flags); 484 offset = usbmisc_imx6_hsic_get_reg_offset(data); 485 if (offset < 0) { 486 spin_unlock_irqrestore(&usbmisc->lock, flags); 487 return offset; 488 } 489 490 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 491 val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 492 if (on) 493 val |= MX6_BM_HSIC_CLK_ON; 494 else 495 val &= ~MX6_BM_HSIC_CLK_ON; 496 497 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 498 spin_unlock_irqrestore(&usbmisc->lock, flags); 499 500 return 0; 501 } 502 503 504 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data) 505 { 506 void __iomem *reg = NULL; 507 unsigned long flags; 508 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 509 u32 val; 510 511 usbmisc_imx6q_init(data); 512 513 if (data->index == 0 || data->index == 1) { 514 reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4; 515 spin_lock_irqsave(&usbmisc->lock, flags); 516 /* Set vbus wakeup source as bvalid */ 517 val = readl(reg); 518 writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg); 519 /* 520 * Disable dp/dm wakeup in device mode when vbus is 521 * not there. 522 */ 523 val = readl(usbmisc->base + data->index * 4); 524 writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN, 525 usbmisc->base + data->index * 4); 526 spin_unlock_irqrestore(&usbmisc->lock, flags); 527 } 528 529 /* For HSIC controller */ 530 if (data->hsic) { 531 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 532 val |= MX6SX_BM_HSIC_AUTO_RESUME; 533 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 534 } 535 536 return 0; 537 } 538 539 static int usbmisc_vf610_init(struct imx_usbmisc_data *data) 540 { 541 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 542 u32 reg; 543 544 /* 545 * Vybrid only has one misc register set, but in two different 546 * areas. These is reflected in two instances of this driver. 547 */ 548 if (data->index >= 1) 549 return -EINVAL; 550 551 if (data->disable_oc) { 552 reg = readl(usbmisc->base); 553 writel(reg | VF610_OVER_CUR_DIS, usbmisc->base); 554 } 555 556 return 0; 557 } 558 559 static int usbmisc_imx7d_set_wakeup 560 (struct imx_usbmisc_data *data, bool enabled) 561 { 562 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 563 unsigned long flags; 564 u32 val; 565 566 spin_lock_irqsave(&usbmisc->lock, flags); 567 val = readl(usbmisc->base); 568 if (enabled) { 569 val &= ~MX6_USB_OTG_WAKEUP_BITS; 570 val |= usbmisc_wakeup_setting(data); 571 writel(val, usbmisc->base); 572 } else { 573 if (val & MX6_BM_WAKEUP_INTR) 574 dev_dbg(data->dev, "wakeup int\n"); 575 writel(val & ~MX6_USB_OTG_WAKEUP_BITS, usbmisc->base); 576 } 577 spin_unlock_irqrestore(&usbmisc->lock, flags); 578 579 return 0; 580 } 581 582 static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) 583 { 584 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 585 unsigned long flags; 586 u32 reg; 587 588 if (data->index >= 1) 589 return -EINVAL; 590 591 spin_lock_irqsave(&usbmisc->lock, flags); 592 reg = readl(usbmisc->base); 593 if (data->disable_oc) { 594 reg |= MX6_BM_OVER_CUR_DIS; 595 } else { 596 reg &= ~MX6_BM_OVER_CUR_DIS; 597 598 /* 599 * If the polarity is not configured keep it as setup by the 600 * bootloader. 601 */ 602 if (data->oc_pol_configured && data->oc_pol_active_low) 603 reg |= MX6_BM_OVER_CUR_POLARITY; 604 else if (data->oc_pol_configured) 605 reg &= ~MX6_BM_OVER_CUR_POLARITY; 606 } 607 /* If the polarity is not set keep it as setup by the bootlader */ 608 if (data->pwr_pol == 1) 609 reg |= MX6_BM_PWR_POLARITY; 610 writel(reg, usbmisc->base); 611 612 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 613 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 614 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, 615 usbmisc->base + MX7D_USBNC_USB_CTRL2); 616 617 spin_unlock_irqrestore(&usbmisc->lock, flags); 618 619 usbmisc_imx7d_set_wakeup(data, false); 620 621 return 0; 622 } 623 624 static const struct usbmisc_ops imx25_usbmisc_ops = { 625 .init = usbmisc_imx25_init, 626 .post = usbmisc_imx25_post, 627 }; 628 629 static const struct usbmisc_ops imx27_usbmisc_ops = { 630 .init = usbmisc_imx27_init, 631 }; 632 633 static const struct usbmisc_ops imx51_usbmisc_ops = { 634 .init = usbmisc_imx53_init, 635 }; 636 637 static const struct usbmisc_ops imx53_usbmisc_ops = { 638 .init = usbmisc_imx53_init, 639 }; 640 641 static const struct usbmisc_ops imx6q_usbmisc_ops = { 642 .set_wakeup = usbmisc_imx6q_set_wakeup, 643 .init = usbmisc_imx6q_init, 644 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 645 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 646 }; 647 648 static const struct usbmisc_ops vf610_usbmisc_ops = { 649 .init = usbmisc_vf610_init, 650 }; 651 652 static const struct usbmisc_ops imx6sx_usbmisc_ops = { 653 .set_wakeup = usbmisc_imx6q_set_wakeup, 654 .init = usbmisc_imx6sx_init, 655 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 656 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 657 }; 658 659 static const struct usbmisc_ops imx7d_usbmisc_ops = { 660 .init = usbmisc_imx7d_init, 661 .set_wakeup = usbmisc_imx7d_set_wakeup, 662 }; 663 664 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) 665 { 666 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 667 668 return usbmisc->ops == &imx53_usbmisc_ops; 669 } 670 671 int imx_usbmisc_init(struct imx_usbmisc_data *data) 672 { 673 struct imx_usbmisc *usbmisc; 674 675 if (!data) 676 return 0; 677 678 usbmisc = dev_get_drvdata(data->dev); 679 if (!usbmisc->ops->init) 680 return 0; 681 return usbmisc->ops->init(data); 682 } 683 EXPORT_SYMBOL_GPL(imx_usbmisc_init); 684 685 int imx_usbmisc_init_post(struct imx_usbmisc_data *data) 686 { 687 struct imx_usbmisc *usbmisc; 688 689 if (!data) 690 return 0; 691 692 usbmisc = dev_get_drvdata(data->dev); 693 if (!usbmisc->ops->post) 694 return 0; 695 return usbmisc->ops->post(data); 696 } 697 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post); 698 699 int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled) 700 { 701 struct imx_usbmisc *usbmisc; 702 703 if (!data) 704 return 0; 705 706 usbmisc = dev_get_drvdata(data->dev); 707 if (!usbmisc->ops->set_wakeup) 708 return 0; 709 return usbmisc->ops->set_wakeup(data, enabled); 710 } 711 EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup); 712 713 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data) 714 { 715 struct imx_usbmisc *usbmisc; 716 717 if (!data) 718 return 0; 719 720 usbmisc = dev_get_drvdata(data->dev); 721 if (!usbmisc->ops->hsic_set_connect || !data->hsic) 722 return 0; 723 return usbmisc->ops->hsic_set_connect(data); 724 } 725 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect); 726 727 int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on) 728 { 729 struct imx_usbmisc *usbmisc; 730 731 if (!data) 732 return 0; 733 734 usbmisc = dev_get_drvdata(data->dev); 735 if (!usbmisc->ops->hsic_set_clk || !data->hsic) 736 return 0; 737 return usbmisc->ops->hsic_set_clk(data, on); 738 } 739 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_clk); 740 static const struct of_device_id usbmisc_imx_dt_ids[] = { 741 { 742 .compatible = "fsl,imx25-usbmisc", 743 .data = &imx25_usbmisc_ops, 744 }, 745 { 746 .compatible = "fsl,imx35-usbmisc", 747 .data = &imx25_usbmisc_ops, 748 }, 749 { 750 .compatible = "fsl,imx27-usbmisc", 751 .data = &imx27_usbmisc_ops, 752 }, 753 { 754 .compatible = "fsl,imx51-usbmisc", 755 .data = &imx51_usbmisc_ops, 756 }, 757 { 758 .compatible = "fsl,imx53-usbmisc", 759 .data = &imx53_usbmisc_ops, 760 }, 761 { 762 .compatible = "fsl,imx6q-usbmisc", 763 .data = &imx6q_usbmisc_ops, 764 }, 765 { 766 .compatible = "fsl,vf610-usbmisc", 767 .data = &vf610_usbmisc_ops, 768 }, 769 { 770 .compatible = "fsl,imx6sx-usbmisc", 771 .data = &imx6sx_usbmisc_ops, 772 }, 773 { 774 .compatible = "fsl,imx6ul-usbmisc", 775 .data = &imx6sx_usbmisc_ops, 776 }, 777 { 778 .compatible = "fsl,imx7d-usbmisc", 779 .data = &imx7d_usbmisc_ops, 780 }, 781 { 782 .compatible = "fsl,imx7ulp-usbmisc", 783 .data = &imx7d_usbmisc_ops, 784 }, 785 { /* sentinel */ } 786 }; 787 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); 788 789 static int usbmisc_imx_probe(struct platform_device *pdev) 790 { 791 struct imx_usbmisc *data; 792 const struct of_device_id *of_id; 793 794 of_id = of_match_device(usbmisc_imx_dt_ids, &pdev->dev); 795 if (!of_id) 796 return -ENODEV; 797 798 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 799 if (!data) 800 return -ENOMEM; 801 802 spin_lock_init(&data->lock); 803 804 data->base = devm_platform_ioremap_resource(pdev, 0); 805 if (IS_ERR(data->base)) 806 return PTR_ERR(data->base); 807 808 data->ops = (const struct usbmisc_ops *)of_id->data; 809 platform_set_drvdata(pdev, data); 810 811 return 0; 812 } 813 814 static int usbmisc_imx_remove(struct platform_device *pdev) 815 { 816 return 0; 817 } 818 819 static struct platform_driver usbmisc_imx_driver = { 820 .probe = usbmisc_imx_probe, 821 .remove = usbmisc_imx_remove, 822 .driver = { 823 .name = "usbmisc_imx", 824 .of_match_table = usbmisc_imx_dt_ids, 825 }, 826 }; 827 828 module_platform_driver(usbmisc_imx_driver); 829 830 MODULE_ALIAS("platform:usbmisc-imx"); 831 MODULE_LICENSE("GPL"); 832 MODULE_DESCRIPTION("driver for imx usb non-core registers"); 833 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>"); 834