Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Rockchip USB2.0 PHY with Innosilicon IP block driver
0004  *
0005  * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/delay.h>
0011 #include <linux/extcon-provider.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/gpio/consumer.h>
0015 #include <linux/jiffies.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/mutex.h>
0019 #include <linux/of.h>
0020 #include <linux/of_address.h>
0021 #include <linux/of_irq.h>
0022 #include <linux/of_platform.h>
0023 #include <linux/phy/phy.h>
0024 #include <linux/platform_device.h>
0025 #include <linux/power_supply.h>
0026 #include <linux/regmap.h>
0027 #include <linux/mfd/syscon.h>
0028 #include <linux/usb/of.h>
0029 #include <linux/usb/otg.h>
0030 
0031 #define BIT_WRITEABLE_SHIFT 16
0032 #define SCHEDULE_DELAY      (60 * HZ)
0033 #define OTG_SCHEDULE_DELAY  (2 * HZ)
0034 
0035 enum rockchip_usb2phy_port_id {
0036     USB2PHY_PORT_OTG,
0037     USB2PHY_PORT_HOST,
0038     USB2PHY_NUM_PORTS,
0039 };
0040 
0041 enum rockchip_usb2phy_host_state {
0042     PHY_STATE_HS_ONLINE = 0,
0043     PHY_STATE_DISCONNECT    = 1,
0044     PHY_STATE_CONNECT   = 2,
0045     PHY_STATE_FS_LS_ONLINE  = 4,
0046 };
0047 
0048 /**
0049  * enum usb_chg_state - Different states involved in USB charger detection.
0050  * @USB_CHG_STATE_UNDEFINED:    USB charger is not connected or detection
0051  *              process is not yet started.
0052  * @USB_CHG_STATE_WAIT_FOR_DCD: Waiting for Data pins contact.
0053  * @USB_CHG_STATE_DCD_DONE: Data pin contact is detected.
0054  * @USB_CHG_STATE_PRIMARY_DONE: Primary detection is completed (Detects
0055  *              between SDP and DCP/CDP).
0056  * @USB_CHG_STATE_SECONDARY_DONE: Secondary detection is completed (Detects
0057  *                between DCP and CDP).
0058  * @USB_CHG_STATE_DETECTED: USB charger type is determined.
0059  */
0060 enum usb_chg_state {
0061     USB_CHG_STATE_UNDEFINED = 0,
0062     USB_CHG_STATE_WAIT_FOR_DCD,
0063     USB_CHG_STATE_DCD_DONE,
0064     USB_CHG_STATE_PRIMARY_DONE,
0065     USB_CHG_STATE_SECONDARY_DONE,
0066     USB_CHG_STATE_DETECTED,
0067 };
0068 
0069 static const unsigned int rockchip_usb2phy_extcon_cable[] = {
0070     EXTCON_USB,
0071     EXTCON_USB_HOST,
0072     EXTCON_CHG_USB_SDP,
0073     EXTCON_CHG_USB_CDP,
0074     EXTCON_CHG_USB_DCP,
0075     EXTCON_CHG_USB_SLOW,
0076     EXTCON_NONE,
0077 };
0078 
0079 struct usb2phy_reg {
0080     unsigned int    offset;
0081     unsigned int    bitend;
0082     unsigned int    bitstart;
0083     unsigned int    disable;
0084     unsigned int    enable;
0085 };
0086 
0087 /**
0088  * struct rockchip_chg_det_reg - usb charger detect registers
0089  * @cp_det: charging port detected successfully.
0090  * @dcp_det: dedicated charging port detected successfully.
0091  * @dp_det: assert data pin connect successfully.
0092  * @idm_sink_en: open dm sink curren.
0093  * @idp_sink_en: open dp sink current.
0094  * @idp_src_en: open dm source current.
0095  * @rdm_pdwn_en: open dm pull down resistor.
0096  * @vdm_src_en: open dm voltage source.
0097  * @vdp_src_en: open dp voltage source.
0098  * @opmode: utmi operational mode.
0099  */
0100 struct rockchip_chg_det_reg {
0101     struct usb2phy_reg  cp_det;
0102     struct usb2phy_reg  dcp_det;
0103     struct usb2phy_reg  dp_det;
0104     struct usb2phy_reg  idm_sink_en;
0105     struct usb2phy_reg  idp_sink_en;
0106     struct usb2phy_reg  idp_src_en;
0107     struct usb2phy_reg  rdm_pdwn_en;
0108     struct usb2phy_reg  vdm_src_en;
0109     struct usb2phy_reg  vdp_src_en;
0110     struct usb2phy_reg  opmode;
0111 };
0112 
0113 /**
0114  * struct rockchip_usb2phy_port_cfg - usb-phy port configuration.
0115  * @phy_sus: phy suspend register.
0116  * @bvalid_det_en: vbus valid rise detection enable register.
0117  * @bvalid_det_st: vbus valid rise detection status register.
0118  * @bvalid_det_clr: vbus valid rise detection clear register.
0119  * @id_det_en: id detection enable register.
0120  * @id_det_st: id detection state register.
0121  * @id_det_clr: id detection clear register.
0122  * @ls_det_en: linestate detection enable register.
0123  * @ls_det_st: linestate detection state register.
0124  * @ls_det_clr: linestate detection clear register.
0125  * @utmi_avalid: utmi vbus avalid status register.
0126  * @utmi_bvalid: utmi vbus bvalid status register.
0127  * @utmi_id: utmi id state register.
0128  * @utmi_ls: utmi linestate state register.
0129  * @utmi_hstdet: utmi host disconnect register.
0130  */
0131 struct rockchip_usb2phy_port_cfg {
0132     struct usb2phy_reg  phy_sus;
0133     struct usb2phy_reg  bvalid_det_en;
0134     struct usb2phy_reg  bvalid_det_st;
0135     struct usb2phy_reg  bvalid_det_clr;
0136     struct usb2phy_reg  id_det_en;
0137     struct usb2phy_reg  id_det_st;
0138     struct usb2phy_reg  id_det_clr;
0139     struct usb2phy_reg  ls_det_en;
0140     struct usb2phy_reg  ls_det_st;
0141     struct usb2phy_reg  ls_det_clr;
0142     struct usb2phy_reg  utmi_avalid;
0143     struct usb2phy_reg  utmi_bvalid;
0144     struct usb2phy_reg  utmi_id;
0145     struct usb2phy_reg  utmi_ls;
0146     struct usb2phy_reg  utmi_hstdet;
0147 };
0148 
0149 /**
0150  * struct rockchip_usb2phy_cfg - usb-phy configuration.
0151  * @reg: the address offset of grf for usb-phy config.
0152  * @num_ports: specify how many ports that the phy has.
0153  * @clkout_ctl: keep on/turn off output clk of phy.
0154  * @port_cfgs: usb-phy port configurations.
0155  * @chg_det: charger detection registers.
0156  */
0157 struct rockchip_usb2phy_cfg {
0158     unsigned int    reg;
0159     unsigned int    num_ports;
0160     struct usb2phy_reg  clkout_ctl;
0161     const struct rockchip_usb2phy_port_cfg  port_cfgs[USB2PHY_NUM_PORTS];
0162     const struct rockchip_chg_det_reg   chg_det;
0163 };
0164 
0165 /**
0166  * struct rockchip_usb2phy_port - usb-phy port data.
0167  * @phy: generic phy.
0168  * @port_id: flag for otg port or host port.
0169  * @suspended: phy suspended flag.
0170  * @vbus_attached: otg device vbus status.
0171  * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
0172  * @id_irq: IRQ number assigned for ID pin detection.
0173  * @ls_irq: IRQ number assigned for linestate detection.
0174  * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
0175  *       irqs to one irq in otg-port.
0176  * @mutex: for register updating in sm_work.
0177  * @chg_work: charge detect work.
0178  * @otg_sm_work: OTG state machine work.
0179  * @sm_work: HOST state machine work.
0180  * @port_cfg: port register configuration, assigned by driver data.
0181  * @event_nb: hold event notification callback.
0182  * @state: define OTG enumeration states before device reset.
0183  * @mode: the dr_mode of the controller.
0184  */
0185 struct rockchip_usb2phy_port {
0186     struct phy  *phy;
0187     unsigned int    port_id;
0188     bool        suspended;
0189     bool        vbus_attached;
0190     int     bvalid_irq;
0191     int     id_irq;
0192     int     ls_irq;
0193     int     otg_mux_irq;
0194     struct mutex    mutex;
0195     struct      delayed_work chg_work;
0196     struct      delayed_work otg_sm_work;
0197     struct      delayed_work sm_work;
0198     const struct    rockchip_usb2phy_port_cfg *port_cfg;
0199     struct notifier_block   event_nb;
0200     enum usb_otg_state  state;
0201     enum usb_dr_mode    mode;
0202 };
0203 
0204 /**
0205  * struct rockchip_usb2phy - usb2.0 phy driver data.
0206  * @dev: pointer to device.
0207  * @grf: General Register Files regmap.
0208  * @usbgrf: USB General Register Files regmap.
0209  * @clk: clock struct of phy input clk.
0210  * @clk480m: clock struct of phy output clk.
0211  * @clk480m_hw: clock struct of phy output clk management.
0212  * @chg_state: states involved in USB charger detection.
0213  * @chg_type: USB charger types.
0214  * @dcd_retries: The retry count used to track Data contact
0215  *       detection process.
0216  * @edev: extcon device for notification registration
0217  * @irq: muxed interrupt for single irq configuration
0218  * @phy_cfg: phy register configuration, assigned by driver data.
0219  * @ports: phy port instance.
0220  */
0221 struct rockchip_usb2phy {
0222     struct device   *dev;
0223     struct regmap   *grf;
0224     struct regmap   *usbgrf;
0225     struct clk  *clk;
0226     struct clk  *clk480m;
0227     struct clk_hw   clk480m_hw;
0228     enum usb_chg_state  chg_state;
0229     enum power_supply_type  chg_type;
0230     u8          dcd_retries;
0231     struct extcon_dev   *edev;
0232     int         irq;
0233     const struct rockchip_usb2phy_cfg   *phy_cfg;
0234     struct rockchip_usb2phy_port    ports[USB2PHY_NUM_PORTS];
0235 };
0236 
0237 static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
0238 {
0239     return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
0240 }
0241 
0242 static inline int property_enable(struct regmap *base,
0243                   const struct usb2phy_reg *reg, bool en)
0244 {
0245     unsigned int val, mask, tmp;
0246 
0247     tmp = en ? reg->enable : reg->disable;
0248     mask = GENMASK(reg->bitend, reg->bitstart);
0249     val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
0250 
0251     return regmap_write(base, reg->offset, val);
0252 }
0253 
0254 static inline bool property_enabled(struct regmap *base,
0255                     const struct usb2phy_reg *reg)
0256 {
0257     int ret;
0258     unsigned int tmp, orig;
0259     unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
0260 
0261     ret = regmap_read(base, reg->offset, &orig);
0262     if (ret)
0263         return false;
0264 
0265     tmp = (orig & mask) >> reg->bitstart;
0266     return tmp != reg->disable;
0267 }
0268 
0269 static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
0270 {
0271     struct rockchip_usb2phy *rphy =
0272         container_of(hw, struct rockchip_usb2phy, clk480m_hw);
0273     struct regmap *base = get_reg_base(rphy);
0274     int ret;
0275 
0276     /* turn on 480m clk output if it is off */
0277     if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
0278         ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
0279         if (ret)
0280             return ret;
0281 
0282         /* waiting for the clk become stable */
0283         usleep_range(1200, 1300);
0284     }
0285 
0286     return 0;
0287 }
0288 
0289 static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
0290 {
0291     struct rockchip_usb2phy *rphy =
0292         container_of(hw, struct rockchip_usb2phy, clk480m_hw);
0293     struct regmap *base = get_reg_base(rphy);
0294 
0295     /* turn off 480m clk output */
0296     property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
0297 }
0298 
0299 static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
0300 {
0301     struct rockchip_usb2phy *rphy =
0302         container_of(hw, struct rockchip_usb2phy, clk480m_hw);
0303     struct regmap *base = get_reg_base(rphy);
0304 
0305     return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
0306 }
0307 
0308 static unsigned long
0309 rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
0310                      unsigned long parent_rate)
0311 {
0312     return 480000000;
0313 }
0314 
0315 static const struct clk_ops rockchip_usb2phy_clkout_ops = {
0316     .prepare = rockchip_usb2phy_clk480m_prepare,
0317     .unprepare = rockchip_usb2phy_clk480m_unprepare,
0318     .is_prepared = rockchip_usb2phy_clk480m_prepared,
0319     .recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
0320 };
0321 
0322 static void rockchip_usb2phy_clk480m_unregister(void *data)
0323 {
0324     struct rockchip_usb2phy *rphy = data;
0325 
0326     of_clk_del_provider(rphy->dev->of_node);
0327     clk_unregister(rphy->clk480m);
0328 }
0329 
0330 static int
0331 rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
0332 {
0333     struct device_node *node = rphy->dev->of_node;
0334     struct clk_init_data init;
0335     const char *clk_name;
0336     int ret = 0;
0337 
0338     init.flags = 0;
0339     init.name = "clk_usbphy_480m";
0340     init.ops = &rockchip_usb2phy_clkout_ops;
0341 
0342     /* optional override of the clockname */
0343     of_property_read_string(node, "clock-output-names", &init.name);
0344 
0345     if (rphy->clk) {
0346         clk_name = __clk_get_name(rphy->clk);
0347         init.parent_names = &clk_name;
0348         init.num_parents = 1;
0349     } else {
0350         init.parent_names = NULL;
0351         init.num_parents = 0;
0352     }
0353 
0354     rphy->clk480m_hw.init = &init;
0355 
0356     /* register the clock */
0357     rphy->clk480m = clk_register(rphy->dev, &rphy->clk480m_hw);
0358     if (IS_ERR(rphy->clk480m)) {
0359         ret = PTR_ERR(rphy->clk480m);
0360         goto err_ret;
0361     }
0362 
0363     ret = of_clk_add_provider(node, of_clk_src_simple_get, rphy->clk480m);
0364     if (ret < 0)
0365         goto err_clk_provider;
0366 
0367     return devm_add_action_or_reset(rphy->dev, rockchip_usb2phy_clk480m_unregister, rphy);
0368 
0369 err_clk_provider:
0370     clk_unregister(rphy->clk480m);
0371 err_ret:
0372     return ret;
0373 }
0374 
0375 static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
0376 {
0377     int ret;
0378     struct device_node *node = rphy->dev->of_node;
0379     struct extcon_dev *edev;
0380 
0381     if (of_property_read_bool(node, "extcon")) {
0382         edev = extcon_get_edev_by_phandle(rphy->dev, 0);
0383         if (IS_ERR(edev)) {
0384             if (PTR_ERR(edev) != -EPROBE_DEFER)
0385                 dev_err(rphy->dev, "Invalid or missing extcon\n");
0386             return PTR_ERR(edev);
0387         }
0388     } else {
0389         /* Initialize extcon device */
0390         edev = devm_extcon_dev_allocate(rphy->dev,
0391                         rockchip_usb2phy_extcon_cable);
0392 
0393         if (IS_ERR(edev))
0394             return -ENOMEM;
0395 
0396         ret = devm_extcon_dev_register(rphy->dev, edev);
0397         if (ret) {
0398             dev_err(rphy->dev, "failed to register extcon device\n");
0399             return ret;
0400         }
0401     }
0402 
0403     rphy->edev = edev;
0404 
0405     return 0;
0406 }
0407 
0408 static int rockchip_usb2phy_init(struct phy *phy)
0409 {
0410     struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0411     struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
0412     int ret = 0;
0413 
0414     mutex_lock(&rport->mutex);
0415 
0416     if (rport->port_id == USB2PHY_PORT_OTG) {
0417         if (rport->mode != USB_DR_MODE_HOST &&
0418             rport->mode != USB_DR_MODE_UNKNOWN) {
0419             /* clear bvalid status and enable bvalid detect irq */
0420             ret = property_enable(rphy->grf,
0421                           &rport->port_cfg->bvalid_det_clr,
0422                           true);
0423             if (ret)
0424                 goto out;
0425 
0426             ret = property_enable(rphy->grf,
0427                           &rport->port_cfg->bvalid_det_en,
0428                           true);
0429             if (ret)
0430                 goto out;
0431 
0432             /* clear id status and enable id detect irq */
0433             ret = property_enable(rphy->grf,
0434                           &rport->port_cfg->id_det_clr,
0435                           true);
0436             if (ret)
0437                 goto out;
0438 
0439             ret = property_enable(rphy->grf,
0440                           &rport->port_cfg->id_det_en,
0441                           true);
0442             if (ret)
0443                 goto out;
0444 
0445             schedule_delayed_work(&rport->otg_sm_work,
0446                           OTG_SCHEDULE_DELAY * 3);
0447         } else {
0448             /* If OTG works in host only mode, do nothing. */
0449             dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
0450         }
0451     } else if (rport->port_id == USB2PHY_PORT_HOST) {
0452         /* clear linestate and enable linestate detect irq */
0453         ret = property_enable(rphy->grf,
0454                       &rport->port_cfg->ls_det_clr, true);
0455         if (ret)
0456             goto out;
0457 
0458         ret = property_enable(rphy->grf,
0459                       &rport->port_cfg->ls_det_en, true);
0460         if (ret)
0461             goto out;
0462 
0463         schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
0464     }
0465 
0466 out:
0467     mutex_unlock(&rport->mutex);
0468     return ret;
0469 }
0470 
0471 static int rockchip_usb2phy_power_on(struct phy *phy)
0472 {
0473     struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0474     struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
0475     struct regmap *base = get_reg_base(rphy);
0476     int ret;
0477 
0478     dev_dbg(&rport->phy->dev, "port power on\n");
0479 
0480     if (!rport->suspended)
0481         return 0;
0482 
0483     ret = clk_prepare_enable(rphy->clk480m);
0484     if (ret)
0485         return ret;
0486 
0487     ret = property_enable(base, &rport->port_cfg->phy_sus, false);
0488     if (ret)
0489         return ret;
0490 
0491     /* waiting for the utmi_clk to become stable */
0492     usleep_range(1500, 2000);
0493 
0494     rport->suspended = false;
0495     return 0;
0496 }
0497 
0498 static int rockchip_usb2phy_power_off(struct phy *phy)
0499 {
0500     struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0501     struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
0502     struct regmap *base = get_reg_base(rphy);
0503     int ret;
0504 
0505     dev_dbg(&rport->phy->dev, "port power off\n");
0506 
0507     if (rport->suspended)
0508         return 0;
0509 
0510     ret = property_enable(base, &rport->port_cfg->phy_sus, true);
0511     if (ret)
0512         return ret;
0513 
0514     rport->suspended = true;
0515     clk_disable_unprepare(rphy->clk480m);
0516 
0517     return 0;
0518 }
0519 
0520 static int rockchip_usb2phy_exit(struct phy *phy)
0521 {
0522     struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0523 
0524     if (rport->port_id == USB2PHY_PORT_OTG &&
0525         rport->mode != USB_DR_MODE_HOST &&
0526         rport->mode != USB_DR_MODE_UNKNOWN) {
0527         cancel_delayed_work_sync(&rport->otg_sm_work);
0528         cancel_delayed_work_sync(&rport->chg_work);
0529     } else if (rport->port_id == USB2PHY_PORT_HOST)
0530         cancel_delayed_work_sync(&rport->sm_work);
0531 
0532     return 0;
0533 }
0534 
0535 static const struct phy_ops rockchip_usb2phy_ops = {
0536     .init       = rockchip_usb2phy_init,
0537     .exit       = rockchip_usb2phy_exit,
0538     .power_on   = rockchip_usb2phy_power_on,
0539     .power_off  = rockchip_usb2phy_power_off,
0540     .owner      = THIS_MODULE,
0541 };
0542 
0543 static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
0544 {
0545     struct rockchip_usb2phy_port *rport =
0546         container_of(work, struct rockchip_usb2phy_port,
0547                  otg_sm_work.work);
0548     struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0549     static unsigned int cable;
0550     unsigned long delay;
0551     bool vbus_attach, sch_work, notify_charger;
0552 
0553     vbus_attach = property_enabled(rphy->grf,
0554                        &rport->port_cfg->utmi_bvalid);
0555 
0556     sch_work = false;
0557     notify_charger = false;
0558     delay = OTG_SCHEDULE_DELAY;
0559     dev_dbg(&rport->phy->dev, "%s otg sm work\n",
0560         usb_otg_state_string(rport->state));
0561 
0562     switch (rport->state) {
0563     case OTG_STATE_UNDEFINED:
0564         rport->state = OTG_STATE_B_IDLE;
0565         if (!vbus_attach)
0566             rockchip_usb2phy_power_off(rport->phy);
0567         fallthrough;
0568     case OTG_STATE_B_IDLE:
0569         if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
0570             dev_dbg(&rport->phy->dev, "usb otg host connect\n");
0571             rport->state = OTG_STATE_A_HOST;
0572             rockchip_usb2phy_power_on(rport->phy);
0573             return;
0574         } else if (vbus_attach) {
0575             dev_dbg(&rport->phy->dev, "vbus_attach\n");
0576             switch (rphy->chg_state) {
0577             case USB_CHG_STATE_UNDEFINED:
0578                 schedule_delayed_work(&rport->chg_work, 0);
0579                 return;
0580             case USB_CHG_STATE_DETECTED:
0581                 switch (rphy->chg_type) {
0582                 case POWER_SUPPLY_TYPE_USB:
0583                     dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
0584                     rockchip_usb2phy_power_on(rport->phy);
0585                     rport->state = OTG_STATE_B_PERIPHERAL;
0586                     notify_charger = true;
0587                     sch_work = true;
0588                     cable = EXTCON_CHG_USB_SDP;
0589                     break;
0590                 case POWER_SUPPLY_TYPE_USB_DCP:
0591                     dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
0592                     rockchip_usb2phy_power_off(rport->phy);
0593                     notify_charger = true;
0594                     sch_work = true;
0595                     cable = EXTCON_CHG_USB_DCP;
0596                     break;
0597                 case POWER_SUPPLY_TYPE_USB_CDP:
0598                     dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
0599                     rockchip_usb2phy_power_on(rport->phy);
0600                     rport->state = OTG_STATE_B_PERIPHERAL;
0601                     notify_charger = true;
0602                     sch_work = true;
0603                     cable = EXTCON_CHG_USB_CDP;
0604                     break;
0605                 default:
0606                     break;
0607                 }
0608                 break;
0609             default:
0610                 break;
0611             }
0612         } else {
0613             notify_charger = true;
0614             rphy->chg_state = USB_CHG_STATE_UNDEFINED;
0615             rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
0616         }
0617 
0618         if (rport->vbus_attached != vbus_attach) {
0619             rport->vbus_attached = vbus_attach;
0620 
0621             if (notify_charger && rphy->edev) {
0622                 extcon_set_state_sync(rphy->edev,
0623                             cable, vbus_attach);
0624                 if (cable == EXTCON_CHG_USB_SDP)
0625                     extcon_set_state_sync(rphy->edev,
0626                                   EXTCON_USB,
0627                                   vbus_attach);
0628             }
0629         }
0630         break;
0631     case OTG_STATE_B_PERIPHERAL:
0632         if (!vbus_attach) {
0633             dev_dbg(&rport->phy->dev, "usb disconnect\n");
0634             rphy->chg_state = USB_CHG_STATE_UNDEFINED;
0635             rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
0636             rport->state = OTG_STATE_B_IDLE;
0637             delay = 0;
0638             rockchip_usb2phy_power_off(rport->phy);
0639         }
0640         sch_work = true;
0641         break;
0642     case OTG_STATE_A_HOST:
0643         if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
0644             dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
0645             rport->state = OTG_STATE_B_IDLE;
0646             rockchip_usb2phy_power_off(rport->phy);
0647         }
0648         break;
0649     default:
0650         break;
0651     }
0652 
0653     if (sch_work)
0654         schedule_delayed_work(&rport->otg_sm_work, delay);
0655 }
0656 
0657 static const char *chg_to_string(enum power_supply_type chg_type)
0658 {
0659     switch (chg_type) {
0660     case POWER_SUPPLY_TYPE_USB:
0661         return "USB_SDP_CHARGER";
0662     case POWER_SUPPLY_TYPE_USB_DCP:
0663         return "USB_DCP_CHARGER";
0664     case POWER_SUPPLY_TYPE_USB_CDP:
0665         return "USB_CDP_CHARGER";
0666     default:
0667         return "INVALID_CHARGER";
0668     }
0669 }
0670 
0671 static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
0672                     bool en)
0673 {
0674     struct regmap *base = get_reg_base(rphy);
0675 
0676     property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
0677     property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
0678 }
0679 
0680 static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
0681                         bool en)
0682 {
0683     struct regmap *base = get_reg_base(rphy);
0684 
0685     property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
0686     property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
0687 }
0688 
0689 static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
0690                           bool en)
0691 {
0692     struct regmap *base = get_reg_base(rphy);
0693 
0694     property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
0695     property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
0696 }
0697 
0698 #define CHG_DCD_POLL_TIME   (100 * HZ / 1000)
0699 #define CHG_DCD_MAX_RETRIES 6
0700 #define CHG_PRIMARY_DET_TIME    (40 * HZ / 1000)
0701 #define CHG_SECONDARY_DET_TIME  (40 * HZ / 1000)
0702 static void rockchip_chg_detect_work(struct work_struct *work)
0703 {
0704     struct rockchip_usb2phy_port *rport =
0705         container_of(work, struct rockchip_usb2phy_port, chg_work.work);
0706     struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0707     struct regmap *base = get_reg_base(rphy);
0708     bool is_dcd, tmout, vout;
0709     unsigned long delay;
0710 
0711     dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
0712         rphy->chg_state);
0713     switch (rphy->chg_state) {
0714     case USB_CHG_STATE_UNDEFINED:
0715         if (!rport->suspended)
0716             rockchip_usb2phy_power_off(rport->phy);
0717         /* put the controller in non-driving mode */
0718         property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
0719         /* Start DCD processing stage 1 */
0720         rockchip_chg_enable_dcd(rphy, true);
0721         rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
0722         rphy->dcd_retries = 0;
0723         delay = CHG_DCD_POLL_TIME;
0724         break;
0725     case USB_CHG_STATE_WAIT_FOR_DCD:
0726         /* get data contact detection status */
0727         is_dcd = property_enabled(rphy->grf,
0728                       &rphy->phy_cfg->chg_det.dp_det);
0729         tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
0730         /* stage 2 */
0731         if (is_dcd || tmout) {
0732             /* stage 4 */
0733             /* Turn off DCD circuitry */
0734             rockchip_chg_enable_dcd(rphy, false);
0735             /* Voltage Source on DP, Probe on DM */
0736             rockchip_chg_enable_primary_det(rphy, true);
0737             delay = CHG_PRIMARY_DET_TIME;
0738             rphy->chg_state = USB_CHG_STATE_DCD_DONE;
0739         } else {
0740             /* stage 3 */
0741             delay = CHG_DCD_POLL_TIME;
0742         }
0743         break;
0744     case USB_CHG_STATE_DCD_DONE:
0745         vout = property_enabled(rphy->grf,
0746                     &rphy->phy_cfg->chg_det.cp_det);
0747         rockchip_chg_enable_primary_det(rphy, false);
0748         if (vout) {
0749             /* Voltage Source on DM, Probe on DP  */
0750             rockchip_chg_enable_secondary_det(rphy, true);
0751             delay = CHG_SECONDARY_DET_TIME;
0752             rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
0753         } else {
0754             if (rphy->dcd_retries == CHG_DCD_MAX_RETRIES) {
0755                 /* floating charger found */
0756                 rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
0757                 rphy->chg_state = USB_CHG_STATE_DETECTED;
0758                 delay = 0;
0759             } else {
0760                 rphy->chg_type = POWER_SUPPLY_TYPE_USB;
0761                 rphy->chg_state = USB_CHG_STATE_DETECTED;
0762                 delay = 0;
0763             }
0764         }
0765         break;
0766     case USB_CHG_STATE_PRIMARY_DONE:
0767         vout = property_enabled(rphy->grf,
0768                     &rphy->phy_cfg->chg_det.dcp_det);
0769         /* Turn off voltage source */
0770         rockchip_chg_enable_secondary_det(rphy, false);
0771         if (vout)
0772             rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
0773         else
0774             rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
0775         fallthrough;
0776     case USB_CHG_STATE_SECONDARY_DONE:
0777         rphy->chg_state = USB_CHG_STATE_DETECTED;
0778         fallthrough;
0779     case USB_CHG_STATE_DETECTED:
0780         /* put the controller in normal mode */
0781         property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
0782         rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
0783         dev_dbg(&rport->phy->dev, "charger = %s\n",
0784              chg_to_string(rphy->chg_type));
0785         return;
0786     default:
0787         return;
0788     }
0789 
0790     schedule_delayed_work(&rport->chg_work, delay);
0791 }
0792 
0793 /*
0794  * The function manage host-phy port state and suspend/resume phy port
0795  * to save power.
0796  *
0797  * we rely on utmi_linestate and utmi_hostdisconnect to identify whether
0798  * devices is disconnect or not. Besides, we do not need care it is FS/LS
0799  * disconnected or HS disconnected, actually, we just only need get the
0800  * device is disconnected at last through rearm the delayed work,
0801  * to suspend the phy port in _PHY_STATE_DISCONNECT_ case.
0802  *
0803  * NOTE: It may invoke *phy_powr_off or *phy_power_on which will invoke
0804  * some clk related APIs, so do not invoke it from interrupt context directly.
0805  */
0806 static void rockchip_usb2phy_sm_work(struct work_struct *work)
0807 {
0808     struct rockchip_usb2phy_port *rport =
0809         container_of(work, struct rockchip_usb2phy_port, sm_work.work);
0810     struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0811     unsigned int sh = rport->port_cfg->utmi_hstdet.bitend -
0812               rport->port_cfg->utmi_hstdet.bitstart + 1;
0813     unsigned int ul, uhd, state;
0814     unsigned int ul_mask, uhd_mask;
0815     int ret;
0816 
0817     mutex_lock(&rport->mutex);
0818 
0819     ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
0820     if (ret < 0)
0821         goto next_schedule;
0822 
0823     ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
0824     if (ret < 0)
0825         goto next_schedule;
0826 
0827     uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
0828                rport->port_cfg->utmi_hstdet.bitstart);
0829     ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
0830               rport->port_cfg->utmi_ls.bitstart);
0831 
0832     /* stitch on utmi_ls and utmi_hstdet as phy state */
0833     state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
0834         (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
0835 
0836     switch (state) {
0837     case PHY_STATE_HS_ONLINE:
0838         dev_dbg(&rport->phy->dev, "HS online\n");
0839         break;
0840     case PHY_STATE_FS_LS_ONLINE:
0841         /*
0842          * For FS/LS device, the online state share with connect state
0843          * from utmi_ls and utmi_hstdet register, so we distinguish
0844          * them via suspended flag.
0845          *
0846          * Plus, there are two cases, one is D- Line pull-up, and D+
0847          * line pull-down, the state is 4; another is D+ line pull-up,
0848          * and D- line pull-down, the state is 2.
0849          */
0850         if (!rport->suspended) {
0851             /* D- line pull-up, D+ line pull-down */
0852             dev_dbg(&rport->phy->dev, "FS/LS online\n");
0853             break;
0854         }
0855         fallthrough;
0856     case PHY_STATE_CONNECT:
0857         if (rport->suspended) {
0858             dev_dbg(&rport->phy->dev, "Connected\n");
0859             rockchip_usb2phy_power_on(rport->phy);
0860             rport->suspended = false;
0861         } else {
0862             /* D+ line pull-up, D- line pull-down */
0863             dev_dbg(&rport->phy->dev, "FS/LS online\n");
0864         }
0865         break;
0866     case PHY_STATE_DISCONNECT:
0867         if (!rport->suspended) {
0868             dev_dbg(&rport->phy->dev, "Disconnected\n");
0869             rockchip_usb2phy_power_off(rport->phy);
0870             rport->suspended = true;
0871         }
0872 
0873         /*
0874          * activate the linestate detection to get the next device
0875          * plug-in irq.
0876          */
0877         property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
0878         property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
0879 
0880         /*
0881          * we don't need to rearm the delayed work when the phy port
0882          * is suspended.
0883          */
0884         mutex_unlock(&rport->mutex);
0885         return;
0886     default:
0887         dev_dbg(&rport->phy->dev, "unknown phy state\n");
0888         break;
0889     }
0890 
0891 next_schedule:
0892     mutex_unlock(&rport->mutex);
0893     schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
0894 }
0895 
0896 static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
0897 {
0898     struct rockchip_usb2phy_port *rport = data;
0899     struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0900 
0901     if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
0902         return IRQ_NONE;
0903 
0904     mutex_lock(&rport->mutex);
0905 
0906     /* disable linestate detect irq and clear its status */
0907     property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
0908     property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
0909 
0910     mutex_unlock(&rport->mutex);
0911 
0912     /*
0913      * In this case for host phy port, a new device is plugged in,
0914      * meanwhile, if the phy port is suspended, we need rearm the work to
0915      * resume it and mange its states; otherwise, we do nothing about that.
0916      */
0917     if (rport->suspended && rport->port_id == USB2PHY_PORT_HOST)
0918         rockchip_usb2phy_sm_work(&rport->sm_work.work);
0919 
0920     return IRQ_HANDLED;
0921 }
0922 
0923 static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
0924 {
0925     struct rockchip_usb2phy_port *rport = data;
0926     struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0927 
0928     if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
0929         return IRQ_NONE;
0930 
0931     /* clear bvalid detect irq pending status */
0932     property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
0933 
0934     rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
0935 
0936     return IRQ_HANDLED;
0937 }
0938 
0939 static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
0940 {
0941     struct rockchip_usb2phy_port *rport = data;
0942     struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0943     bool id;
0944 
0945     if (!property_enabled(rphy->grf, &rport->port_cfg->id_det_st))
0946         return IRQ_NONE;
0947 
0948     /* clear id detect irq pending status */
0949     property_enable(rphy->grf, &rport->port_cfg->id_det_clr, true);
0950 
0951     id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
0952     extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
0953 
0954     return IRQ_HANDLED;
0955 }
0956 
0957 static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
0958 {
0959     irqreturn_t ret = IRQ_NONE;
0960 
0961     ret |= rockchip_usb2phy_bvalid_irq(irq, data);
0962     ret |= rockchip_usb2phy_id_irq(irq, data);
0963 
0964     return ret;
0965 }
0966 
0967 static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
0968 {
0969     struct rockchip_usb2phy *rphy = data;
0970     struct rockchip_usb2phy_port *rport;
0971     irqreturn_t ret = IRQ_NONE;
0972     unsigned int index;
0973 
0974     for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
0975         rport = &rphy->ports[index];
0976         if (!rport->phy)
0977             continue;
0978 
0979         switch (rport->port_id) {
0980         case USB2PHY_PORT_OTG:
0981             if (rport->mode != USB_DR_MODE_HOST &&
0982                 rport->mode != USB_DR_MODE_UNKNOWN)
0983                 ret |= rockchip_usb2phy_otg_mux_irq(irq, rport);
0984             break;
0985         case USB2PHY_PORT_HOST:
0986             ret |= rockchip_usb2phy_linestate_irq(irq, rport);
0987             break;
0988         }
0989     }
0990 
0991     return ret;
0992 }
0993 
0994 static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
0995                       struct rockchip_usb2phy_port *rport,
0996                       struct device_node *child_np)
0997 {
0998     int ret;
0999 
1000     /*
1001      * If the usb2 phy used combined irq for otg and host port,
1002      * don't need to init otg and host port irq separately.
1003      */
1004     if (rphy->irq > 0)
1005         return 0;
1006 
1007     switch (rport->port_id) {
1008     case USB2PHY_PORT_HOST:
1009         rport->ls_irq = of_irq_get_byname(child_np, "linestate");
1010         if (rport->ls_irq < 0) {
1011             dev_err(rphy->dev, "no linestate irq provided\n");
1012             return rport->ls_irq;
1013         }
1014 
1015         ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
1016                         rockchip_usb2phy_linestate_irq,
1017                         IRQF_ONESHOT,
1018                         "rockchip_usb2phy", rport);
1019         if (ret) {
1020             dev_err(rphy->dev, "failed to request linestate irq handle\n");
1021             return ret;
1022         }
1023         break;
1024     case USB2PHY_PORT_OTG:
1025         /*
1026          * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
1027          * interrupts muxed together, so probe the otg-mux interrupt first,
1028          * if not found, then look for the regular interrupts one by one.
1029          */
1030         rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
1031         if (rport->otg_mux_irq > 0) {
1032             ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
1033                             NULL,
1034                             rockchip_usb2phy_otg_mux_irq,
1035                             IRQF_ONESHOT,
1036                             "rockchip_usb2phy_otg",
1037                             rport);
1038             if (ret) {
1039                 dev_err(rphy->dev,
1040                     "failed to request otg-mux irq handle\n");
1041                 return ret;
1042             }
1043         } else {
1044             rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
1045             if (rport->bvalid_irq < 0) {
1046                 dev_err(rphy->dev, "no vbus valid irq provided\n");
1047                 ret = rport->bvalid_irq;
1048                 return ret;
1049             }
1050 
1051             ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
1052                             NULL,
1053                             rockchip_usb2phy_bvalid_irq,
1054                             IRQF_ONESHOT,
1055                             "rockchip_usb2phy_bvalid",
1056                             rport);
1057             if (ret) {
1058                 dev_err(rphy->dev,
1059                     "failed to request otg-bvalid irq handle\n");
1060                 return ret;
1061             }
1062 
1063             rport->id_irq = of_irq_get_byname(child_np, "otg-id");
1064             if (rport->id_irq < 0) {
1065                 dev_err(rphy->dev, "no otg-id irq provided\n");
1066                 ret = rport->id_irq;
1067                 return ret;
1068             }
1069 
1070             ret = devm_request_threaded_irq(rphy->dev, rport->id_irq,
1071                             NULL,
1072                             rockchip_usb2phy_id_irq,
1073                             IRQF_ONESHOT,
1074                             "rockchip_usb2phy_id",
1075                             rport);
1076             if (ret) {
1077                 dev_err(rphy->dev,
1078                     "failed to request otg-id irq handle\n");
1079                 return ret;
1080             }
1081         }
1082         break;
1083     default:
1084         return -EINVAL;
1085     }
1086 
1087     return 0;
1088 }
1089 
1090 static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
1091                        struct rockchip_usb2phy_port *rport,
1092                        struct device_node *child_np)
1093 {
1094     int ret;
1095 
1096     rport->port_id = USB2PHY_PORT_HOST;
1097     rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
1098     rport->suspended = true;
1099 
1100     mutex_init(&rport->mutex);
1101     INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
1102 
1103     ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1104     if (ret) {
1105         dev_err(rphy->dev, "failed to setup host irq\n");
1106         return ret;
1107     }
1108 
1109     return 0;
1110 }
1111 
1112 static int rockchip_otg_event(struct notifier_block *nb,
1113                   unsigned long event, void *ptr)
1114 {
1115     struct rockchip_usb2phy_port *rport =
1116         container_of(nb, struct rockchip_usb2phy_port, event_nb);
1117 
1118     schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
1119 
1120     return NOTIFY_DONE;
1121 }
1122 
1123 static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
1124                       struct rockchip_usb2phy_port *rport,
1125                       struct device_node *child_np)
1126 {
1127     int ret;
1128 
1129     rport->port_id = USB2PHY_PORT_OTG;
1130     rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
1131     rport->state = OTG_STATE_UNDEFINED;
1132 
1133     /*
1134      * set suspended flag to true, but actually don't
1135      * put phy in suspend mode, it aims to enable usb
1136      * phy and clock in power_on() called by usb controller
1137      * driver during probe.
1138      */
1139     rport->suspended = true;
1140     rport->vbus_attached = false;
1141 
1142     mutex_init(&rport->mutex);
1143 
1144     rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
1145     if (rport->mode == USB_DR_MODE_HOST ||
1146         rport->mode == USB_DR_MODE_UNKNOWN) {
1147         ret = 0;
1148         goto out;
1149     }
1150 
1151     INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
1152     INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
1153 
1154     ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1155     if (ret) {
1156         dev_err(rphy->dev, "failed to init irq for host port\n");
1157         goto out;
1158     }
1159 
1160     if (!IS_ERR(rphy->edev)) {
1161         rport->event_nb.notifier_call = rockchip_otg_event;
1162 
1163         ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
1164                     EXTCON_USB_HOST, &rport->event_nb);
1165         if (ret)
1166             dev_err(rphy->dev, "register USB HOST notifier failed\n");
1167 
1168         if (!of_property_read_bool(rphy->dev->of_node, "extcon")) {
1169             /* do initial sync of usb state */
1170             ret = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
1171             extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !ret);
1172         }
1173     }
1174 
1175 out:
1176     return ret;
1177 }
1178 
1179 static int rockchip_usb2phy_probe(struct platform_device *pdev)
1180 {
1181     struct device *dev = &pdev->dev;
1182     struct device_node *np = dev->of_node;
1183     struct device_node *child_np;
1184     struct phy_provider *provider;
1185     struct rockchip_usb2phy *rphy;
1186     const struct rockchip_usb2phy_cfg *phy_cfgs;
1187     const struct of_device_id *match;
1188     unsigned int reg;
1189     int index, ret;
1190 
1191     rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
1192     if (!rphy)
1193         return -ENOMEM;
1194 
1195     match = of_match_device(dev->driver->of_match_table, dev);
1196     if (!match || !match->data) {
1197         dev_err(dev, "phy configs are not assigned!\n");
1198         return -EINVAL;
1199     }
1200 
1201     if (!dev->parent || !dev->parent->of_node) {
1202         rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
1203         if (IS_ERR(rphy->grf)) {
1204             dev_err(dev, "failed to locate usbgrf\n");
1205             return PTR_ERR(rphy->grf);
1206         }
1207     }
1208 
1209     else {
1210         rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
1211         if (IS_ERR(rphy->grf))
1212             return PTR_ERR(rphy->grf);
1213     }
1214 
1215     if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
1216         rphy->usbgrf =
1217             syscon_regmap_lookup_by_phandle(dev->of_node,
1218                             "rockchip,usbgrf");
1219         if (IS_ERR(rphy->usbgrf))
1220             return PTR_ERR(rphy->usbgrf);
1221     } else {
1222         rphy->usbgrf = NULL;
1223     }
1224 
1225     if (of_property_read_u32_index(np, "reg", 0, &reg)) {
1226         dev_err(dev, "the reg property is not assigned in %pOFn node\n",
1227             np);
1228         return -EINVAL;
1229     }
1230 
1231     /* support address_cells=2 */
1232     if (reg == 0) {
1233         if (of_property_read_u32_index(np, "reg", 1, &reg)) {
1234             dev_err(dev, "the reg property is not assigned in %pOFn node\n",
1235                 np);
1236             return -EINVAL;
1237         }
1238     }
1239 
1240     rphy->dev = dev;
1241     phy_cfgs = match->data;
1242     rphy->chg_state = USB_CHG_STATE_UNDEFINED;
1243     rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
1244     rphy->irq = platform_get_irq_optional(pdev, 0);
1245     platform_set_drvdata(pdev, rphy);
1246 
1247     ret = rockchip_usb2phy_extcon_register(rphy);
1248     if (ret)
1249         return ret;
1250 
1251     /* find out a proper config which can be matched with dt. */
1252     index = 0;
1253     while (phy_cfgs[index].reg) {
1254         if (phy_cfgs[index].reg == reg) {
1255             rphy->phy_cfg = &phy_cfgs[index];
1256             break;
1257         }
1258 
1259         ++index;
1260     }
1261 
1262     if (!rphy->phy_cfg) {
1263         dev_err(dev, "no phy-config can be matched with %pOFn node\n",
1264             np);
1265         return -EINVAL;
1266     }
1267 
1268     rphy->clk = of_clk_get_by_name(np, "phyclk");
1269     if (!IS_ERR(rphy->clk)) {
1270         clk_prepare_enable(rphy->clk);
1271     } else {
1272         dev_info(&pdev->dev, "no phyclk specified\n");
1273         rphy->clk = NULL;
1274     }
1275 
1276     ret = rockchip_usb2phy_clk480m_register(rphy);
1277     if (ret) {
1278         dev_err(dev, "failed to register 480m output clock\n");
1279         goto disable_clks;
1280     }
1281 
1282     index = 0;
1283     for_each_available_child_of_node(np, child_np) {
1284         struct rockchip_usb2phy_port *rport = &rphy->ports[index];
1285         struct phy *phy;
1286 
1287         /* This driver aims to support both otg-port and host-port */
1288         if (!of_node_name_eq(child_np, "host-port") &&
1289             !of_node_name_eq(child_np, "otg-port"))
1290             goto next_child;
1291 
1292         phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
1293         if (IS_ERR(phy)) {
1294             dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
1295             ret = PTR_ERR(phy);
1296             goto put_child;
1297         }
1298 
1299         rport->phy = phy;
1300         phy_set_drvdata(rport->phy, rport);
1301 
1302         /* initialize otg/host port separately */
1303         if (of_node_name_eq(child_np, "host-port")) {
1304             ret = rockchip_usb2phy_host_port_init(rphy, rport,
1305                                   child_np);
1306             if (ret)
1307                 goto put_child;
1308         } else {
1309             ret = rockchip_usb2phy_otg_port_init(rphy, rport,
1310                                  child_np);
1311             if (ret)
1312                 goto put_child;
1313         }
1314 
1315 next_child:
1316         /* to prevent out of boundary */
1317         if (++index >= rphy->phy_cfg->num_ports) {
1318             of_node_put(child_np);
1319             break;
1320         }
1321     }
1322 
1323     provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1324 
1325     if (rphy->irq > 0) {
1326         ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
1327                         rockchip_usb2phy_irq,
1328                         IRQF_ONESHOT,
1329                         "rockchip_usb2phy",
1330                         rphy);
1331         if (ret) {
1332             dev_err(rphy->dev,
1333                 "failed to request usb2phy irq handle\n");
1334             goto put_child;
1335         }
1336     }
1337 
1338     return PTR_ERR_OR_ZERO(provider);
1339 
1340 put_child:
1341     of_node_put(child_np);
1342 disable_clks:
1343     if (rphy->clk) {
1344         clk_disable_unprepare(rphy->clk);
1345         clk_put(rphy->clk);
1346     }
1347     return ret;
1348 }
1349 
1350 static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
1351     {
1352         .reg = 0x760,
1353         .num_ports  = 2,
1354         .clkout_ctl = { 0x0768, 4, 4, 1, 0 },
1355         .port_cfgs  = {
1356             [USB2PHY_PORT_OTG] = {
1357                 .phy_sus    = { 0x0760, 15, 0, 0, 0x1d1 },
1358                 .bvalid_det_en  = { 0x0680, 3, 3, 0, 1 },
1359                 .bvalid_det_st  = { 0x0690, 3, 3, 0, 1 },
1360                 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
1361                 .id_det_en  = { 0x0680, 6, 5, 0, 3 },
1362                 .id_det_st  = { 0x0690, 6, 5, 0, 3 },
1363                 .id_det_clr = { 0x06a0, 6, 5, 0, 3 },
1364                 .ls_det_en  = { 0x0680, 2, 2, 0, 1 },
1365                 .ls_det_st  = { 0x0690, 2, 2, 0, 1 },
1366                 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
1367                 .utmi_bvalid    = { 0x0480, 4, 4, 0, 1 },
1368                 .utmi_id    = { 0x0480, 1, 1, 0, 1 },
1369                 .utmi_ls    = { 0x0480, 3, 2, 0, 1 },
1370             },
1371             [USB2PHY_PORT_HOST] = {
1372                 .phy_sus    = { 0x0764, 15, 0, 0, 0x1d1 },
1373                 .ls_det_en  = { 0x0680, 4, 4, 0, 1 },
1374                 .ls_det_st  = { 0x0690, 4, 4, 0, 1 },
1375                 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 }
1376             }
1377         },
1378         .chg_det = {
1379             .opmode     = { 0x0760, 3, 0, 5, 1 },
1380             .cp_det     = { 0x0884, 4, 4, 0, 1 },
1381             .dcp_det    = { 0x0884, 3, 3, 0, 1 },
1382             .dp_det     = { 0x0884, 5, 5, 0, 1 },
1383             .idm_sink_en    = { 0x0768, 8, 8, 0, 1 },
1384             .idp_sink_en    = { 0x0768, 7, 7, 0, 1 },
1385             .idp_src_en = { 0x0768, 9, 9, 0, 1 },
1386             .rdm_pdwn_en    = { 0x0768, 10, 10, 0, 1 },
1387             .vdm_src_en = { 0x0768, 12, 12, 0, 1 },
1388             .vdp_src_en = { 0x0768, 11, 11, 0, 1 },
1389         },
1390     },
1391     {
1392         .reg = 0x800,
1393         .num_ports  = 2,
1394         .clkout_ctl = { 0x0808, 4, 4, 1, 0 },
1395         .port_cfgs  = {
1396             [USB2PHY_PORT_OTG] = {
1397                 .phy_sus    = { 0x800, 15, 0, 0, 0x1d1 },
1398                 .ls_det_en  = { 0x0684, 0, 0, 0, 1 },
1399                 .ls_det_st  = { 0x0694, 0, 0, 0, 1 },
1400                 .ls_det_clr = { 0x06a4, 0, 0, 0, 1 }
1401             },
1402             [USB2PHY_PORT_HOST] = {
1403                 .phy_sus    = { 0x804, 15, 0, 0, 0x1d1 },
1404                 .ls_det_en  = { 0x0684, 1, 1, 0, 1 },
1405                 .ls_det_st  = { 0x0694, 1, 1, 0, 1 },
1406                 .ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
1407             }
1408         },
1409     },
1410     { /* sentinel */ }
1411 };
1412 
1413 static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
1414     {
1415         .reg = 0x100,
1416         .num_ports  = 2,
1417         .clkout_ctl = { 0x108, 4, 4, 1, 0 },
1418         .port_cfgs  = {
1419             [USB2PHY_PORT_OTG] = {
1420                 .phy_sus    = { 0x0100, 8, 0, 0, 0x1d1 },
1421                 .bvalid_det_en  = { 0x3020, 3, 2, 0, 3 },
1422                 .bvalid_det_st  = { 0x3024, 3, 2, 0, 3 },
1423                 .bvalid_det_clr = { 0x3028, 3, 2, 0, 3 },
1424                 .id_det_en  = { 0x3020, 5, 4, 0, 3 },
1425                 .id_det_st  = { 0x3024, 5, 4, 0, 3 },
1426                 .id_det_clr = { 0x3028, 5, 4, 0, 3 },
1427                 .ls_det_en  = { 0x3020, 0, 0, 0, 1 },
1428                 .ls_det_st  = { 0x3024, 0, 0, 0, 1 },
1429                 .ls_det_clr = { 0x3028, 0, 0, 0, 1 },
1430                 .utmi_avalid    = { 0x0120, 10, 10, 0, 1 },
1431                 .utmi_bvalid    = { 0x0120, 9, 9, 0, 1 },
1432                 .utmi_id    = { 0x0120, 6, 6, 0, 1 },
1433                 .utmi_ls    = { 0x0120, 5, 4, 0, 1 },
1434             },
1435             [USB2PHY_PORT_HOST] = {
1436                 .phy_sus    = { 0x0104, 8, 0, 0, 0x1d1 },
1437                 .ls_det_en  = { 0x3020, 1, 1, 0, 1 },
1438                 .ls_det_st  = { 0x3024, 1, 1, 0, 1 },
1439                 .ls_det_clr = { 0x3028, 1, 1, 0, 1 },
1440                 .utmi_ls    = { 0x0120, 17, 16, 0, 1 },
1441                 .utmi_hstdet    = { 0x0120, 19, 19, 0, 1 }
1442             }
1443         },
1444         .chg_det = {
1445             .opmode     = { 0x0100, 3, 0, 5, 1 },
1446             .cp_det     = { 0x0120, 24, 24, 0, 1 },
1447             .dcp_det    = { 0x0120, 23, 23, 0, 1 },
1448             .dp_det     = { 0x0120, 25, 25, 0, 1 },
1449             .idm_sink_en    = { 0x0108, 8, 8, 0, 1 },
1450             .idp_sink_en    = { 0x0108, 7, 7, 0, 1 },
1451             .idp_src_en = { 0x0108, 9, 9, 0, 1 },
1452             .rdm_pdwn_en    = { 0x0108, 10, 10, 0, 1 },
1453             .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
1454             .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
1455         },
1456     },
1457     { /* sentinel */ }
1458 };
1459 
1460 static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
1461     {
1462         .reg = 0x100,
1463         .num_ports  = 2,
1464         .clkout_ctl = { 0x108, 4, 4, 1, 0 },
1465         .port_cfgs  = {
1466             [USB2PHY_PORT_OTG] = {
1467                 .phy_sus    = { 0x0100, 15, 0, 0, 0x1d1 },
1468                 .bvalid_det_en  = { 0x0110, 3, 2, 0, 3 },
1469                 .bvalid_det_st  = { 0x0114, 3, 2, 0, 3 },
1470                 .bvalid_det_clr = { 0x0118, 3, 2, 0, 3 },
1471                 .id_det_en  = { 0x0110, 5, 4, 0, 3 },
1472                 .id_det_st  = { 0x0114, 5, 4, 0, 3 },
1473                 .id_det_clr = { 0x0118, 5, 4, 0, 3 },
1474                 .ls_det_en  = { 0x0110, 0, 0, 0, 1 },
1475                 .ls_det_st  = { 0x0114, 0, 0, 0, 1 },
1476                 .ls_det_clr = { 0x0118, 0, 0, 0, 1 },
1477                 .utmi_avalid    = { 0x0120, 10, 10, 0, 1 },
1478                 .utmi_bvalid    = { 0x0120, 9, 9, 0, 1 },
1479                 .utmi_id    = { 0x0120, 6, 6, 0, 1 },
1480                 .utmi_ls    = { 0x0120, 5, 4, 0, 1 },
1481             },
1482             [USB2PHY_PORT_HOST] = {
1483                 .phy_sus    = { 0x104, 15, 0, 0, 0x1d1 },
1484                 .ls_det_en  = { 0x110, 1, 1, 0, 1 },
1485                 .ls_det_st  = { 0x114, 1, 1, 0, 1 },
1486                 .ls_det_clr = { 0x118, 1, 1, 0, 1 },
1487                 .utmi_ls    = { 0x120, 17, 16, 0, 1 },
1488                 .utmi_hstdet    = { 0x120, 19, 19, 0, 1 }
1489             }
1490         },
1491         .chg_det = {
1492             .opmode     = { 0x0100, 3, 0, 5, 1 },
1493             .cp_det     = { 0x0120, 24, 24, 0, 1 },
1494             .dcp_det    = { 0x0120, 23, 23, 0, 1 },
1495             .dp_det     = { 0x0120, 25, 25, 0, 1 },
1496             .idm_sink_en    = { 0x0108, 8, 8, 0, 1 },
1497             .idp_sink_en    = { 0x0108, 7, 7, 0, 1 },
1498             .idp_src_en = { 0x0108, 9, 9, 0, 1 },
1499             .rdm_pdwn_en    = { 0x0108, 10, 10, 0, 1 },
1500             .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
1501             .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
1502         },
1503     },
1504     { /* sentinel */ }
1505 };
1506 
1507 static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
1508     {
1509         .reg = 0x700,
1510         .num_ports  = 2,
1511         .clkout_ctl = { 0x0724, 15, 15, 1, 0 },
1512         .port_cfgs  = {
1513             [USB2PHY_PORT_HOST] = {
1514                 .phy_sus    = { 0x0728, 15, 0, 0, 0x1d1 },
1515                 .ls_det_en  = { 0x0680, 4, 4, 0, 1 },
1516                 .ls_det_st  = { 0x0690, 4, 4, 0, 1 },
1517                 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 },
1518                 .utmi_ls    = { 0x049c, 14, 13, 0, 1 },
1519                 .utmi_hstdet    = { 0x049c, 12, 12, 0, 1 }
1520             }
1521         },
1522     },
1523     { /* sentinel */ }
1524 };
1525 
1526 static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
1527     {
1528         .reg        = 0xe450,
1529         .num_ports  = 2,
1530         .clkout_ctl = { 0xe450, 4, 4, 1, 0 },
1531         .port_cfgs  = {
1532             [USB2PHY_PORT_OTG] = {
1533                 .phy_sus    = { 0xe454, 1, 0, 2, 1 },
1534                 .bvalid_det_en  = { 0xe3c0, 3, 3, 0, 1 },
1535                 .bvalid_det_st  = { 0xe3e0, 3, 3, 0, 1 },
1536                 .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 },
1537                 .id_det_en  = { 0xe3c0, 5, 4, 0, 3 },
1538                 .id_det_st  = { 0xe3e0, 5, 4, 0, 3 },
1539                 .id_det_clr = { 0xe3d0, 5, 4, 0, 3 },
1540                 .utmi_avalid    = { 0xe2ac, 7, 7, 0, 1 },
1541                 .utmi_bvalid    = { 0xe2ac, 12, 12, 0, 1 },
1542                 .utmi_id    = { 0xe2ac, 8, 8, 0, 1 },
1543             },
1544             [USB2PHY_PORT_HOST] = {
1545                 .phy_sus    = { 0xe458, 1, 0, 0x2, 0x1 },
1546                 .ls_det_en  = { 0xe3c0, 6, 6, 0, 1 },
1547                 .ls_det_st  = { 0xe3e0, 6, 6, 0, 1 },
1548                 .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 },
1549                 .utmi_ls    = { 0xe2ac, 22, 21, 0, 1 },
1550                 .utmi_hstdet    = { 0xe2ac, 23, 23, 0, 1 }
1551             }
1552         },
1553         .chg_det = {
1554             .opmode     = { 0xe454, 3, 0, 5, 1 },
1555             .cp_det     = { 0xe2ac, 2, 2, 0, 1 },
1556             .dcp_det    = { 0xe2ac, 1, 1, 0, 1 },
1557             .dp_det     = { 0xe2ac, 0, 0, 0, 1 },
1558             .idm_sink_en    = { 0xe450, 8, 8, 0, 1 },
1559             .idp_sink_en    = { 0xe450, 7, 7, 0, 1 },
1560             .idp_src_en = { 0xe450, 9, 9, 0, 1 },
1561             .rdm_pdwn_en    = { 0xe450, 10, 10, 0, 1 },
1562             .vdm_src_en = { 0xe450, 12, 12, 0, 1 },
1563             .vdp_src_en = { 0xe450, 11, 11, 0, 1 },
1564         },
1565     },
1566     {
1567         .reg        = 0xe460,
1568         .num_ports  = 2,
1569         .clkout_ctl = { 0xe460, 4, 4, 1, 0 },
1570         .port_cfgs  = {
1571             [USB2PHY_PORT_OTG] = {
1572                 .phy_sus        = { 0xe464, 1, 0, 2, 1 },
1573                 .bvalid_det_en  = { 0xe3c0, 8, 8, 0, 1 },
1574                 .bvalid_det_st  = { 0xe3e0, 8, 8, 0, 1 },
1575                 .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
1576                 .id_det_en  = { 0xe3c0, 10, 9, 0, 3 },
1577                 .id_det_st  = { 0xe3e0, 10, 9, 0, 3 },
1578                 .id_det_clr = { 0xe3d0, 10, 9, 0, 3 },
1579                 .utmi_avalid    = { 0xe2ac, 10, 10, 0, 1 },
1580                 .utmi_bvalid    = { 0xe2ac, 16, 16, 0, 1 },
1581                 .utmi_id    = { 0xe2ac, 11, 11, 0, 1 },
1582             },
1583             [USB2PHY_PORT_HOST] = {
1584                 .phy_sus    = { 0xe468, 1, 0, 0x2, 0x1 },
1585                 .ls_det_en  = { 0xe3c0, 11, 11, 0, 1 },
1586                 .ls_det_st  = { 0xe3e0, 11, 11, 0, 1 },
1587                 .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 },
1588                 .utmi_ls    = { 0xe2ac, 26, 25, 0, 1 },
1589                 .utmi_hstdet    = { 0xe2ac, 27, 27, 0, 1 }
1590             }
1591         },
1592     },
1593     { /* sentinel */ }
1594 };
1595 
1596 static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
1597     {
1598         .reg = 0xfe8a0000,
1599         .num_ports  = 2,
1600         .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
1601         .port_cfgs  = {
1602             [USB2PHY_PORT_OTG] = {
1603                 .phy_sus    = { 0x0000, 8, 0, 0, 0x1d1 },
1604                 .bvalid_det_en  = { 0x0080, 3, 2, 0, 3 },
1605                 .bvalid_det_st  = { 0x0084, 3, 2, 0, 3 },
1606                 .bvalid_det_clr = { 0x0088, 3, 2, 0, 3 },
1607                 .id_det_en  = { 0x0080, 5, 4, 0, 3 },
1608                 .id_det_st  = { 0x0084, 5, 4, 0, 3 },
1609                 .id_det_clr = { 0x0088, 5, 4, 0, 3 },
1610                 .utmi_avalid    = { 0x00c0, 10, 10, 0, 1 },
1611                 .utmi_bvalid    = { 0x00c0, 9, 9, 0, 1 },
1612                 .utmi_id    = { 0x00c0, 6, 6, 0, 1 },
1613             },
1614             [USB2PHY_PORT_HOST] = {
1615                 /* Select suspend control from controller */
1616                 .phy_sus    = { 0x0004, 8, 0, 0x1d2, 0x1d2 },
1617                 .ls_det_en  = { 0x0080, 1, 1, 0, 1 },
1618                 .ls_det_st  = { 0x0084, 1, 1, 0, 1 },
1619                 .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
1620                 .utmi_ls    = { 0x00c0, 17, 16, 0, 1 },
1621                 .utmi_hstdet    = { 0x00c0, 19, 19, 0, 1 }
1622             }
1623         },
1624         .chg_det = {
1625             .opmode     = { 0x0000, 3, 0, 5, 1 },
1626             .cp_det     = { 0x00c0, 24, 24, 0, 1 },
1627             .dcp_det    = { 0x00c0, 23, 23, 0, 1 },
1628             .dp_det     = { 0x00c0, 25, 25, 0, 1 },
1629             .idm_sink_en    = { 0x0008, 8, 8, 0, 1 },
1630             .idp_sink_en    = { 0x0008, 7, 7, 0, 1 },
1631             .idp_src_en = { 0x0008, 9, 9, 0, 1 },
1632             .rdm_pdwn_en    = { 0x0008, 10, 10, 0, 1 },
1633             .vdm_src_en = { 0x0008, 12, 12, 0, 1 },
1634             .vdp_src_en = { 0x0008, 11, 11, 0, 1 },
1635         },
1636     },
1637     {
1638         .reg = 0xfe8b0000,
1639         .num_ports  = 2,
1640         .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
1641         .port_cfgs  = {
1642             [USB2PHY_PORT_OTG] = {
1643                 .phy_sus    = { 0x0000, 8, 0, 0x1d2, 0x1d1 },
1644                 .ls_det_en  = { 0x0080, 0, 0, 0, 1 },
1645                 .ls_det_st  = { 0x0084, 0, 0, 0, 1 },
1646                 .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
1647                 .utmi_ls    = { 0x00c0, 5, 4, 0, 1 },
1648                 .utmi_hstdet    = { 0x00c0, 7, 7, 0, 1 }
1649             },
1650             [USB2PHY_PORT_HOST] = {
1651                 .phy_sus    = { 0x0004, 8, 0, 0x1d2, 0x1d1 },
1652                 .ls_det_en  = { 0x0080, 1, 1, 0, 1 },
1653                 .ls_det_st  = { 0x0084, 1, 1, 0, 1 },
1654                 .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
1655                 .utmi_ls    = { 0x00c0, 17, 16, 0, 1 },
1656                 .utmi_hstdet    = { 0x00c0, 19, 19, 0, 1 }
1657             }
1658         },
1659     },
1660     { /* sentinel */ }
1661 };
1662 
1663 static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
1664     {
1665         .reg = 0x100,
1666         .num_ports  = 2,
1667         .clkout_ctl = { 0x108, 4, 4, 1, 0 },
1668         .port_cfgs  = {
1669             [USB2PHY_PORT_OTG] = {
1670                 .phy_sus    = { 0x0100, 15, 0, 0, 0x1d1 },
1671                 .bvalid_det_en  = { 0x0680, 3, 3, 0, 1 },
1672                 .bvalid_det_st  = { 0x0690, 3, 3, 0, 1 },
1673                 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
1674                 .ls_det_en  = { 0x0680, 2, 2, 0, 1 },
1675                 .ls_det_st  = { 0x0690, 2, 2, 0, 1 },
1676                 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
1677                 .utmi_bvalid    = { 0x0804, 10, 10, 0, 1 },
1678                 .utmi_ls    = { 0x0804, 13, 12, 0, 1 },
1679             },
1680             [USB2PHY_PORT_HOST] = {
1681                 .phy_sus    = { 0x0104, 15, 0, 0, 0x1d1 },
1682                 .ls_det_en  = { 0x0680, 4, 4, 0, 1 },
1683                 .ls_det_st  = { 0x0690, 4, 4, 0, 1 },
1684                 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 },
1685                 .utmi_ls    = { 0x0804, 9, 8, 0, 1 },
1686                 .utmi_hstdet    = { 0x0804, 7, 7, 0, 1 }
1687             }
1688         },
1689         .chg_det = {
1690             .opmode     = { 0x0100, 3, 0, 5, 1 },
1691             .cp_det     = { 0x0804, 1, 1, 0, 1 },
1692             .dcp_det    = { 0x0804, 0, 0, 0, 1 },
1693             .dp_det     = { 0x0804, 2, 2, 0, 1 },
1694             .idm_sink_en    = { 0x0108, 8, 8, 0, 1 },
1695             .idp_sink_en    = { 0x0108, 7, 7, 0, 1 },
1696             .idp_src_en = { 0x0108, 9, 9, 0, 1 },
1697             .rdm_pdwn_en    = { 0x0108, 10, 10, 0, 1 },
1698             .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
1699             .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
1700         },
1701     },
1702     { /* sentinel */ }
1703 };
1704 
1705 static const struct of_device_id rockchip_usb2phy_dt_match[] = {
1706     { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
1707     { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
1708     { .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
1709     { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
1710     { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
1711     { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
1712     { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
1713     { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
1714     {}
1715 };
1716 MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match);
1717 
1718 static struct platform_driver rockchip_usb2phy_driver = {
1719     .probe      = rockchip_usb2phy_probe,
1720     .driver     = {
1721         .name   = "rockchip-usb2phy",
1722         .of_match_table = rockchip_usb2phy_dt_match,
1723     },
1724 };
1725 module_platform_driver(rockchip_usb2phy_driver);
1726 
1727 MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
1728 MODULE_DESCRIPTION("Rockchip USB2.0 PHY driver");
1729 MODULE_LICENSE("GPL v2");