Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2016 Linaro Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/ulpi/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/ulpi/regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/pinctrl/pinctrl-state.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define ULPI_HSIC_CFG		0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define ULPI_HSIC_IO_CAL	0x33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) struct qcom_usb_hsic_phy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	struct ulpi *ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	struct pinctrl *pctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	struct clk *phy_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	struct clk *cal_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	struct clk *cal_sleep_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static int qcom_usb_hsic_phy_power_on(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	struct ulpi *ulpi = uphy->ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	struct pinctrl_state *pins_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	ret = clk_prepare_enable(uphy->phy_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	ret = clk_prepare_enable(uphy->cal_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		goto err_cal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	ret = clk_prepare_enable(uphy->cal_sleep_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		goto err_sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	/* Set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	ret = ulpi_write(ulpi, ULPI_HSIC_IO_CAL, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		goto err_ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	/* Enable periodic IO calibration in HSIC_CFG register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	ret = ulpi_write(ulpi, ULPI_HSIC_CFG, 0xa8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		goto err_ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	/* Configure pins for HSIC functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	if (IS_ERR(pins_default))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		return PTR_ERR(pins_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	ret = pinctrl_select_state(uphy->pctl, pins_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		goto err_ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	 /* Enable HSIC mode in HSIC_CFG register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	ret = ulpi_write(ulpi, ULPI_SET(ULPI_HSIC_CFG), 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		goto err_ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	/* Disable auto-resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	ret = ulpi_write(ulpi, ULPI_CLR(ULPI_IFC_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			 ULPI_IFC_CTRL_AUTORESUME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		goto err_ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) err_ulpi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	clk_disable_unprepare(uphy->cal_sleep_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) err_sleep:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	clk_disable_unprepare(uphy->cal_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) err_cal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	clk_disable_unprepare(uphy->phy_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static int qcom_usb_hsic_phy_power_off(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	clk_disable_unprepare(uphy->cal_sleep_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	clk_disable_unprepare(uphy->cal_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	clk_disable_unprepare(uphy->phy_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static const struct phy_ops qcom_usb_hsic_phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	.power_on = qcom_usb_hsic_phy_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	.power_off = qcom_usb_hsic_phy_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	struct qcom_usb_hsic_phy *uphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	struct phy_provider *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	uphy = devm_kzalloc(&ulpi->dev, sizeof(*uphy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (!uphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	ulpi_set_drvdata(ulpi, uphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	uphy->ulpi = ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	uphy->pctl = devm_pinctrl_get(&ulpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (IS_ERR(uphy->pctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		return PTR_ERR(uphy->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	uphy->phy_clk = clk = devm_clk_get(&ulpi->dev, "phy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	uphy->cal_clk = clk = devm_clk_get(&ulpi->dev, "cal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 				    &qcom_usb_hsic_phy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (IS_ERR(uphy->phy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		return PTR_ERR(uphy->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	phy_set_drvdata(uphy->phy, uphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	p = devm_of_phy_provider_register(&ulpi->dev, of_phy_simple_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return PTR_ERR_OR_ZERO(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static const struct of_device_id qcom_usb_hsic_phy_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	{ .compatible = "qcom,usb-hsic-phy", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) MODULE_DEVICE_TABLE(of, qcom_usb_hsic_phy_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static struct ulpi_driver qcom_usb_hsic_phy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	.probe = qcom_usb_hsic_phy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		.name = "qcom_usb_hsic_phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		.of_match_table = qcom_usb_hsic_phy_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) module_ulpi_driver(qcom_usb_hsic_phy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) MODULE_DESCRIPTION("Qualcomm USB HSIC phy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) MODULE_LICENSE("GPL v2");