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