cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy-rockchip-inno-usb2.c (49122B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Rockchip USB2.0 PHY with Innosilicon IP block driver
      4 *
      5 * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
      6 */
      7
      8#include <linux/clk.h>
      9#include <linux/clk-provider.h>
     10#include <linux/delay.h>
     11#include <linux/extcon-provider.h>
     12#include <linux/interrupt.h>
     13#include <linux/io.h>
     14#include <linux/gpio/consumer.h>
     15#include <linux/jiffies.h>
     16#include <linux/kernel.h>
     17#include <linux/module.h>
     18#include <linux/mutex.h>
     19#include <linux/of.h>
     20#include <linux/of_address.h>
     21#include <linux/of_irq.h>
     22#include <linux/of_platform.h>
     23#include <linux/phy/phy.h>
     24#include <linux/platform_device.h>
     25#include <linux/power_supply.h>
     26#include <linux/regmap.h>
     27#include <linux/mfd/syscon.h>
     28#include <linux/usb/of.h>
     29#include <linux/usb/otg.h>
     30
     31#define BIT_WRITEABLE_SHIFT	16
     32#define SCHEDULE_DELAY		(60 * HZ)
     33#define OTG_SCHEDULE_DELAY	(2 * HZ)
     34
     35enum rockchip_usb2phy_port_id {
     36	USB2PHY_PORT_OTG,
     37	USB2PHY_PORT_HOST,
     38	USB2PHY_NUM_PORTS,
     39};
     40
     41enum rockchip_usb2phy_host_state {
     42	PHY_STATE_HS_ONLINE	= 0,
     43	PHY_STATE_DISCONNECT	= 1,
     44	PHY_STATE_CONNECT	= 2,
     45	PHY_STATE_FS_LS_ONLINE	= 4,
     46};
     47
     48/**
     49 * enum usb_chg_state - Different states involved in USB charger detection.
     50 * @USB_CHG_STATE_UNDEFINED:	USB charger is not connected or detection
     51 *				process is not yet started.
     52 * @USB_CHG_STATE_WAIT_FOR_DCD:	Waiting for Data pins contact.
     53 * @USB_CHG_STATE_DCD_DONE:	Data pin contact is detected.
     54 * @USB_CHG_STATE_PRIMARY_DONE:	Primary detection is completed (Detects
     55 *				between SDP and DCP/CDP).
     56 * @USB_CHG_STATE_SECONDARY_DONE: Secondary detection is completed (Detects
     57 *				  between DCP and CDP).
     58 * @USB_CHG_STATE_DETECTED:	USB charger type is determined.
     59 */
     60enum usb_chg_state {
     61	USB_CHG_STATE_UNDEFINED = 0,
     62	USB_CHG_STATE_WAIT_FOR_DCD,
     63	USB_CHG_STATE_DCD_DONE,
     64	USB_CHG_STATE_PRIMARY_DONE,
     65	USB_CHG_STATE_SECONDARY_DONE,
     66	USB_CHG_STATE_DETECTED,
     67};
     68
     69static const unsigned int rockchip_usb2phy_extcon_cable[] = {
     70	EXTCON_USB,
     71	EXTCON_USB_HOST,
     72	EXTCON_CHG_USB_SDP,
     73	EXTCON_CHG_USB_CDP,
     74	EXTCON_CHG_USB_DCP,
     75	EXTCON_CHG_USB_SLOW,
     76	EXTCON_NONE,
     77};
     78
     79struct usb2phy_reg {
     80	unsigned int	offset;
     81	unsigned int	bitend;
     82	unsigned int	bitstart;
     83	unsigned int	disable;
     84	unsigned int	enable;
     85};
     86
     87/**
     88 * struct rockchip_chg_det_reg - usb charger detect registers
     89 * @cp_det: charging port detected successfully.
     90 * @dcp_det: dedicated charging port detected successfully.
     91 * @dp_det: assert data pin connect successfully.
     92 * @idm_sink_en: open dm sink curren.
     93 * @idp_sink_en: open dp sink current.
     94 * @idp_src_en: open dm source current.
     95 * @rdm_pdwn_en: open dm pull down resistor.
     96 * @vdm_src_en: open dm voltage source.
     97 * @vdp_src_en: open dp voltage source.
     98 * @opmode: utmi operational mode.
     99 */
    100struct rockchip_chg_det_reg {
    101	struct usb2phy_reg	cp_det;
    102	struct usb2phy_reg	dcp_det;
    103	struct usb2phy_reg	dp_det;
    104	struct usb2phy_reg	idm_sink_en;
    105	struct usb2phy_reg	idp_sink_en;
    106	struct usb2phy_reg	idp_src_en;
    107	struct usb2phy_reg	rdm_pdwn_en;
    108	struct usb2phy_reg	vdm_src_en;
    109	struct usb2phy_reg	vdp_src_en;
    110	struct usb2phy_reg	opmode;
    111};
    112
    113/**
    114 * struct rockchip_usb2phy_port_cfg - usb-phy port configuration.
    115 * @phy_sus: phy suspend register.
    116 * @bvalid_det_en: vbus valid rise detection enable register.
    117 * @bvalid_det_st: vbus valid rise detection status register.
    118 * @bvalid_det_clr: vbus valid rise detection clear register.
    119 * @id_det_en: id detection enable register.
    120 * @id_det_st: id detection state register.
    121 * @id_det_clr: id detection clear register.
    122 * @ls_det_en: linestate detection enable register.
    123 * @ls_det_st: linestate detection state register.
    124 * @ls_det_clr: linestate detection clear register.
    125 * @utmi_avalid: utmi vbus avalid status register.
    126 * @utmi_bvalid: utmi vbus bvalid status register.
    127 * @utmi_id: utmi id state register.
    128 * @utmi_ls: utmi linestate state register.
    129 * @utmi_hstdet: utmi host disconnect register.
    130 */
    131struct rockchip_usb2phy_port_cfg {
    132	struct usb2phy_reg	phy_sus;
    133	struct usb2phy_reg	bvalid_det_en;
    134	struct usb2phy_reg	bvalid_det_st;
    135	struct usb2phy_reg	bvalid_det_clr;
    136	struct usb2phy_reg	id_det_en;
    137	struct usb2phy_reg	id_det_st;
    138	struct usb2phy_reg	id_det_clr;
    139	struct usb2phy_reg	ls_det_en;
    140	struct usb2phy_reg	ls_det_st;
    141	struct usb2phy_reg	ls_det_clr;
    142	struct usb2phy_reg	utmi_avalid;
    143	struct usb2phy_reg	utmi_bvalid;
    144	struct usb2phy_reg	utmi_id;
    145	struct usb2phy_reg	utmi_ls;
    146	struct usb2phy_reg	utmi_hstdet;
    147};
    148
    149/**
    150 * struct rockchip_usb2phy_cfg - usb-phy configuration.
    151 * @reg: the address offset of grf for usb-phy config.
    152 * @num_ports: specify how many ports that the phy has.
    153 * @clkout_ctl: keep on/turn off output clk of phy.
    154 * @port_cfgs: usb-phy port configurations.
    155 * @chg_det: charger detection registers.
    156 */
    157struct rockchip_usb2phy_cfg {
    158	unsigned int	reg;
    159	unsigned int	num_ports;
    160	struct usb2phy_reg	clkout_ctl;
    161	const struct rockchip_usb2phy_port_cfg	port_cfgs[USB2PHY_NUM_PORTS];
    162	const struct rockchip_chg_det_reg	chg_det;
    163};
    164
    165/**
    166 * struct rockchip_usb2phy_port - usb-phy port data.
    167 * @phy: generic phy.
    168 * @port_id: flag for otg port or host port.
    169 * @suspended: phy suspended flag.
    170 * @vbus_attached: otg device vbus status.
    171 * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
    172 * @id_irq: IRQ number assigned for ID pin detection.
    173 * @ls_irq: IRQ number assigned for linestate detection.
    174 * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
    175 *		 irqs to one irq in otg-port.
    176 * @mutex: for register updating in sm_work.
    177 * @chg_work: charge detect work.
    178 * @otg_sm_work: OTG state machine work.
    179 * @sm_work: HOST state machine work.
    180 * @port_cfg: port register configuration, assigned by driver data.
    181 * @event_nb: hold event notification callback.
    182 * @state: define OTG enumeration states before device reset.
    183 * @mode: the dr_mode of the controller.
    184 */
    185struct rockchip_usb2phy_port {
    186	struct phy	*phy;
    187	unsigned int	port_id;
    188	bool		suspended;
    189	bool		vbus_attached;
    190	int		bvalid_irq;
    191	int		id_irq;
    192	int		ls_irq;
    193	int		otg_mux_irq;
    194	struct mutex	mutex;
    195	struct		delayed_work chg_work;
    196	struct		delayed_work otg_sm_work;
    197	struct		delayed_work sm_work;
    198	const struct	rockchip_usb2phy_port_cfg *port_cfg;
    199	struct notifier_block	event_nb;
    200	enum usb_otg_state	state;
    201	enum usb_dr_mode	mode;
    202};
    203
    204/**
    205 * struct rockchip_usb2phy - usb2.0 phy driver data.
    206 * @dev: pointer to device.
    207 * @grf: General Register Files regmap.
    208 * @usbgrf: USB General Register Files regmap.
    209 * @clk: clock struct of phy input clk.
    210 * @clk480m: clock struct of phy output clk.
    211 * @clk480m_hw: clock struct of phy output clk management.
    212 * @chg_state: states involved in USB charger detection.
    213 * @chg_type: USB charger types.
    214 * @dcd_retries: The retry count used to track Data contact
    215 *		 detection process.
    216 * @edev: extcon device for notification registration
    217 * @irq: muxed interrupt for single irq configuration
    218 * @phy_cfg: phy register configuration, assigned by driver data.
    219 * @ports: phy port instance.
    220 */
    221struct rockchip_usb2phy {
    222	struct device	*dev;
    223	struct regmap	*grf;
    224	struct regmap	*usbgrf;
    225	struct clk	*clk;
    226	struct clk	*clk480m;
    227	struct clk_hw	clk480m_hw;
    228	enum usb_chg_state	chg_state;
    229	enum power_supply_type	chg_type;
    230	u8			dcd_retries;
    231	struct extcon_dev	*edev;
    232	int			irq;
    233	const struct rockchip_usb2phy_cfg	*phy_cfg;
    234	struct rockchip_usb2phy_port	ports[USB2PHY_NUM_PORTS];
    235};
    236
    237static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
    238{
    239	return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
    240}
    241
    242static inline int property_enable(struct regmap *base,
    243				  const struct usb2phy_reg *reg, bool en)
    244{
    245	unsigned int val, mask, tmp;
    246
    247	tmp = en ? reg->enable : reg->disable;
    248	mask = GENMASK(reg->bitend, reg->bitstart);
    249	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
    250
    251	return regmap_write(base, reg->offset, val);
    252}
    253
    254static inline bool property_enabled(struct regmap *base,
    255				    const struct usb2phy_reg *reg)
    256{
    257	int ret;
    258	unsigned int tmp, orig;
    259	unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
    260
    261	ret = regmap_read(base, reg->offset, &orig);
    262	if (ret)
    263		return false;
    264
    265	tmp = (orig & mask) >> reg->bitstart;
    266	return tmp != reg->disable;
    267}
    268
    269static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
    270{
    271	struct rockchip_usb2phy *rphy =
    272		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
    273	struct regmap *base = get_reg_base(rphy);
    274	int ret;
    275
    276	/* turn on 480m clk output if it is off */
    277	if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
    278		ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
    279		if (ret)
    280			return ret;
    281
    282		/* waiting for the clk become stable */
    283		usleep_range(1200, 1300);
    284	}
    285
    286	return 0;
    287}
    288
    289static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
    290{
    291	struct rockchip_usb2phy *rphy =
    292		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
    293	struct regmap *base = get_reg_base(rphy);
    294
    295	/* turn off 480m clk output */
    296	property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
    297}
    298
    299static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
    300{
    301	struct rockchip_usb2phy *rphy =
    302		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
    303	struct regmap *base = get_reg_base(rphy);
    304
    305	return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
    306}
    307
    308static unsigned long
    309rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
    310				     unsigned long parent_rate)
    311{
    312	return 480000000;
    313}
    314
    315static const struct clk_ops rockchip_usb2phy_clkout_ops = {
    316	.prepare = rockchip_usb2phy_clk480m_prepare,
    317	.unprepare = rockchip_usb2phy_clk480m_unprepare,
    318	.is_prepared = rockchip_usb2phy_clk480m_prepared,
    319	.recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
    320};
    321
    322static void rockchip_usb2phy_clk480m_unregister(void *data)
    323{
    324	struct rockchip_usb2phy *rphy = data;
    325
    326	of_clk_del_provider(rphy->dev->of_node);
    327	clk_unregister(rphy->clk480m);
    328}
    329
    330static int
    331rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
    332{
    333	struct device_node *node = rphy->dev->of_node;
    334	struct clk_init_data init;
    335	const char *clk_name;
    336	int ret = 0;
    337
    338	init.flags = 0;
    339	init.name = "clk_usbphy_480m";
    340	init.ops = &rockchip_usb2phy_clkout_ops;
    341
    342	/* optional override of the clockname */
    343	of_property_read_string(node, "clock-output-names", &init.name);
    344
    345	if (rphy->clk) {
    346		clk_name = __clk_get_name(rphy->clk);
    347		init.parent_names = &clk_name;
    348		init.num_parents = 1;
    349	} else {
    350		init.parent_names = NULL;
    351		init.num_parents = 0;
    352	}
    353
    354	rphy->clk480m_hw.init = &init;
    355
    356	/* register the clock */
    357	rphy->clk480m = clk_register(rphy->dev, &rphy->clk480m_hw);
    358	if (IS_ERR(rphy->clk480m)) {
    359		ret = PTR_ERR(rphy->clk480m);
    360		goto err_ret;
    361	}
    362
    363	ret = of_clk_add_provider(node, of_clk_src_simple_get, rphy->clk480m);
    364	if (ret < 0)
    365		goto err_clk_provider;
    366
    367	return devm_add_action_or_reset(rphy->dev, rockchip_usb2phy_clk480m_unregister, rphy);
    368
    369err_clk_provider:
    370	clk_unregister(rphy->clk480m);
    371err_ret:
    372	return ret;
    373}
    374
    375static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
    376{
    377	int ret;
    378	struct device_node *node = rphy->dev->of_node;
    379	struct extcon_dev *edev;
    380
    381	if (of_property_read_bool(node, "extcon")) {
    382		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
    383		if (IS_ERR(edev)) {
    384			if (PTR_ERR(edev) != -EPROBE_DEFER)
    385				dev_err(rphy->dev, "Invalid or missing extcon\n");
    386			return PTR_ERR(edev);
    387		}
    388	} else {
    389		/* Initialize extcon device */
    390		edev = devm_extcon_dev_allocate(rphy->dev,
    391						rockchip_usb2phy_extcon_cable);
    392
    393		if (IS_ERR(edev))
    394			return -ENOMEM;
    395
    396		ret = devm_extcon_dev_register(rphy->dev, edev);
    397		if (ret) {
    398			dev_err(rphy->dev, "failed to register extcon device\n");
    399			return ret;
    400		}
    401	}
    402
    403	rphy->edev = edev;
    404
    405	return 0;
    406}
    407
    408static int rockchip_usb2phy_init(struct phy *phy)
    409{
    410	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
    411	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
    412	int ret = 0;
    413
    414	mutex_lock(&rport->mutex);
    415
    416	if (rport->port_id == USB2PHY_PORT_OTG) {
    417		if (rport->mode != USB_DR_MODE_HOST &&
    418		    rport->mode != USB_DR_MODE_UNKNOWN) {
    419			/* clear bvalid status and enable bvalid detect irq */
    420			ret = property_enable(rphy->grf,
    421					      &rport->port_cfg->bvalid_det_clr,
    422					      true);
    423			if (ret)
    424				goto out;
    425
    426			ret = property_enable(rphy->grf,
    427					      &rport->port_cfg->bvalid_det_en,
    428					      true);
    429			if (ret)
    430				goto out;
    431
    432			/* clear id status and enable id detect irq */
    433			ret = property_enable(rphy->grf,
    434					      &rport->port_cfg->id_det_clr,
    435					      true);
    436			if (ret)
    437				goto out;
    438
    439			ret = property_enable(rphy->grf,
    440					      &rport->port_cfg->id_det_en,
    441					      true);
    442			if (ret)
    443				goto out;
    444
    445			schedule_delayed_work(&rport->otg_sm_work,
    446					      OTG_SCHEDULE_DELAY * 3);
    447		} else {
    448			/* If OTG works in host only mode, do nothing. */
    449			dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
    450		}
    451	} else if (rport->port_id == USB2PHY_PORT_HOST) {
    452		/* clear linestate and enable linestate detect irq */
    453		ret = property_enable(rphy->grf,
    454				      &rport->port_cfg->ls_det_clr, true);
    455		if (ret)
    456			goto out;
    457
    458		ret = property_enable(rphy->grf,
    459				      &rport->port_cfg->ls_det_en, true);
    460		if (ret)
    461			goto out;
    462
    463		schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
    464	}
    465
    466out:
    467	mutex_unlock(&rport->mutex);
    468	return ret;
    469}
    470
    471static int rockchip_usb2phy_power_on(struct phy *phy)
    472{
    473	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
    474	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
    475	struct regmap *base = get_reg_base(rphy);
    476	int ret;
    477
    478	dev_dbg(&rport->phy->dev, "port power on\n");
    479
    480	if (!rport->suspended)
    481		return 0;
    482
    483	ret = clk_prepare_enable(rphy->clk480m);
    484	if (ret)
    485		return ret;
    486
    487	ret = property_enable(base, &rport->port_cfg->phy_sus, false);
    488	if (ret)
    489		return ret;
    490
    491	/* waiting for the utmi_clk to become stable */
    492	usleep_range(1500, 2000);
    493
    494	rport->suspended = false;
    495	return 0;
    496}
    497
    498static int rockchip_usb2phy_power_off(struct phy *phy)
    499{
    500	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
    501	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
    502	struct regmap *base = get_reg_base(rphy);
    503	int ret;
    504
    505	dev_dbg(&rport->phy->dev, "port power off\n");
    506
    507	if (rport->suspended)
    508		return 0;
    509
    510	ret = property_enable(base, &rport->port_cfg->phy_sus, true);
    511	if (ret)
    512		return ret;
    513
    514	rport->suspended = true;
    515	clk_disable_unprepare(rphy->clk480m);
    516
    517	return 0;
    518}
    519
    520static int rockchip_usb2phy_exit(struct phy *phy)
    521{
    522	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
    523
    524	if (rport->port_id == USB2PHY_PORT_OTG &&
    525	    rport->mode != USB_DR_MODE_HOST &&
    526	    rport->mode != USB_DR_MODE_UNKNOWN) {
    527		cancel_delayed_work_sync(&rport->otg_sm_work);
    528		cancel_delayed_work_sync(&rport->chg_work);
    529	} else if (rport->port_id == USB2PHY_PORT_HOST)
    530		cancel_delayed_work_sync(&rport->sm_work);
    531
    532	return 0;
    533}
    534
    535static const struct phy_ops rockchip_usb2phy_ops = {
    536	.init		= rockchip_usb2phy_init,
    537	.exit		= rockchip_usb2phy_exit,
    538	.power_on	= rockchip_usb2phy_power_on,
    539	.power_off	= rockchip_usb2phy_power_off,
    540	.owner		= THIS_MODULE,
    541};
    542
    543static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
    544{
    545	struct rockchip_usb2phy_port *rport =
    546		container_of(work, struct rockchip_usb2phy_port,
    547			     otg_sm_work.work);
    548	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
    549	static unsigned int cable;
    550	unsigned long delay;
    551	bool vbus_attach, sch_work, notify_charger;
    552
    553	vbus_attach = property_enabled(rphy->grf,
    554				       &rport->port_cfg->utmi_bvalid);
    555
    556	sch_work = false;
    557	notify_charger = false;
    558	delay = OTG_SCHEDULE_DELAY;
    559	dev_dbg(&rport->phy->dev, "%s otg sm work\n",
    560		usb_otg_state_string(rport->state));
    561
    562	switch (rport->state) {
    563	case OTG_STATE_UNDEFINED:
    564		rport->state = OTG_STATE_B_IDLE;
    565		if (!vbus_attach)
    566			rockchip_usb2phy_power_off(rport->phy);
    567		fallthrough;
    568	case OTG_STATE_B_IDLE:
    569		if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
    570			dev_dbg(&rport->phy->dev, "usb otg host connect\n");
    571			rport->state = OTG_STATE_A_HOST;
    572			rockchip_usb2phy_power_on(rport->phy);
    573			return;
    574		} else if (vbus_attach) {
    575			dev_dbg(&rport->phy->dev, "vbus_attach\n");
    576			switch (rphy->chg_state) {
    577			case USB_CHG_STATE_UNDEFINED:
    578				schedule_delayed_work(&rport->chg_work, 0);
    579				return;
    580			case USB_CHG_STATE_DETECTED:
    581				switch (rphy->chg_type) {
    582				case POWER_SUPPLY_TYPE_USB:
    583					dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
    584					rockchip_usb2phy_power_on(rport->phy);
    585					rport->state = OTG_STATE_B_PERIPHERAL;
    586					notify_charger = true;
    587					sch_work = true;
    588					cable = EXTCON_CHG_USB_SDP;
    589					break;
    590				case POWER_SUPPLY_TYPE_USB_DCP:
    591					dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
    592					rockchip_usb2phy_power_off(rport->phy);
    593					notify_charger = true;
    594					sch_work = true;
    595					cable = EXTCON_CHG_USB_DCP;
    596					break;
    597				case POWER_SUPPLY_TYPE_USB_CDP:
    598					dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
    599					rockchip_usb2phy_power_on(rport->phy);
    600					rport->state = OTG_STATE_B_PERIPHERAL;
    601					notify_charger = true;
    602					sch_work = true;
    603					cable = EXTCON_CHG_USB_CDP;
    604					break;
    605				default:
    606					break;
    607				}
    608				break;
    609			default:
    610				break;
    611			}
    612		} else {
    613			notify_charger = true;
    614			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
    615			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
    616		}
    617
    618		if (rport->vbus_attached != vbus_attach) {
    619			rport->vbus_attached = vbus_attach;
    620
    621			if (notify_charger && rphy->edev) {
    622				extcon_set_state_sync(rphy->edev,
    623							cable, vbus_attach);
    624				if (cable == EXTCON_CHG_USB_SDP)
    625					extcon_set_state_sync(rphy->edev,
    626							      EXTCON_USB,
    627							      vbus_attach);
    628			}
    629		}
    630		break;
    631	case OTG_STATE_B_PERIPHERAL:
    632		if (!vbus_attach) {
    633			dev_dbg(&rport->phy->dev, "usb disconnect\n");
    634			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
    635			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
    636			rport->state = OTG_STATE_B_IDLE;
    637			delay = 0;
    638			rockchip_usb2phy_power_off(rport->phy);
    639		}
    640		sch_work = true;
    641		break;
    642	case OTG_STATE_A_HOST:
    643		if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
    644			dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
    645			rport->state = OTG_STATE_B_IDLE;
    646			rockchip_usb2phy_power_off(rport->phy);
    647		}
    648		break;
    649	default:
    650		break;
    651	}
    652
    653	if (sch_work)
    654		schedule_delayed_work(&rport->otg_sm_work, delay);
    655}
    656
    657static const char *chg_to_string(enum power_supply_type chg_type)
    658{
    659	switch (chg_type) {
    660	case POWER_SUPPLY_TYPE_USB:
    661		return "USB_SDP_CHARGER";
    662	case POWER_SUPPLY_TYPE_USB_DCP:
    663		return "USB_DCP_CHARGER";
    664	case POWER_SUPPLY_TYPE_USB_CDP:
    665		return "USB_CDP_CHARGER";
    666	default:
    667		return "INVALID_CHARGER";
    668	}
    669}
    670
    671static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
    672				    bool en)
    673{
    674	struct regmap *base = get_reg_base(rphy);
    675
    676	property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
    677	property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
    678}
    679
    680static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
    681					    bool en)
    682{
    683	struct regmap *base = get_reg_base(rphy);
    684
    685	property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
    686	property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
    687}
    688
    689static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
    690					      bool en)
    691{
    692	struct regmap *base = get_reg_base(rphy);
    693
    694	property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
    695	property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
    696}
    697
    698#define CHG_DCD_POLL_TIME	(100 * HZ / 1000)
    699#define CHG_DCD_MAX_RETRIES	6
    700#define CHG_PRIMARY_DET_TIME	(40 * HZ / 1000)
    701#define CHG_SECONDARY_DET_TIME	(40 * HZ / 1000)
    702static void rockchip_chg_detect_work(struct work_struct *work)
    703{
    704	struct rockchip_usb2phy_port *rport =
    705		container_of(work, struct rockchip_usb2phy_port, chg_work.work);
    706	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
    707	struct regmap *base = get_reg_base(rphy);
    708	bool is_dcd, tmout, vout;
    709	unsigned long delay;
    710
    711	dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
    712		rphy->chg_state);
    713	switch (rphy->chg_state) {
    714	case USB_CHG_STATE_UNDEFINED:
    715		if (!rport->suspended)
    716			rockchip_usb2phy_power_off(rport->phy);
    717		/* put the controller in non-driving mode */
    718		property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
    719		/* Start DCD processing stage 1 */
    720		rockchip_chg_enable_dcd(rphy, true);
    721		rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
    722		rphy->dcd_retries = 0;
    723		delay = CHG_DCD_POLL_TIME;
    724		break;
    725	case USB_CHG_STATE_WAIT_FOR_DCD:
    726		/* get data contact detection status */
    727		is_dcd = property_enabled(rphy->grf,
    728					  &rphy->phy_cfg->chg_det.dp_det);
    729		tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
    730		/* stage 2 */
    731		if (is_dcd || tmout) {
    732			/* stage 4 */
    733			/* Turn off DCD circuitry */
    734			rockchip_chg_enable_dcd(rphy, false);
    735			/* Voltage Source on DP, Probe on DM */
    736			rockchip_chg_enable_primary_det(rphy, true);
    737			delay = CHG_PRIMARY_DET_TIME;
    738			rphy->chg_state = USB_CHG_STATE_DCD_DONE;
    739		} else {
    740			/* stage 3 */
    741			delay = CHG_DCD_POLL_TIME;
    742		}
    743		break;
    744	case USB_CHG_STATE_DCD_DONE:
    745		vout = property_enabled(rphy->grf,
    746					&rphy->phy_cfg->chg_det.cp_det);
    747		rockchip_chg_enable_primary_det(rphy, false);
    748		if (vout) {
    749			/* Voltage Source on DM, Probe on DP  */
    750			rockchip_chg_enable_secondary_det(rphy, true);
    751			delay = CHG_SECONDARY_DET_TIME;
    752			rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
    753		} else {
    754			if (rphy->dcd_retries == CHG_DCD_MAX_RETRIES) {
    755				/* floating charger found */
    756				rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
    757				rphy->chg_state = USB_CHG_STATE_DETECTED;
    758				delay = 0;
    759			} else {
    760				rphy->chg_type = POWER_SUPPLY_TYPE_USB;
    761				rphy->chg_state = USB_CHG_STATE_DETECTED;
    762				delay = 0;
    763			}
    764		}
    765		break;
    766	case USB_CHG_STATE_PRIMARY_DONE:
    767		vout = property_enabled(rphy->grf,
    768					&rphy->phy_cfg->chg_det.dcp_det);
    769		/* Turn off voltage source */
    770		rockchip_chg_enable_secondary_det(rphy, false);
    771		if (vout)
    772			rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
    773		else
    774			rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
    775		fallthrough;
    776	case USB_CHG_STATE_SECONDARY_DONE:
    777		rphy->chg_state = USB_CHG_STATE_DETECTED;
    778		fallthrough;
    779	case USB_CHG_STATE_DETECTED:
    780		/* put the controller in normal mode */
    781		property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
    782		rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
    783		dev_dbg(&rport->phy->dev, "charger = %s\n",
    784			 chg_to_string(rphy->chg_type));
    785		return;
    786	default:
    787		return;
    788	}
    789
    790	schedule_delayed_work(&rport->chg_work, delay);
    791}
    792
    793/*
    794 * The function manage host-phy port state and suspend/resume phy port
    795 * to save power.
    796 *
    797 * we rely on utmi_linestate and utmi_hostdisconnect to identify whether
    798 * devices is disconnect or not. Besides, we do not need care it is FS/LS
    799 * disconnected or HS disconnected, actually, we just only need get the
    800 * device is disconnected at last through rearm the delayed work,
    801 * to suspend the phy port in _PHY_STATE_DISCONNECT_ case.
    802 *
    803 * NOTE: It may invoke *phy_powr_off or *phy_power_on which will invoke
    804 * some clk related APIs, so do not invoke it from interrupt context directly.
    805 */
    806static void rockchip_usb2phy_sm_work(struct work_struct *work)
    807{
    808	struct rockchip_usb2phy_port *rport =
    809		container_of(work, struct rockchip_usb2phy_port, sm_work.work);
    810	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
    811	unsigned int sh = rport->port_cfg->utmi_hstdet.bitend -
    812			  rport->port_cfg->utmi_hstdet.bitstart + 1;
    813	unsigned int ul, uhd, state;
    814	unsigned int ul_mask, uhd_mask;
    815	int ret;
    816
    817	mutex_lock(&rport->mutex);
    818
    819	ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
    820	if (ret < 0)
    821		goto next_schedule;
    822
    823	ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
    824	if (ret < 0)
    825		goto next_schedule;
    826
    827	uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
    828			   rport->port_cfg->utmi_hstdet.bitstart);
    829	ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
    830			  rport->port_cfg->utmi_ls.bitstart);
    831
    832	/* stitch on utmi_ls and utmi_hstdet as phy state */
    833	state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
    834		(((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
    835
    836	switch (state) {
    837	case PHY_STATE_HS_ONLINE:
    838		dev_dbg(&rport->phy->dev, "HS online\n");
    839		break;
    840	case PHY_STATE_FS_LS_ONLINE:
    841		/*
    842		 * For FS/LS device, the online state share with connect state
    843		 * from utmi_ls and utmi_hstdet register, so we distinguish
    844		 * them via suspended flag.
    845		 *
    846		 * Plus, there are two cases, one is D- Line pull-up, and D+
    847		 * line pull-down, the state is 4; another is D+ line pull-up,
    848		 * and D- line pull-down, the state is 2.
    849		 */
    850		if (!rport->suspended) {
    851			/* D- line pull-up, D+ line pull-down */
    852			dev_dbg(&rport->phy->dev, "FS/LS online\n");
    853			break;
    854		}
    855		fallthrough;
    856	case PHY_STATE_CONNECT:
    857		if (rport->suspended) {
    858			dev_dbg(&rport->phy->dev, "Connected\n");
    859			rockchip_usb2phy_power_on(rport->phy);
    860			rport->suspended = false;
    861		} else {
    862			/* D+ line pull-up, D- line pull-down */
    863			dev_dbg(&rport->phy->dev, "FS/LS online\n");
    864		}
    865		break;
    866	case PHY_STATE_DISCONNECT:
    867		if (!rport->suspended) {
    868			dev_dbg(&rport->phy->dev, "Disconnected\n");
    869			rockchip_usb2phy_power_off(rport->phy);
    870			rport->suspended = true;
    871		}
    872
    873		/*
    874		 * activate the linestate detection to get the next device
    875		 * plug-in irq.
    876		 */
    877		property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
    878		property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
    879
    880		/*
    881		 * we don't need to rearm the delayed work when the phy port
    882		 * is suspended.
    883		 */
    884		mutex_unlock(&rport->mutex);
    885		return;
    886	default:
    887		dev_dbg(&rport->phy->dev, "unknown phy state\n");
    888		break;
    889	}
    890
    891next_schedule:
    892	mutex_unlock(&rport->mutex);
    893	schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
    894}
    895
    896static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
    897{
    898	struct rockchip_usb2phy_port *rport = data;
    899	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
    900
    901	if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
    902		return IRQ_NONE;
    903
    904	mutex_lock(&rport->mutex);
    905
    906	/* disable linestate detect irq and clear its status */
    907	property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
    908	property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
    909
    910	mutex_unlock(&rport->mutex);
    911
    912	/*
    913	 * In this case for host phy port, a new device is plugged in,
    914	 * meanwhile, if the phy port is suspended, we need rearm the work to
    915	 * resume it and mange its states; otherwise, we do nothing about that.
    916	 */
    917	if (rport->suspended && rport->port_id == USB2PHY_PORT_HOST)
    918		rockchip_usb2phy_sm_work(&rport->sm_work.work);
    919
    920	return IRQ_HANDLED;
    921}
    922
    923static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
    924{
    925	struct rockchip_usb2phy_port *rport = data;
    926	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
    927
    928	if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
    929		return IRQ_NONE;
    930
    931	/* clear bvalid detect irq pending status */
    932	property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
    933
    934	rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
    935
    936	return IRQ_HANDLED;
    937}
    938
    939static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
    940{
    941	struct rockchip_usb2phy_port *rport = data;
    942	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
    943	bool id;
    944
    945	if (!property_enabled(rphy->grf, &rport->port_cfg->id_det_st))
    946		return IRQ_NONE;
    947
    948	/* clear id detect irq pending status */
    949	property_enable(rphy->grf, &rport->port_cfg->id_det_clr, true);
    950
    951	id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
    952	extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
    953
    954	return IRQ_HANDLED;
    955}
    956
    957static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
    958{
    959	irqreturn_t ret = IRQ_NONE;
    960
    961	ret |= rockchip_usb2phy_bvalid_irq(irq, data);
    962	ret |= rockchip_usb2phy_id_irq(irq, data);
    963
    964	return ret;
    965}
    966
    967static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
    968{
    969	struct rockchip_usb2phy *rphy = data;
    970	struct rockchip_usb2phy_port *rport;
    971	irqreturn_t ret = IRQ_NONE;
    972	unsigned int index;
    973
    974	for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
    975		rport = &rphy->ports[index];
    976		if (!rport->phy)
    977			continue;
    978
    979		switch (rport->port_id) {
    980		case USB2PHY_PORT_OTG:
    981			ret |= rockchip_usb2phy_otg_mux_irq(irq, rport);
    982			break;
    983		case USB2PHY_PORT_HOST:
    984			ret |= rockchip_usb2phy_linestate_irq(irq, rport);
    985			break;
    986		}
    987	}
    988
    989	return ret;
    990}
    991
    992static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
    993					  struct rockchip_usb2phy_port *rport,
    994					  struct device_node *child_np)
    995{
    996	int ret;
    997
    998	/*
    999	 * If the usb2 phy used combined irq for otg and host port,
   1000	 * don't need to init otg and host port irq separately.
   1001	 */
   1002	if (rphy->irq > 0)
   1003		return 0;
   1004
   1005	switch (rport->port_id) {
   1006	case USB2PHY_PORT_HOST:
   1007		rport->ls_irq = of_irq_get_byname(child_np, "linestate");
   1008		if (rport->ls_irq < 0) {
   1009			dev_err(rphy->dev, "no linestate irq provided\n");
   1010			return rport->ls_irq;
   1011		}
   1012
   1013		ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
   1014						rockchip_usb2phy_linestate_irq,
   1015						IRQF_ONESHOT,
   1016						"rockchip_usb2phy", rport);
   1017		if (ret) {
   1018			dev_err(rphy->dev, "failed to request linestate irq handle\n");
   1019			return ret;
   1020		}
   1021		break;
   1022	case USB2PHY_PORT_OTG:
   1023		/*
   1024		 * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
   1025		 * interrupts muxed together, so probe the otg-mux interrupt first,
   1026		 * if not found, then look for the regular interrupts one by one.
   1027		 */
   1028		rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
   1029		if (rport->otg_mux_irq > 0) {
   1030			ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
   1031							NULL,
   1032							rockchip_usb2phy_otg_mux_irq,
   1033							IRQF_ONESHOT,
   1034							"rockchip_usb2phy_otg",
   1035							rport);
   1036			if (ret) {
   1037				dev_err(rphy->dev,
   1038					"failed to request otg-mux irq handle\n");
   1039				return ret;
   1040			}
   1041		} else {
   1042			rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
   1043			if (rport->bvalid_irq < 0) {
   1044				dev_err(rphy->dev, "no vbus valid irq provided\n");
   1045				ret = rport->bvalid_irq;
   1046				return ret;
   1047			}
   1048
   1049			ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
   1050							NULL,
   1051							rockchip_usb2phy_bvalid_irq,
   1052							IRQF_ONESHOT,
   1053							"rockchip_usb2phy_bvalid",
   1054							rport);
   1055			if (ret) {
   1056				dev_err(rphy->dev,
   1057					"failed to request otg-bvalid irq handle\n");
   1058				return ret;
   1059			}
   1060
   1061			rport->id_irq = of_irq_get_byname(child_np, "otg-id");
   1062			if (rport->id_irq < 0) {
   1063				dev_err(rphy->dev, "no otg-id irq provided\n");
   1064				ret = rport->id_irq;
   1065				return ret;
   1066			}
   1067
   1068			ret = devm_request_threaded_irq(rphy->dev, rport->id_irq,
   1069							NULL,
   1070							rockchip_usb2phy_id_irq,
   1071							IRQF_ONESHOT,
   1072							"rockchip_usb2phy_id",
   1073							rport);
   1074			if (ret) {
   1075				dev_err(rphy->dev,
   1076					"failed to request otg-id irq handle\n");
   1077				return ret;
   1078			}
   1079		}
   1080		break;
   1081	default:
   1082		return -EINVAL;
   1083	}
   1084
   1085	return 0;
   1086}
   1087
   1088static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
   1089					   struct rockchip_usb2phy_port *rport,
   1090					   struct device_node *child_np)
   1091{
   1092	int ret;
   1093
   1094	rport->port_id = USB2PHY_PORT_HOST;
   1095	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
   1096	rport->suspended = true;
   1097
   1098	mutex_init(&rport->mutex);
   1099	INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
   1100
   1101	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
   1102	if (ret) {
   1103		dev_err(rphy->dev, "failed to setup host irq\n");
   1104		return ret;
   1105	}
   1106
   1107	return 0;
   1108}
   1109
   1110static int rockchip_otg_event(struct notifier_block *nb,
   1111			      unsigned long event, void *ptr)
   1112{
   1113	struct rockchip_usb2phy_port *rport =
   1114		container_of(nb, struct rockchip_usb2phy_port, event_nb);
   1115
   1116	schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
   1117
   1118	return NOTIFY_DONE;
   1119}
   1120
   1121static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
   1122					  struct rockchip_usb2phy_port *rport,
   1123					  struct device_node *child_np)
   1124{
   1125	int ret;
   1126
   1127	rport->port_id = USB2PHY_PORT_OTG;
   1128	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
   1129	rport->state = OTG_STATE_UNDEFINED;
   1130
   1131	/*
   1132	 * set suspended flag to true, but actually don't
   1133	 * put phy in suspend mode, it aims to enable usb
   1134	 * phy and clock in power_on() called by usb controller
   1135	 * driver during probe.
   1136	 */
   1137	rport->suspended = true;
   1138	rport->vbus_attached = false;
   1139
   1140	mutex_init(&rport->mutex);
   1141
   1142	rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
   1143	if (rport->mode == USB_DR_MODE_HOST ||
   1144	    rport->mode == USB_DR_MODE_UNKNOWN) {
   1145		ret = 0;
   1146		goto out;
   1147	}
   1148
   1149	INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
   1150	INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
   1151
   1152	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
   1153	if (ret) {
   1154		dev_err(rphy->dev, "failed to init irq for host port\n");
   1155		goto out;
   1156	}
   1157
   1158	if (!IS_ERR(rphy->edev)) {
   1159		rport->event_nb.notifier_call = rockchip_otg_event;
   1160
   1161		ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
   1162					EXTCON_USB_HOST, &rport->event_nb);
   1163		if (ret)
   1164			dev_err(rphy->dev, "register USB HOST notifier failed\n");
   1165	}
   1166
   1167out:
   1168	return ret;
   1169}
   1170
   1171static int rockchip_usb2phy_probe(struct platform_device *pdev)
   1172{
   1173	struct device *dev = &pdev->dev;
   1174	struct device_node *np = dev->of_node;
   1175	struct device_node *child_np;
   1176	struct phy_provider *provider;
   1177	struct rockchip_usb2phy *rphy;
   1178	const struct rockchip_usb2phy_cfg *phy_cfgs;
   1179	const struct of_device_id *match;
   1180	unsigned int reg;
   1181	int index, ret;
   1182
   1183	rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
   1184	if (!rphy)
   1185		return -ENOMEM;
   1186
   1187	match = of_match_device(dev->driver->of_match_table, dev);
   1188	if (!match || !match->data) {
   1189		dev_err(dev, "phy configs are not assigned!\n");
   1190		return -EINVAL;
   1191	}
   1192
   1193	if (!dev->parent || !dev->parent->of_node) {
   1194		rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
   1195		if (IS_ERR(rphy->grf)) {
   1196			dev_err(dev, "failed to locate usbgrf\n");
   1197			return PTR_ERR(rphy->grf);
   1198		}
   1199	}
   1200
   1201	else {
   1202		rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
   1203		if (IS_ERR(rphy->grf))
   1204			return PTR_ERR(rphy->grf);
   1205	}
   1206
   1207	if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
   1208		rphy->usbgrf =
   1209			syscon_regmap_lookup_by_phandle(dev->of_node,
   1210							"rockchip,usbgrf");
   1211		if (IS_ERR(rphy->usbgrf))
   1212			return PTR_ERR(rphy->usbgrf);
   1213	} else {
   1214		rphy->usbgrf = NULL;
   1215	}
   1216
   1217	if (of_property_read_u32_index(np, "reg", 0, &reg)) {
   1218		dev_err(dev, "the reg property is not assigned in %pOFn node\n",
   1219			np);
   1220		return -EINVAL;
   1221	}
   1222
   1223	/* support address_cells=2 */
   1224	if (reg == 0) {
   1225		if (of_property_read_u32_index(np, "reg", 1, &reg)) {
   1226			dev_err(dev, "the reg property is not assigned in %pOFn node\n",
   1227				np);
   1228			return -EINVAL;
   1229		}
   1230	}
   1231
   1232	rphy->dev = dev;
   1233	phy_cfgs = match->data;
   1234	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
   1235	rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
   1236	rphy->irq = platform_get_irq_optional(pdev, 0);
   1237	platform_set_drvdata(pdev, rphy);
   1238
   1239	ret = rockchip_usb2phy_extcon_register(rphy);
   1240	if (ret)
   1241		return ret;
   1242
   1243	/* find out a proper config which can be matched with dt. */
   1244	index = 0;
   1245	while (phy_cfgs[index].reg) {
   1246		if (phy_cfgs[index].reg == reg) {
   1247			rphy->phy_cfg = &phy_cfgs[index];
   1248			break;
   1249		}
   1250
   1251		++index;
   1252	}
   1253
   1254	if (!rphy->phy_cfg) {
   1255		dev_err(dev, "no phy-config can be matched with %pOFn node\n",
   1256			np);
   1257		return -EINVAL;
   1258	}
   1259
   1260	rphy->clk = of_clk_get_by_name(np, "phyclk");
   1261	if (!IS_ERR(rphy->clk)) {
   1262		clk_prepare_enable(rphy->clk);
   1263	} else {
   1264		dev_info(&pdev->dev, "no phyclk specified\n");
   1265		rphy->clk = NULL;
   1266	}
   1267
   1268	ret = rockchip_usb2phy_clk480m_register(rphy);
   1269	if (ret) {
   1270		dev_err(dev, "failed to register 480m output clock\n");
   1271		goto disable_clks;
   1272	}
   1273
   1274	index = 0;
   1275	for_each_available_child_of_node(np, child_np) {
   1276		struct rockchip_usb2phy_port *rport = &rphy->ports[index];
   1277		struct phy *phy;
   1278
   1279		/* This driver aims to support both otg-port and host-port */
   1280		if (!of_node_name_eq(child_np, "host-port") &&
   1281		    !of_node_name_eq(child_np, "otg-port"))
   1282			goto next_child;
   1283
   1284		phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
   1285		if (IS_ERR(phy)) {
   1286			dev_err(dev, "failed to create phy\n");
   1287			ret = PTR_ERR(phy);
   1288			goto put_child;
   1289		}
   1290
   1291		rport->phy = phy;
   1292		phy_set_drvdata(rport->phy, rport);
   1293
   1294		/* initialize otg/host port separately */
   1295		if (of_node_name_eq(child_np, "host-port")) {
   1296			ret = rockchip_usb2phy_host_port_init(rphy, rport,
   1297							      child_np);
   1298			if (ret)
   1299				goto put_child;
   1300		} else {
   1301			ret = rockchip_usb2phy_otg_port_init(rphy, rport,
   1302							     child_np);
   1303			if (ret)
   1304				goto put_child;
   1305		}
   1306
   1307next_child:
   1308		/* to prevent out of boundary */
   1309		if (++index >= rphy->phy_cfg->num_ports) {
   1310			of_node_put(child_np);
   1311			break;
   1312		}
   1313	}
   1314
   1315	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
   1316
   1317	if (rphy->irq > 0) {
   1318		ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
   1319						rockchip_usb2phy_irq,
   1320						IRQF_ONESHOT,
   1321						"rockchip_usb2phy",
   1322						rphy);
   1323		if (ret) {
   1324			dev_err(rphy->dev,
   1325				"failed to request usb2phy irq handle\n");
   1326			goto put_child;
   1327		}
   1328	}
   1329
   1330	return PTR_ERR_OR_ZERO(provider);
   1331
   1332put_child:
   1333	of_node_put(child_np);
   1334disable_clks:
   1335	if (rphy->clk) {
   1336		clk_disable_unprepare(rphy->clk);
   1337		clk_put(rphy->clk);
   1338	}
   1339	return ret;
   1340}
   1341
   1342static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
   1343	{
   1344		.reg = 0x760,
   1345		.num_ports	= 2,
   1346		.clkout_ctl	= { 0x0768, 4, 4, 1, 0 },
   1347		.port_cfgs	= {
   1348			[USB2PHY_PORT_OTG] = {
   1349				.phy_sus	= { 0x0760, 15, 0, 0, 0x1d1 },
   1350				.bvalid_det_en	= { 0x0680, 3, 3, 0, 1 },
   1351				.bvalid_det_st	= { 0x0690, 3, 3, 0, 1 },
   1352				.bvalid_det_clr	= { 0x06a0, 3, 3, 0, 1 },
   1353				.id_det_en	= { 0x0680, 6, 5, 0, 3 },
   1354				.id_det_st	= { 0x0690, 6, 5, 0, 3 },
   1355				.id_det_clr	= { 0x06a0, 6, 5, 0, 3 },
   1356				.ls_det_en	= { 0x0680, 2, 2, 0, 1 },
   1357				.ls_det_st	= { 0x0690, 2, 2, 0, 1 },
   1358				.ls_det_clr	= { 0x06a0, 2, 2, 0, 1 },
   1359				.utmi_bvalid	= { 0x0480, 4, 4, 0, 1 },
   1360				.utmi_id	= { 0x0480, 1, 1, 0, 1 },
   1361				.utmi_ls	= { 0x0480, 3, 2, 0, 1 },
   1362			},
   1363			[USB2PHY_PORT_HOST] = {
   1364				.phy_sus	= { 0x0764, 15, 0, 0, 0x1d1 },
   1365				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
   1366				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
   1367				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 }
   1368			}
   1369		},
   1370		.chg_det = {
   1371			.opmode		= { 0x0760, 3, 0, 5, 1 },
   1372			.cp_det		= { 0x0884, 4, 4, 0, 1 },
   1373			.dcp_det	= { 0x0884, 3, 3, 0, 1 },
   1374			.dp_det		= { 0x0884, 5, 5, 0, 1 },
   1375			.idm_sink_en	= { 0x0768, 8, 8, 0, 1 },
   1376			.idp_sink_en	= { 0x0768, 7, 7, 0, 1 },
   1377			.idp_src_en	= { 0x0768, 9, 9, 0, 1 },
   1378			.rdm_pdwn_en	= { 0x0768, 10, 10, 0, 1 },
   1379			.vdm_src_en	= { 0x0768, 12, 12, 0, 1 },
   1380			.vdp_src_en	= { 0x0768, 11, 11, 0, 1 },
   1381		},
   1382	},
   1383	{
   1384		.reg = 0x800,
   1385		.num_ports	= 2,
   1386		.clkout_ctl	= { 0x0808, 4, 4, 1, 0 },
   1387		.port_cfgs	= {
   1388			[USB2PHY_PORT_OTG] = {
   1389				.phy_sus	= { 0x800, 15, 0, 0, 0x1d1 },
   1390				.ls_det_en	= { 0x0684, 0, 0, 0, 1 },
   1391				.ls_det_st	= { 0x0694, 0, 0, 0, 1 },
   1392				.ls_det_clr	= { 0x06a4, 0, 0, 0, 1 }
   1393			},
   1394			[USB2PHY_PORT_HOST] = {
   1395				.phy_sus	= { 0x804, 15, 0, 0, 0x1d1 },
   1396				.ls_det_en	= { 0x0684, 1, 1, 0, 1 },
   1397				.ls_det_st	= { 0x0694, 1, 1, 0, 1 },
   1398				.ls_det_clr	= { 0x06a4, 1, 1, 0, 1 }
   1399			}
   1400		},
   1401	},
   1402	{ /* sentinel */ }
   1403};
   1404
   1405static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
   1406	{
   1407		.reg = 0x100,
   1408		.num_ports	= 2,
   1409		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
   1410		.port_cfgs	= {
   1411			[USB2PHY_PORT_OTG] = {
   1412				.phy_sus	= { 0x0100, 8, 0, 0, 0x1d1 },
   1413				.bvalid_det_en	= { 0x3020, 3, 2, 0, 3 },
   1414				.bvalid_det_st	= { 0x3024, 3, 2, 0, 3 },
   1415				.bvalid_det_clr = { 0x3028, 3, 2, 0, 3 },
   1416				.id_det_en	= { 0x3020, 5, 4, 0, 3 },
   1417				.id_det_st	= { 0x3024, 5, 4, 0, 3 },
   1418				.id_det_clr	= { 0x3028, 5, 4, 0, 3 },
   1419				.ls_det_en	= { 0x3020, 0, 0, 0, 1 },
   1420				.ls_det_st	= { 0x3024, 0, 0, 0, 1 },
   1421				.ls_det_clr	= { 0x3028, 0, 0, 0, 1 },
   1422				.utmi_avalid	= { 0x0120, 10, 10, 0, 1 },
   1423				.utmi_bvalid	= { 0x0120, 9, 9, 0, 1 },
   1424				.utmi_id	= { 0x0120, 6, 6, 0, 1 },
   1425				.utmi_ls	= { 0x0120, 5, 4, 0, 1 },
   1426			},
   1427			[USB2PHY_PORT_HOST] = {
   1428				.phy_sus	= { 0x0104, 8, 0, 0, 0x1d1 },
   1429				.ls_det_en	= { 0x3020, 1, 1, 0, 1 },
   1430				.ls_det_st	= { 0x3024, 1, 1, 0, 1 },
   1431				.ls_det_clr	= { 0x3028, 1, 1, 0, 1 },
   1432				.utmi_ls	= { 0x0120, 17, 16, 0, 1 },
   1433				.utmi_hstdet	= { 0x0120, 19, 19, 0, 1 }
   1434			}
   1435		},
   1436		.chg_det = {
   1437			.opmode		= { 0x0100, 3, 0, 5, 1 },
   1438			.cp_det		= { 0x0120, 24, 24, 0, 1 },
   1439			.dcp_det	= { 0x0120, 23, 23, 0, 1 },
   1440			.dp_det		= { 0x0120, 25, 25, 0, 1 },
   1441			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
   1442			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
   1443			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
   1444			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
   1445			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
   1446			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
   1447		},
   1448	},
   1449	{ /* sentinel */ }
   1450};
   1451
   1452static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
   1453	{
   1454		.reg = 0x100,
   1455		.num_ports	= 2,
   1456		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
   1457		.port_cfgs	= {
   1458			[USB2PHY_PORT_OTG] = {
   1459				.phy_sus	= { 0x0100, 15, 0, 0, 0x1d1 },
   1460				.bvalid_det_en	= { 0x0110, 3, 2, 0, 3 },
   1461				.bvalid_det_st	= { 0x0114, 3, 2, 0, 3 },
   1462				.bvalid_det_clr = { 0x0118, 3, 2, 0, 3 },
   1463				.id_det_en	= { 0x0110, 5, 4, 0, 3 },
   1464				.id_det_st	= { 0x0114, 5, 4, 0, 3 },
   1465				.id_det_clr	= { 0x0118, 5, 4, 0, 3 },
   1466				.ls_det_en	= { 0x0110, 0, 0, 0, 1 },
   1467				.ls_det_st	= { 0x0114, 0, 0, 0, 1 },
   1468				.ls_det_clr	= { 0x0118, 0, 0, 0, 1 },
   1469				.utmi_avalid	= { 0x0120, 10, 10, 0, 1 },
   1470				.utmi_bvalid	= { 0x0120, 9, 9, 0, 1 },
   1471				.utmi_id	= { 0x0120, 6, 6, 0, 1 },
   1472				.utmi_ls	= { 0x0120, 5, 4, 0, 1 },
   1473			},
   1474			[USB2PHY_PORT_HOST] = {
   1475				.phy_sus	= { 0x104, 15, 0, 0, 0x1d1 },
   1476				.ls_det_en	= { 0x110, 1, 1, 0, 1 },
   1477				.ls_det_st	= { 0x114, 1, 1, 0, 1 },
   1478				.ls_det_clr	= { 0x118, 1, 1, 0, 1 },
   1479				.utmi_ls	= { 0x120, 17, 16, 0, 1 },
   1480				.utmi_hstdet	= { 0x120, 19, 19, 0, 1 }
   1481			}
   1482		},
   1483		.chg_det = {
   1484			.opmode		= { 0x0100, 3, 0, 5, 1 },
   1485			.cp_det		= { 0x0120, 24, 24, 0, 1 },
   1486			.dcp_det	= { 0x0120, 23, 23, 0, 1 },
   1487			.dp_det		= { 0x0120, 25, 25, 0, 1 },
   1488			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
   1489			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
   1490			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
   1491			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
   1492			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
   1493			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
   1494		},
   1495	},
   1496	{ /* sentinel */ }
   1497};
   1498
   1499static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
   1500	{
   1501		.reg = 0x700,
   1502		.num_ports	= 2,
   1503		.clkout_ctl	= { 0x0724, 15, 15, 1, 0 },
   1504		.port_cfgs	= {
   1505			[USB2PHY_PORT_HOST] = {
   1506				.phy_sus	= { 0x0728, 15, 0, 0, 0x1d1 },
   1507				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
   1508				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
   1509				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 },
   1510				.utmi_ls	= { 0x049c, 14, 13, 0, 1 },
   1511				.utmi_hstdet	= { 0x049c, 12, 12, 0, 1 }
   1512			}
   1513		},
   1514	},
   1515	{ /* sentinel */ }
   1516};
   1517
   1518static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
   1519	{
   1520		.reg		= 0xe450,
   1521		.num_ports	= 2,
   1522		.clkout_ctl	= { 0xe450, 4, 4, 1, 0 },
   1523		.port_cfgs	= {
   1524			[USB2PHY_PORT_OTG] = {
   1525				.phy_sus	= { 0xe454, 1, 0, 2, 1 },
   1526				.bvalid_det_en	= { 0xe3c0, 3, 3, 0, 1 },
   1527				.bvalid_det_st	= { 0xe3e0, 3, 3, 0, 1 },
   1528				.bvalid_det_clr	= { 0xe3d0, 3, 3, 0, 1 },
   1529				.id_det_en	= { 0xe3c0, 5, 4, 0, 3 },
   1530				.id_det_st	= { 0xe3e0, 5, 4, 0, 3 },
   1531				.id_det_clr	= { 0xe3d0, 5, 4, 0, 3 },
   1532				.utmi_avalid	= { 0xe2ac, 7, 7, 0, 1 },
   1533				.utmi_bvalid	= { 0xe2ac, 12, 12, 0, 1 },
   1534				.utmi_id	= { 0xe2ac, 8, 8, 0, 1 },
   1535			},
   1536			[USB2PHY_PORT_HOST] = {
   1537				.phy_sus	= { 0xe458, 1, 0, 0x2, 0x1 },
   1538				.ls_det_en	= { 0xe3c0, 6, 6, 0, 1 },
   1539				.ls_det_st	= { 0xe3e0, 6, 6, 0, 1 },
   1540				.ls_det_clr	= { 0xe3d0, 6, 6, 0, 1 },
   1541				.utmi_ls	= { 0xe2ac, 22, 21, 0, 1 },
   1542				.utmi_hstdet	= { 0xe2ac, 23, 23, 0, 1 }
   1543			}
   1544		},
   1545		.chg_det = {
   1546			.opmode		= { 0xe454, 3, 0, 5, 1 },
   1547			.cp_det		= { 0xe2ac, 2, 2, 0, 1 },
   1548			.dcp_det	= { 0xe2ac, 1, 1, 0, 1 },
   1549			.dp_det		= { 0xe2ac, 0, 0, 0, 1 },
   1550			.idm_sink_en	= { 0xe450, 8, 8, 0, 1 },
   1551			.idp_sink_en	= { 0xe450, 7, 7, 0, 1 },
   1552			.idp_src_en	= { 0xe450, 9, 9, 0, 1 },
   1553			.rdm_pdwn_en	= { 0xe450, 10, 10, 0, 1 },
   1554			.vdm_src_en	= { 0xe450, 12, 12, 0, 1 },
   1555			.vdp_src_en	= { 0xe450, 11, 11, 0, 1 },
   1556		},
   1557	},
   1558	{
   1559		.reg		= 0xe460,
   1560		.num_ports	= 2,
   1561		.clkout_ctl	= { 0xe460, 4, 4, 1, 0 },
   1562		.port_cfgs	= {
   1563			[USB2PHY_PORT_OTG] = {
   1564				.phy_sus        = { 0xe464, 1, 0, 2, 1 },
   1565				.bvalid_det_en  = { 0xe3c0, 8, 8, 0, 1 },
   1566				.bvalid_det_st  = { 0xe3e0, 8, 8, 0, 1 },
   1567				.bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
   1568				.id_det_en	= { 0xe3c0, 10, 9, 0, 3 },
   1569				.id_det_st	= { 0xe3e0, 10, 9, 0, 3 },
   1570				.id_det_clr	= { 0xe3d0, 10, 9, 0, 3 },
   1571				.utmi_avalid	= { 0xe2ac, 10, 10, 0, 1 },
   1572				.utmi_bvalid    = { 0xe2ac, 16, 16, 0, 1 },
   1573				.utmi_id	= { 0xe2ac, 11, 11, 0, 1 },
   1574			},
   1575			[USB2PHY_PORT_HOST] = {
   1576				.phy_sus	= { 0xe468, 1, 0, 0x2, 0x1 },
   1577				.ls_det_en	= { 0xe3c0, 11, 11, 0, 1 },
   1578				.ls_det_st	= { 0xe3e0, 11, 11, 0, 1 },
   1579				.ls_det_clr	= { 0xe3d0, 11, 11, 0, 1 },
   1580				.utmi_ls	= { 0xe2ac, 26, 25, 0, 1 },
   1581				.utmi_hstdet	= { 0xe2ac, 27, 27, 0, 1 }
   1582			}
   1583		},
   1584	},
   1585	{ /* sentinel */ }
   1586};
   1587
   1588static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
   1589	{
   1590		.reg = 0xfe8a0000,
   1591		.num_ports	= 2,
   1592		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
   1593		.port_cfgs	= {
   1594			[USB2PHY_PORT_OTG] = {
   1595				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
   1596				.bvalid_det_en	= { 0x0080, 3, 2, 0, 3 },
   1597				.bvalid_det_st	= { 0x0084, 3, 2, 0, 3 },
   1598				.bvalid_det_clr = { 0x0088, 3, 2, 0, 3 },
   1599				.id_det_en	= { 0x0080, 5, 4, 0, 3 },
   1600				.id_det_st	= { 0x0084, 5, 4, 0, 3 },
   1601				.id_det_clr	= { 0x0088, 5, 4, 0, 3 },
   1602				.utmi_avalid	= { 0x00c0, 10, 10, 0, 1 },
   1603				.utmi_bvalid	= { 0x00c0, 9, 9, 0, 1 },
   1604				.utmi_id	= { 0x00c0, 6, 6, 0, 1 },
   1605			},
   1606			[USB2PHY_PORT_HOST] = {
   1607				/* Select suspend control from controller */
   1608				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d2 },
   1609				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
   1610				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
   1611				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
   1612				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
   1613				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
   1614			}
   1615		},
   1616		.chg_det = {
   1617			.opmode		= { 0x0000, 3, 0, 5, 1 },
   1618			.cp_det		= { 0x00c0, 24, 24, 0, 1 },
   1619			.dcp_det	= { 0x00c0, 23, 23, 0, 1 },
   1620			.dp_det		= { 0x00c0, 25, 25, 0, 1 },
   1621			.idm_sink_en	= { 0x0008, 8, 8, 0, 1 },
   1622			.idp_sink_en	= { 0x0008, 7, 7, 0, 1 },
   1623			.idp_src_en	= { 0x0008, 9, 9, 0, 1 },
   1624			.rdm_pdwn_en	= { 0x0008, 10, 10, 0, 1 },
   1625			.vdm_src_en	= { 0x0008, 12, 12, 0, 1 },
   1626			.vdp_src_en	= { 0x0008, 11, 11, 0, 1 },
   1627		},
   1628	},
   1629	{
   1630		.reg = 0xfe8b0000,
   1631		.num_ports	= 2,
   1632		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
   1633		.port_cfgs	= {
   1634			[USB2PHY_PORT_OTG] = {
   1635				.phy_sus	= { 0x0000, 8, 0, 0x1d2, 0x1d1 },
   1636				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
   1637				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
   1638				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
   1639				.utmi_ls	= { 0x00c0, 5, 4, 0, 1 },
   1640				.utmi_hstdet	= { 0x00c0, 7, 7, 0, 1 }
   1641			},
   1642			[USB2PHY_PORT_HOST] = {
   1643				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d1 },
   1644				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
   1645				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
   1646				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
   1647				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
   1648				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
   1649			}
   1650		},
   1651	},
   1652	{ /* sentinel */ }
   1653};
   1654
   1655static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
   1656	{
   1657		.reg = 0x100,
   1658		.num_ports	= 2,
   1659		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
   1660		.port_cfgs	= {
   1661			[USB2PHY_PORT_OTG] = {
   1662				.phy_sus	= { 0x0100, 15, 0, 0, 0x1d1 },
   1663				.bvalid_det_en	= { 0x0680, 3, 3, 0, 1 },
   1664				.bvalid_det_st	= { 0x0690, 3, 3, 0, 1 },
   1665				.bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
   1666				.ls_det_en	= { 0x0680, 2, 2, 0, 1 },
   1667				.ls_det_st	= { 0x0690, 2, 2, 0, 1 },
   1668				.ls_det_clr	= { 0x06a0, 2, 2, 0, 1 },
   1669				.utmi_bvalid	= { 0x0804, 10, 10, 0, 1 },
   1670				.utmi_ls	= { 0x0804, 13, 12, 0, 1 },
   1671			},
   1672			[USB2PHY_PORT_HOST] = {
   1673				.phy_sus	= { 0x0104, 15, 0, 0, 0x1d1 },
   1674				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
   1675				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
   1676				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 },
   1677				.utmi_ls	= { 0x0804, 9, 8, 0, 1 },
   1678				.utmi_hstdet	= { 0x0804, 7, 7, 0, 1 }
   1679			}
   1680		},
   1681		.chg_det = {
   1682			.opmode		= { 0x0100, 3, 0, 5, 1 },
   1683			.cp_det		= { 0x0804, 1, 1, 0, 1 },
   1684			.dcp_det	= { 0x0804, 0, 0, 0, 1 },
   1685			.dp_det		= { 0x0804, 2, 2, 0, 1 },
   1686			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
   1687			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
   1688			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
   1689			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
   1690			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
   1691			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
   1692		},
   1693	},
   1694	{ /* sentinel */ }
   1695};
   1696
   1697static const struct of_device_id rockchip_usb2phy_dt_match[] = {
   1698	{ .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
   1699	{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
   1700	{ .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
   1701	{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
   1702	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
   1703	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
   1704	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
   1705	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
   1706	{}
   1707};
   1708MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match);
   1709
   1710static struct platform_driver rockchip_usb2phy_driver = {
   1711	.probe		= rockchip_usb2phy_probe,
   1712	.driver		= {
   1713		.name	= "rockchip-usb2phy",
   1714		.of_match_table = rockchip_usb2phy_dt_match,
   1715	},
   1716};
   1717module_platform_driver(rockchip_usb2phy_driver);
   1718
   1719MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
   1720MODULE_DESCRIPTION("Rockchip USB2.0 PHY driver");
   1721MODULE_LICENSE("GPL v2");