phy-sun4i-usb.c (26416B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Allwinner sun4i USB phy driver 4 * 5 * Copyright (C) 2014-2015 Hans de Goede <hdegoede@redhat.com> 6 * 7 * Based on code from 8 * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 9 * 10 * Modelled after: Samsung S5P/Exynos SoC series MIPI CSIS/DSIM DPHY driver 11 * Copyright (C) 2013 Samsung Electronics Co., Ltd. 12 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> 13 */ 14 15#include <linux/clk.h> 16#include <linux/delay.h> 17#include <linux/err.h> 18#include <linux/extcon-provider.h> 19#include <linux/gpio/consumer.h> 20#include <linux/io.h> 21#include <linux/interrupt.h> 22#include <linux/kernel.h> 23#include <linux/module.h> 24#include <linux/mutex.h> 25#include <linux/of.h> 26#include <linux/of_address.h> 27#include <linux/of_device.h> 28#include <linux/of_gpio.h> 29#include <linux/phy/phy.h> 30#include <linux/phy/phy-sun4i-usb.h> 31#include <linux/platform_device.h> 32#include <linux/power_supply.h> 33#include <linux/regulator/consumer.h> 34#include <linux/reset.h> 35#include <linux/spinlock.h> 36#include <linux/usb/of.h> 37#include <linux/workqueue.h> 38 39#define REG_ISCR 0x00 40#define REG_PHYCTL_A10 0x04 41#define REG_PHYBIST 0x08 42#define REG_PHYTUNE 0x0c 43#define REG_PHYCTL_A33 0x10 44#define REG_PHY_OTGCTL 0x20 45 46#define REG_HCI_PHY_CTL 0x10 47 48#define PHYCTL_DATA BIT(7) 49 50#define OTGCTL_ROUTE_MUSB BIT(0) 51 52#define SUNXI_AHB_ICHR8_EN BIT(10) 53#define SUNXI_AHB_INCR4_BURST_EN BIT(9) 54#define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) 55#define SUNXI_ULPI_BYPASS_EN BIT(0) 56 57/* ISCR, Interface Status and Control bits */ 58#define ISCR_ID_PULLUP_EN (1 << 17) 59#define ISCR_DPDM_PULLUP_EN (1 << 16) 60/* sunxi has the phy id/vbus pins not connected, so we use the force bits */ 61#define ISCR_FORCE_ID_MASK (3 << 14) 62#define ISCR_FORCE_ID_LOW (2 << 14) 63#define ISCR_FORCE_ID_HIGH (3 << 14) 64#define ISCR_FORCE_VBUS_MASK (3 << 12) 65#define ISCR_FORCE_VBUS_LOW (2 << 12) 66#define ISCR_FORCE_VBUS_HIGH (3 << 12) 67 68/* Common Control Bits for Both PHYs */ 69#define PHY_PLL_BW 0x03 70#define PHY_RES45_CAL_EN 0x0c 71 72/* Private Control Bits for Each PHY */ 73#define PHY_TX_AMPLITUDE_TUNE 0x20 74#define PHY_TX_SLEWRATE_TUNE 0x22 75#define PHY_VBUSVALID_TH_SEL 0x25 76#define PHY_PULLUP_RES_SEL 0x27 77#define PHY_OTG_FUNC_EN 0x28 78#define PHY_VBUS_DET_EN 0x29 79#define PHY_DISCON_TH_SEL 0x2a 80#define PHY_SQUELCH_DETECT 0x3c 81 82/* A83T specific control bits for PHY0 */ 83#define PHY_CTL_VBUSVLDEXT BIT(5) 84#define PHY_CTL_SIDDQ BIT(3) 85#define PHY_CTL_H3_SIDDQ BIT(1) 86 87/* A83T specific control bits for PHY2 HSIC */ 88#define SUNXI_EHCI_HS_FORCE BIT(20) 89#define SUNXI_HSIC_CONNECT_DET BIT(17) 90#define SUNXI_HSIC_CONNECT_INT BIT(16) 91#define SUNXI_HSIC BIT(1) 92 93#define MAX_PHYS 4 94 95/* 96 * Note do not raise the debounce time, we must report Vusb high within 100ms 97 * otherwise we get Vbus errors 98 */ 99#define DEBOUNCE_TIME msecs_to_jiffies(50) 100#define POLL_TIME msecs_to_jiffies(250) 101 102enum sun4i_usb_phy_type { 103 sun4i_a10_phy, 104 sun6i_a31_phy, 105 sun8i_a33_phy, 106 sun8i_a83t_phy, 107 sun8i_h3_phy, 108 sun8i_r40_phy, 109 sun8i_v3s_phy, 110 sun50i_a64_phy, 111 sun50i_h6_phy, 112}; 113 114struct sun4i_usb_phy_cfg { 115 int num_phys; 116 int hsic_index; 117 enum sun4i_usb_phy_type type; 118 u32 disc_thresh; 119 u32 hci_phy_ctl_clear; 120 u8 phyctl_offset; 121 bool dedicated_clocks; 122 bool phy0_dual_route; 123 int missing_phys; 124}; 125 126struct sun4i_usb_phy_data { 127 void __iomem *base; 128 const struct sun4i_usb_phy_cfg *cfg; 129 enum usb_dr_mode dr_mode; 130 spinlock_t reg_lock; /* guard access to phyctl reg */ 131 struct sun4i_usb_phy { 132 struct phy *phy; 133 void __iomem *pmu; 134 struct regulator *vbus; 135 struct reset_control *reset; 136 struct clk *clk; 137 struct clk *clk2; 138 bool regulator_on; 139 int index; 140 } phys[MAX_PHYS]; 141 /* phy0 / otg related variables */ 142 struct extcon_dev *extcon; 143 bool phy0_init; 144 struct gpio_desc *id_det_gpio; 145 struct gpio_desc *vbus_det_gpio; 146 struct power_supply *vbus_power_supply; 147 struct notifier_block vbus_power_nb; 148 bool vbus_power_nb_registered; 149 bool force_session_end; 150 int id_det_irq; 151 int vbus_det_irq; 152 int id_det; 153 int vbus_det; 154 struct delayed_work detect; 155}; 156 157#define to_sun4i_usb_phy_data(phy) \ 158 container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index]) 159 160static void sun4i_usb_phy0_update_iscr(struct phy *_phy, u32 clr, u32 set) 161{ 162 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 163 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); 164 u32 iscr; 165 166 iscr = readl(data->base + REG_ISCR); 167 iscr &= ~clr; 168 iscr |= set; 169 writel(iscr, data->base + REG_ISCR); 170} 171 172static void sun4i_usb_phy0_set_id_detect(struct phy *phy, u32 val) 173{ 174 if (val) 175 val = ISCR_FORCE_ID_HIGH; 176 else 177 val = ISCR_FORCE_ID_LOW; 178 179 sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_ID_MASK, val); 180} 181 182static void sun4i_usb_phy0_set_vbus_detect(struct phy *phy, u32 val) 183{ 184 if (val) 185 val = ISCR_FORCE_VBUS_HIGH; 186 else 187 val = ISCR_FORCE_VBUS_LOW; 188 189 sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_VBUS_MASK, val); 190} 191 192static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, 193 int len) 194{ 195 struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); 196 u32 temp, usbc_bit = BIT(phy->index * 2); 197 void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; 198 unsigned long flags; 199 int i; 200 201 spin_lock_irqsave(&phy_data->reg_lock, flags); 202 203 if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) { 204 /* SoCs newer than A33 need us to set phyctl to 0 explicitly */ 205 writel(0, phyctl); 206 } 207 208 for (i = 0; i < len; i++) { 209 temp = readl(phyctl); 210 211 /* clear the address portion */ 212 temp &= ~(0xff << 8); 213 214 /* set the address */ 215 temp |= ((addr + i) << 8); 216 writel(temp, phyctl); 217 218 /* set the data bit and clear usbc bit*/ 219 temp = readb(phyctl); 220 if (data & 0x1) 221 temp |= PHYCTL_DATA; 222 else 223 temp &= ~PHYCTL_DATA; 224 temp &= ~usbc_bit; 225 writeb(temp, phyctl); 226 227 /* pulse usbc_bit */ 228 temp = readb(phyctl); 229 temp |= usbc_bit; 230 writeb(temp, phyctl); 231 232 temp = readb(phyctl); 233 temp &= ~usbc_bit; 234 writeb(temp, phyctl); 235 236 data >>= 1; 237 } 238 239 spin_unlock_irqrestore(&phy_data->reg_lock, flags); 240} 241 242static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable) 243{ 244 struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); 245 u32 bits, reg_value; 246 247 if (!phy->pmu) 248 return; 249 250 bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN | 251 SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN; 252 253 /* A83T USB2 is HSIC */ 254 if (phy_data->cfg->type == sun8i_a83t_phy && phy->index == 2) 255 bits |= SUNXI_EHCI_HS_FORCE | SUNXI_HSIC_CONNECT_INT | 256 SUNXI_HSIC; 257 258 reg_value = readl(phy->pmu); 259 260 if (enable) 261 reg_value |= bits; 262 else 263 reg_value &= ~bits; 264 265 writel(reg_value, phy->pmu); 266} 267 268static int sun4i_usb_phy_init(struct phy *_phy) 269{ 270 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 271 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); 272 int ret; 273 u32 val; 274 275 ret = clk_prepare_enable(phy->clk); 276 if (ret) 277 return ret; 278 279 ret = clk_prepare_enable(phy->clk2); 280 if (ret) { 281 clk_disable_unprepare(phy->clk); 282 return ret; 283 } 284 285 ret = reset_control_deassert(phy->reset); 286 if (ret) { 287 clk_disable_unprepare(phy->clk2); 288 clk_disable_unprepare(phy->clk); 289 return ret; 290 } 291 292 if (phy->pmu && data->cfg->hci_phy_ctl_clear) { 293 val = readl(phy->pmu + REG_HCI_PHY_CTL); 294 val &= ~data->cfg->hci_phy_ctl_clear; 295 writel(val, phy->pmu + REG_HCI_PHY_CTL); 296 } 297 298 if (data->cfg->type == sun8i_a83t_phy || 299 data->cfg->type == sun50i_h6_phy) { 300 if (phy->index == 0) { 301 val = readl(data->base + data->cfg->phyctl_offset); 302 val |= PHY_CTL_VBUSVLDEXT; 303 val &= ~PHY_CTL_SIDDQ; 304 writel(val, data->base + data->cfg->phyctl_offset); 305 } 306 } else { 307 /* Enable USB 45 Ohm resistor calibration */ 308 if (phy->index == 0) 309 sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); 310 311 /* Adjust PHY's magnitude and rate */ 312 sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); 313 314 /* Disconnect threshold adjustment */ 315 sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, 316 data->cfg->disc_thresh, 2); 317 } 318 319 sun4i_usb_phy_passby(phy, 1); 320 321 if (phy->index == 0) { 322 data->phy0_init = true; 323 324 /* Enable pull-ups */ 325 sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_DPDM_PULLUP_EN); 326 sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_ID_PULLUP_EN); 327 328 /* Force ISCR and cable state updates */ 329 data->id_det = -1; 330 data->vbus_det = -1; 331 queue_delayed_work(system_wq, &data->detect, 0); 332 } 333 334 return 0; 335} 336 337static int sun4i_usb_phy_exit(struct phy *_phy) 338{ 339 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 340 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); 341 342 if (phy->index == 0) { 343 if (data->cfg->type == sun8i_a83t_phy || 344 data->cfg->type == sun50i_h6_phy) { 345 void __iomem *phyctl = data->base + 346 data->cfg->phyctl_offset; 347 348 writel(readl(phyctl) | PHY_CTL_SIDDQ, phyctl); 349 } 350 351 /* Disable pull-ups */ 352 sun4i_usb_phy0_update_iscr(_phy, ISCR_DPDM_PULLUP_EN, 0); 353 sun4i_usb_phy0_update_iscr(_phy, ISCR_ID_PULLUP_EN, 0); 354 data->phy0_init = false; 355 } 356 357 sun4i_usb_phy_passby(phy, 0); 358 reset_control_assert(phy->reset); 359 clk_disable_unprepare(phy->clk2); 360 clk_disable_unprepare(phy->clk); 361 362 return 0; 363} 364 365static int sun4i_usb_phy0_get_id_det(struct sun4i_usb_phy_data *data) 366{ 367 switch (data->dr_mode) { 368 case USB_DR_MODE_OTG: 369 if (data->id_det_gpio) 370 return gpiod_get_value_cansleep(data->id_det_gpio); 371 else 372 return 1; /* Fallback to peripheral mode */ 373 case USB_DR_MODE_HOST: 374 return 0; 375 case USB_DR_MODE_PERIPHERAL: 376 default: 377 return 1; 378 } 379} 380 381static int sun4i_usb_phy0_get_vbus_det(struct sun4i_usb_phy_data *data) 382{ 383 if (data->vbus_det_gpio) 384 return gpiod_get_value_cansleep(data->vbus_det_gpio); 385 386 if (data->vbus_power_supply) { 387 union power_supply_propval val; 388 int r; 389 390 r = power_supply_get_property(data->vbus_power_supply, 391 POWER_SUPPLY_PROP_PRESENT, &val); 392 if (r == 0) 393 return val.intval; 394 } 395 396 /* Fallback: report vbus as high */ 397 return 1; 398} 399 400static bool sun4i_usb_phy0_have_vbus_det(struct sun4i_usb_phy_data *data) 401{ 402 return data->vbus_det_gpio || data->vbus_power_supply; 403} 404 405static bool sun4i_usb_phy0_poll(struct sun4i_usb_phy_data *data) 406{ 407 if ((data->id_det_gpio && data->id_det_irq <= 0) || 408 (data->vbus_det_gpio && data->vbus_det_irq <= 0)) 409 return true; 410 411 /* 412 * The A31/A23/A33 companion pmics (AXP221/AXP223) do not 413 * generate vbus change interrupts when the board is driving 414 * vbus using the N_VBUSEN pin on the pmic, so we must poll 415 * when using the pmic for vbus-det _and_ we're driving vbus. 416 */ 417 if ((data->cfg->type == sun6i_a31_phy || 418 data->cfg->type == sun8i_a33_phy) && 419 data->vbus_power_supply && data->phys[0].regulator_on) 420 return true; 421 422 return false; 423} 424 425static int sun4i_usb_phy_power_on(struct phy *_phy) 426{ 427 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 428 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); 429 int ret; 430 431 if (!phy->vbus || phy->regulator_on) 432 return 0; 433 434 /* For phy0 only turn on Vbus if we don't have an ext. Vbus */ 435 if (phy->index == 0 && sun4i_usb_phy0_have_vbus_det(data) && 436 data->vbus_det) { 437 dev_warn(&_phy->dev, "External vbus detected, not enabling our own vbus\n"); 438 return 0; 439 } 440 441 ret = regulator_enable(phy->vbus); 442 if (ret) 443 return ret; 444 445 phy->regulator_on = true; 446 447 /* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */ 448 if (phy->index == 0 && sun4i_usb_phy0_poll(data)) 449 mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); 450 451 return 0; 452} 453 454static int sun4i_usb_phy_power_off(struct phy *_phy) 455{ 456 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 457 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); 458 459 if (!phy->vbus || !phy->regulator_on) 460 return 0; 461 462 regulator_disable(phy->vbus); 463 phy->regulator_on = false; 464 465 /* 466 * phy0 vbus typically slowly discharges, sometimes this causes the 467 * Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan. 468 */ 469 if (phy->index == 0 && !sun4i_usb_phy0_poll(data)) 470 mod_delayed_work(system_wq, &data->detect, POLL_TIME); 471 472 return 0; 473} 474 475static int sun4i_usb_phy_set_mode(struct phy *_phy, 476 enum phy_mode mode, int submode) 477{ 478 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 479 struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); 480 int new_mode; 481 482 if (phy->index != 0) { 483 if (mode == PHY_MODE_USB_HOST) 484 return 0; 485 return -EINVAL; 486 } 487 488 switch (mode) { 489 case PHY_MODE_USB_HOST: 490 new_mode = USB_DR_MODE_HOST; 491 break; 492 case PHY_MODE_USB_DEVICE: 493 new_mode = USB_DR_MODE_PERIPHERAL; 494 break; 495 case PHY_MODE_USB_OTG: 496 new_mode = USB_DR_MODE_OTG; 497 break; 498 default: 499 return -EINVAL; 500 } 501 502 if (new_mode != data->dr_mode) { 503 dev_info(&_phy->dev, "Changing dr_mode to %d\n", new_mode); 504 data->dr_mode = new_mode; 505 } 506 507 data->id_det = -1; /* Force reprocessing of id */ 508 data->force_session_end = true; 509 queue_delayed_work(system_wq, &data->detect, 0); 510 511 return 0; 512} 513 514void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) 515{ 516 struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); 517 518 sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2); 519} 520EXPORT_SYMBOL_GPL(sun4i_usb_phy_set_squelch_detect); 521 522static const struct phy_ops sun4i_usb_phy_ops = { 523 .init = sun4i_usb_phy_init, 524 .exit = sun4i_usb_phy_exit, 525 .power_on = sun4i_usb_phy_power_on, 526 .power_off = sun4i_usb_phy_power_off, 527 .set_mode = sun4i_usb_phy_set_mode, 528 .owner = THIS_MODULE, 529}; 530 531static void sun4i_usb_phy0_reroute(struct sun4i_usb_phy_data *data, int id_det) 532{ 533 u32 regval; 534 535 regval = readl(data->base + REG_PHY_OTGCTL); 536 if (id_det == 0) { 537 /* Host mode. Route phy0 to EHCI/OHCI */ 538 regval &= ~OTGCTL_ROUTE_MUSB; 539 } else { 540 /* Peripheral mode. Route phy0 to MUSB */ 541 regval |= OTGCTL_ROUTE_MUSB; 542 } 543 writel(regval, data->base + REG_PHY_OTGCTL); 544} 545 546static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) 547{ 548 struct sun4i_usb_phy_data *data = 549 container_of(work, struct sun4i_usb_phy_data, detect.work); 550 struct phy *phy0 = data->phys[0].phy; 551 struct sun4i_usb_phy *phy; 552 bool force_session_end, id_notify = false, vbus_notify = false; 553 int id_det, vbus_det; 554 555 if (!phy0) 556 return; 557 558 phy = phy_get_drvdata(phy0); 559 id_det = sun4i_usb_phy0_get_id_det(data); 560 vbus_det = sun4i_usb_phy0_get_vbus_det(data); 561 562 mutex_lock(&phy0->mutex); 563 564 if (!data->phy0_init) { 565 mutex_unlock(&phy0->mutex); 566 return; 567 } 568 569 force_session_end = data->force_session_end; 570 data->force_session_end = false; 571 572 if (id_det != data->id_det) { 573 /* id-change, force session end if we've no vbus detection */ 574 if (data->dr_mode == USB_DR_MODE_OTG && 575 !sun4i_usb_phy0_have_vbus_det(data)) 576 force_session_end = true; 577 578 /* When entering host mode (id = 0) force end the session now */ 579 if (force_session_end && id_det == 0) { 580 sun4i_usb_phy0_set_vbus_detect(phy0, 0); 581 msleep(200); 582 sun4i_usb_phy0_set_vbus_detect(phy0, 1); 583 } 584 sun4i_usb_phy0_set_id_detect(phy0, id_det); 585 data->id_det = id_det; 586 id_notify = true; 587 } 588 589 if (vbus_det != data->vbus_det) { 590 sun4i_usb_phy0_set_vbus_detect(phy0, vbus_det); 591 data->vbus_det = vbus_det; 592 vbus_notify = true; 593 } 594 595 mutex_unlock(&phy0->mutex); 596 597 if (id_notify) { 598 extcon_set_state_sync(data->extcon, EXTCON_USB_HOST, 599 !id_det); 600 /* When leaving host mode force end the session here */ 601 if (force_session_end && id_det == 1) { 602 mutex_lock(&phy0->mutex); 603 sun4i_usb_phy0_set_vbus_detect(phy0, 0); 604 msleep(1000); 605 sun4i_usb_phy0_set_vbus_detect(phy0, 1); 606 mutex_unlock(&phy0->mutex); 607 } 608 609 /* Enable PHY0 passby for host mode only. */ 610 sun4i_usb_phy_passby(phy, !id_det); 611 612 /* Re-route PHY0 if necessary */ 613 if (data->cfg->phy0_dual_route) 614 sun4i_usb_phy0_reroute(data, id_det); 615 } 616 617 if (vbus_notify) 618 extcon_set_state_sync(data->extcon, EXTCON_USB, vbus_det); 619 620 if (sun4i_usb_phy0_poll(data)) 621 queue_delayed_work(system_wq, &data->detect, POLL_TIME); 622} 623 624static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id) 625{ 626 struct sun4i_usb_phy_data *data = dev_id; 627 628 /* vbus or id changed, let the pins settle and then scan them */ 629 mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); 630 631 return IRQ_HANDLED; 632} 633 634static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb, 635 unsigned long val, void *v) 636{ 637 struct sun4i_usb_phy_data *data = 638 container_of(nb, struct sun4i_usb_phy_data, vbus_power_nb); 639 struct power_supply *psy = v; 640 641 /* Properties on the vbus_power_supply changed, scan vbus_det */ 642 if (val == PSY_EVENT_PROP_CHANGED && psy == data->vbus_power_supply) 643 mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); 644 645 return NOTIFY_OK; 646} 647 648static struct phy *sun4i_usb_phy_xlate(struct device *dev, 649 struct of_phandle_args *args) 650{ 651 struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); 652 653 if (args->args[0] >= data->cfg->num_phys) 654 return ERR_PTR(-ENODEV); 655 656 if (data->cfg->missing_phys & BIT(args->args[0])) 657 return ERR_PTR(-ENODEV); 658 659 return data->phys[args->args[0]].phy; 660} 661 662static int sun4i_usb_phy_remove(struct platform_device *pdev) 663{ 664 struct device *dev = &pdev->dev; 665 struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); 666 667 if (data->vbus_power_nb_registered) 668 power_supply_unreg_notifier(&data->vbus_power_nb); 669 if (data->id_det_irq > 0) 670 devm_free_irq(dev, data->id_det_irq, data); 671 if (data->vbus_det_irq > 0) 672 devm_free_irq(dev, data->vbus_det_irq, data); 673 674 cancel_delayed_work_sync(&data->detect); 675 676 return 0; 677} 678 679static const unsigned int sun4i_usb_phy0_cable[] = { 680 EXTCON_USB, 681 EXTCON_USB_HOST, 682 EXTCON_NONE, 683}; 684 685static int sun4i_usb_phy_probe(struct platform_device *pdev) 686{ 687 struct sun4i_usb_phy_data *data; 688 struct device *dev = &pdev->dev; 689 struct device_node *np = dev->of_node; 690 struct phy_provider *phy_provider; 691 int i, ret; 692 693 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 694 if (!data) 695 return -ENOMEM; 696 697 spin_lock_init(&data->reg_lock); 698 INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan); 699 dev_set_drvdata(dev, data); 700 data->cfg = of_device_get_match_data(dev); 701 if (!data->cfg) 702 return -EINVAL; 703 704 data->base = devm_platform_ioremap_resource_byname(pdev, "phy_ctrl"); 705 if (IS_ERR(data->base)) 706 return PTR_ERR(data->base); 707 708 data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det", 709 GPIOD_IN); 710 if (IS_ERR(data->id_det_gpio)) { 711 dev_err(dev, "Couldn't request ID GPIO\n"); 712 return PTR_ERR(data->id_det_gpio); 713 } 714 715 data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det", 716 GPIOD_IN); 717 if (IS_ERR(data->vbus_det_gpio)) { 718 dev_err(dev, "Couldn't request VBUS detect GPIO\n"); 719 return PTR_ERR(data->vbus_det_gpio); 720 } 721 722 if (of_find_property(np, "usb0_vbus_power-supply", NULL)) { 723 data->vbus_power_supply = devm_power_supply_get_by_phandle(dev, 724 "usb0_vbus_power-supply"); 725 if (IS_ERR(data->vbus_power_supply)) { 726 dev_err(dev, "Couldn't get the VBUS power supply\n"); 727 return PTR_ERR(data->vbus_power_supply); 728 } 729 730 if (!data->vbus_power_supply) 731 return -EPROBE_DEFER; 732 } 733 734 data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0); 735 736 data->extcon = devm_extcon_dev_allocate(dev, sun4i_usb_phy0_cable); 737 if (IS_ERR(data->extcon)) { 738 dev_err(dev, "Couldn't allocate our extcon device\n"); 739 return PTR_ERR(data->extcon); 740 } 741 742 ret = devm_extcon_dev_register(dev, data->extcon); 743 if (ret) { 744 dev_err(dev, "failed to register extcon: %d\n", ret); 745 return ret; 746 } 747 748 for (i = 0; i < data->cfg->num_phys; i++) { 749 struct sun4i_usb_phy *phy = data->phys + i; 750 char name[16]; 751 752 if (data->cfg->missing_phys & BIT(i)) 753 continue; 754 755 snprintf(name, sizeof(name), "usb%d_vbus", i); 756 phy->vbus = devm_regulator_get_optional(dev, name); 757 if (IS_ERR(phy->vbus)) { 758 if (PTR_ERR(phy->vbus) == -EPROBE_DEFER) { 759 dev_err(dev, 760 "Couldn't get regulator %s... Deferring probe\n", 761 name); 762 return -EPROBE_DEFER; 763 } 764 765 phy->vbus = NULL; 766 } 767 768 if (data->cfg->dedicated_clocks) 769 snprintf(name, sizeof(name), "usb%d_phy", i); 770 else 771 strlcpy(name, "usb_phy", sizeof(name)); 772 773 phy->clk = devm_clk_get(dev, name); 774 if (IS_ERR(phy->clk)) { 775 dev_err(dev, "failed to get clock %s\n", name); 776 return PTR_ERR(phy->clk); 777 } 778 779 /* The first PHY is always tied to OTG, and never HSIC */ 780 if (data->cfg->hsic_index && i == data->cfg->hsic_index) { 781 /* HSIC needs secondary clock */ 782 snprintf(name, sizeof(name), "usb%d_hsic_12M", i); 783 phy->clk2 = devm_clk_get(dev, name); 784 if (IS_ERR(phy->clk2)) { 785 dev_err(dev, "failed to get clock %s\n", name); 786 return PTR_ERR(phy->clk2); 787 } 788 } 789 790 snprintf(name, sizeof(name), "usb%d_reset", i); 791 phy->reset = devm_reset_control_get(dev, name); 792 if (IS_ERR(phy->reset)) { 793 dev_err(dev, "failed to get reset %s\n", name); 794 return PTR_ERR(phy->reset); 795 } 796 797 if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */ 798 snprintf(name, sizeof(name), "pmu%d", i); 799 phy->pmu = devm_platform_ioremap_resource_byname(pdev, name); 800 if (IS_ERR(phy->pmu)) 801 return PTR_ERR(phy->pmu); 802 } 803 804 phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops); 805 if (IS_ERR(phy->phy)) { 806 dev_err(dev, "failed to create PHY %d\n", i); 807 return PTR_ERR(phy->phy); 808 } 809 810 phy->index = i; 811 phy_set_drvdata(phy->phy, &data->phys[i]); 812 } 813 814 data->id_det_irq = gpiod_to_irq(data->id_det_gpio); 815 if (data->id_det_irq > 0) { 816 ret = devm_request_irq(dev, data->id_det_irq, 817 sun4i_usb_phy0_id_vbus_det_irq, 818 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 819 "usb0-id-det", data); 820 if (ret) { 821 dev_err(dev, "Err requesting id-det-irq: %d\n", ret); 822 return ret; 823 } 824 } 825 826 data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio); 827 if (data->vbus_det_irq > 0) { 828 ret = devm_request_irq(dev, data->vbus_det_irq, 829 sun4i_usb_phy0_id_vbus_det_irq, 830 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 831 "usb0-vbus-det", data); 832 if (ret) { 833 dev_err(dev, "Err requesting vbus-det-irq: %d\n", ret); 834 data->vbus_det_irq = -1; 835 sun4i_usb_phy_remove(pdev); /* Stop detect work */ 836 return ret; 837 } 838 } 839 840 if (data->vbus_power_supply) { 841 data->vbus_power_nb.notifier_call = sun4i_usb_phy0_vbus_notify; 842 data->vbus_power_nb.priority = 0; 843 ret = power_supply_reg_notifier(&data->vbus_power_nb); 844 if (ret) { 845 sun4i_usb_phy_remove(pdev); /* Stop detect work */ 846 return ret; 847 } 848 data->vbus_power_nb_registered = true; 849 } 850 851 phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate); 852 if (IS_ERR(phy_provider)) { 853 sun4i_usb_phy_remove(pdev); /* Stop detect work */ 854 return PTR_ERR(phy_provider); 855 } 856 857 dev_dbg(dev, "successfully loaded\n"); 858 859 return 0; 860} 861 862static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { 863 .num_phys = 3, 864 .type = sun4i_a10_phy, 865 .disc_thresh = 3, 866 .phyctl_offset = REG_PHYCTL_A10, 867 .dedicated_clocks = false, 868}; 869 870static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { 871 .num_phys = 2, 872 .type = sun4i_a10_phy, 873 .disc_thresh = 2, 874 .phyctl_offset = REG_PHYCTL_A10, 875 .dedicated_clocks = false, 876}; 877 878static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { 879 .num_phys = 3, 880 .type = sun6i_a31_phy, 881 .disc_thresh = 3, 882 .phyctl_offset = REG_PHYCTL_A10, 883 .dedicated_clocks = true, 884}; 885 886static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { 887 .num_phys = 3, 888 .type = sun4i_a10_phy, 889 .disc_thresh = 2, 890 .phyctl_offset = REG_PHYCTL_A10, 891 .dedicated_clocks = false, 892}; 893 894static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { 895 .num_phys = 2, 896 .type = sun6i_a31_phy, 897 .disc_thresh = 3, 898 .phyctl_offset = REG_PHYCTL_A10, 899 .dedicated_clocks = true, 900}; 901 902static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { 903 .num_phys = 2, 904 .type = sun8i_a33_phy, 905 .disc_thresh = 3, 906 .phyctl_offset = REG_PHYCTL_A33, 907 .dedicated_clocks = true, 908}; 909 910static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = { 911 .num_phys = 3, 912 .hsic_index = 2, 913 .type = sun8i_a83t_phy, 914 .phyctl_offset = REG_PHYCTL_A33, 915 .dedicated_clocks = true, 916}; 917 918static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { 919 .num_phys = 4, 920 .type = sun8i_h3_phy, 921 .disc_thresh = 3, 922 .phyctl_offset = REG_PHYCTL_A33, 923 .dedicated_clocks = true, 924 .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ, 925 .phy0_dual_route = true, 926}; 927 928static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = { 929 .num_phys = 3, 930 .type = sun8i_r40_phy, 931 .disc_thresh = 3, 932 .phyctl_offset = REG_PHYCTL_A33, 933 .dedicated_clocks = true, 934 .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ, 935 .phy0_dual_route = true, 936}; 937 938static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { 939 .num_phys = 1, 940 .type = sun8i_v3s_phy, 941 .disc_thresh = 3, 942 .phyctl_offset = REG_PHYCTL_A33, 943 .dedicated_clocks = true, 944 .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ, 945 .phy0_dual_route = true, 946}; 947 948static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = { 949 .num_phys = 2, 950 .type = sun50i_h6_phy, 951 .phyctl_offset = REG_PHYCTL_A33, 952 .dedicated_clocks = true, 953 .hci_phy_ctl_clear = PHY_CTL_SIDDQ, 954 .phy0_dual_route = true, 955}; 956 957static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { 958 .num_phys = 2, 959 .type = sun50i_a64_phy, 960 .disc_thresh = 3, 961 .phyctl_offset = REG_PHYCTL_A33, 962 .dedicated_clocks = true, 963 .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ, 964 .phy0_dual_route = true, 965}; 966 967static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = { 968 .num_phys = 4, 969 .type = sun50i_h6_phy, 970 .phyctl_offset = REG_PHYCTL_A33, 971 .dedicated_clocks = true, 972 .phy0_dual_route = true, 973 .missing_phys = BIT(1) | BIT(2), 974}; 975 976static const struct of_device_id sun4i_usb_phy_of_match[] = { 977 { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg }, 978 { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg }, 979 { .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg }, 980 { .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg }, 981 { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg }, 982 { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg }, 983 { .compatible = "allwinner,sun8i-a83t-usb-phy", .data = &sun8i_a83t_cfg }, 984 { .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg }, 985 { .compatible = "allwinner,sun8i-r40-usb-phy", .data = &sun8i_r40_cfg }, 986 { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = &sun8i_v3s_cfg }, 987 { .compatible = "allwinner,sun20i-d1-usb-phy", .data = &sun20i_d1_cfg }, 988 { .compatible = "allwinner,sun50i-a64-usb-phy", 989 .data = &sun50i_a64_cfg}, 990 { .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg }, 991 { }, 992}; 993MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); 994 995static struct platform_driver sun4i_usb_phy_driver = { 996 .probe = sun4i_usb_phy_probe, 997 .remove = sun4i_usb_phy_remove, 998 .driver = { 999 .of_match_table = sun4i_usb_phy_of_match, 1000 .name = "sun4i-usb-phy", 1001 } 1002}; 1003module_platform_driver(sun4i_usb_phy_driver); 1004 1005MODULE_DESCRIPTION("Allwinner sun4i USB phy driver"); 1006MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 1007MODULE_LICENSE("GPL v2");