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