brintos

brintos / linux-shallow public Read only

0
0
Text · 3.9 KiB · 97bd363 Raw
166 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) 2015 Linaro Ltd.4 * Copyright (c) 2015 HiSilicon Limited.5 */6 7#include <linux/mfd/syscon.h>8#include <linux/mod_devicetable.h>9#include <linux/module.h>10#include <linux/platform_device.h>11#include <linux/phy/phy.h>12#include <linux/regmap.h>13 14#define SC_PERIPH_CTRL4			0x00c15 16#define CTRL4_PICO_SIDDQ		BIT(6)17#define CTRL4_PICO_OGDISABLE		BIT(8)18#define CTRL4_PICO_VBUSVLDEXT		BIT(10)19#define CTRL4_PICO_VBUSVLDEXTSEL	BIT(11)20#define CTRL4_OTG_PHY_SEL		BIT(21)21 22#define SC_PERIPH_CTRL5			0x01023 24#define CTRL5_USBOTG_RES_SEL		BIT(3)25#define CTRL5_PICOPHY_ACAENB		BIT(4)26#define CTRL5_PICOPHY_BC_MODE		BIT(5)27#define CTRL5_PICOPHY_CHRGSEL		BIT(6)28#define CTRL5_PICOPHY_VDATSRCEND	BIT(7)29#define CTRL5_PICOPHY_VDATDETENB	BIT(8)30#define CTRL5_PICOPHY_DCDENB		BIT(9)31#define CTRL5_PICOPHY_IDDIG		BIT(10)32 33#define SC_PERIPH_CTRL8			0x01834#define SC_PERIPH_RSTEN0		0x30035#define SC_PERIPH_RSTDIS0		0x30436 37#define RST0_USBOTG_BUS			BIT(4)38#define RST0_POR_PICOPHY		BIT(5)39#define RST0_USBOTG			BIT(6)40#define RST0_USBOTG_32K			BIT(7)41 42#define EYE_PATTERN_PARA		0x7053348c43 44struct hi6220_priv {45	struct regmap *reg;46	struct device *dev;47};48 49static void hi6220_phy_init(struct hi6220_priv *priv)50{51	struct regmap *reg = priv->reg;52	u32 val, mask;53 54	val = RST0_USBOTG_BUS | RST0_POR_PICOPHY |55	      RST0_USBOTG | RST0_USBOTG_32K;56	mask = val;57	regmap_update_bits(reg, SC_PERIPH_RSTEN0, mask, val);58	regmap_update_bits(reg, SC_PERIPH_RSTDIS0, mask, val);59}60 61static int hi6220_phy_setup(struct hi6220_priv *priv, bool on)62{63	struct regmap *reg = priv->reg;64	u32 val, mask;65	int ret;66 67	if (on) {68		val = CTRL5_USBOTG_RES_SEL | CTRL5_PICOPHY_ACAENB;69		mask = val | CTRL5_PICOPHY_BC_MODE;70		ret = regmap_update_bits(reg, SC_PERIPH_CTRL5, mask, val);71		if (ret)72			goto out;73 74		val =  CTRL4_PICO_VBUSVLDEXT | CTRL4_PICO_VBUSVLDEXTSEL |75		       CTRL4_OTG_PHY_SEL;76		mask = val | CTRL4_PICO_SIDDQ | CTRL4_PICO_OGDISABLE;77		ret = regmap_update_bits(reg, SC_PERIPH_CTRL4, mask, val);78		if (ret)79			goto out;80 81		ret = regmap_write(reg, SC_PERIPH_CTRL8, EYE_PATTERN_PARA);82		if (ret)83			goto out;84	} else {85		val = CTRL4_PICO_SIDDQ;86		mask = val;87		ret = regmap_update_bits(reg, SC_PERIPH_CTRL4, mask, val);88		if (ret)89			goto out;90	}91 92	return 0;93out:94	dev_err(priv->dev, "failed to setup phy ret: %d\n", ret);95	return ret;96}97 98static int hi6220_phy_start(struct phy *phy)99{100	struct hi6220_priv *priv = phy_get_drvdata(phy);101 102	return hi6220_phy_setup(priv, true);103}104 105static int hi6220_phy_exit(struct phy *phy)106{107	struct hi6220_priv *priv = phy_get_drvdata(phy);108 109	return hi6220_phy_setup(priv, false);110}111 112static const struct phy_ops hi6220_phy_ops = {113	.init		= hi6220_phy_start,114	.exit		= hi6220_phy_exit,115	.owner		= THIS_MODULE,116};117 118static int hi6220_phy_probe(struct platform_device *pdev)119{120	struct phy_provider *phy_provider;121	struct device *dev = &pdev->dev;122	struct phy *phy;123	struct hi6220_priv *priv;124 125	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);126	if (!priv)127		return -ENOMEM;128 129	priv->dev = dev;130	priv->reg = syscon_regmap_lookup_by_phandle(dev->of_node,131					"hisilicon,peripheral-syscon");132	if (IS_ERR(priv->reg)) {133		dev_err(dev, "no hisilicon,peripheral-syscon\n");134		return PTR_ERR(priv->reg);135	}136 137	hi6220_phy_init(priv);138 139	phy = devm_phy_create(dev, NULL, &hi6220_phy_ops);140	if (IS_ERR(phy))141		return PTR_ERR(phy);142 143	phy_set_drvdata(phy, priv);144	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);145	return PTR_ERR_OR_ZERO(phy_provider);146}147 148static const struct of_device_id hi6220_phy_of_match[] = {149	{.compatible = "hisilicon,hi6220-usb-phy",},150	{ },151};152MODULE_DEVICE_TABLE(of, hi6220_phy_of_match);153 154static struct platform_driver hi6220_phy_driver = {155	.probe	= hi6220_phy_probe,156	.driver = {157		.name	= "hi6220-usb-phy",158		.of_match_table	= hi6220_phy_of_match,159	}160};161module_platform_driver(hi6220_phy_driver);162 163MODULE_DESCRIPTION("HISILICON HI6220 USB PHY driver");164MODULE_ALIAS("platform:hi6220-usb-phy");165MODULE_LICENSE("GPL");166