1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2020-2022 Bootlin 4 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 5 */ 6 7 #include <linux/phy/phy.h> 8 #include <linux/regmap.h> 9 10 #include "sun8i_a83t_dphy.h" 11 #include "sun8i_a83t_mipi_csi2.h" 12 13 static int sun8i_a83t_dphy_configure(struct phy *dphy, 14 union phy_configure_opts *opts) 15 { 16 return phy_mipi_dphy_config_validate(&opts->mipi_dphy); 17 } 18 19 static int sun8i_a83t_dphy_power_on(struct phy *dphy) 20 { 21 struct sun8i_a83t_mipi_csi2_device *csi2_dev = phy_get_drvdata(dphy); 22 struct regmap *regmap = csi2_dev->regmap; 23 24 regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG, 25 SUN8I_A83T_DPHY_CTRL_RESET_N | 26 SUN8I_A83T_DPHY_CTRL_SHUTDOWN_N); 27 28 regmap_write(regmap, SUN8I_A83T_DPHY_ANA0_REG, 29 SUN8I_A83T_DPHY_ANA0_REXT_EN | 30 SUN8I_A83T_DPHY_ANA0_RINT(2) | 31 SUN8I_A83T_DPHY_ANA0_SNK(2)); 32 33 return 0; 34 }; 35 36 static int sun8i_a83t_dphy_power_off(struct phy *dphy) 37 { 38 struct sun8i_a83t_mipi_csi2_device *csi2_dev = phy_get_drvdata(dphy); 39 struct regmap *regmap = csi2_dev->regmap; 40 41 regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG, 0); 42 43 return 0; 44 }; 45 46 static const struct phy_ops sun8i_a83t_dphy_ops = { 47 .configure = sun8i_a83t_dphy_configure, 48 .power_on = sun8i_a83t_dphy_power_on, 49 .power_off = sun8i_a83t_dphy_power_off, 50 }; 51 52 int sun8i_a83t_dphy_register(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 53 { 54 struct device *dev = csi2_dev->dev; 55 struct phy_provider *phy_provider; 56 57 csi2_dev->dphy = devm_phy_create(dev, NULL, &sun8i_a83t_dphy_ops); 58 if (IS_ERR(csi2_dev->dphy)) { 59 dev_err(dev, "failed to create D-PHY\n"); 60 return PTR_ERR(csi2_dev->dphy); 61 } 62 63 phy_set_drvdata(csi2_dev->dphy, csi2_dev); 64 65 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 66 if (IS_ERR(phy_provider)) { 67 dev_err(dev, "failed to register D-PHY provider\n"); 68 return PTR_ERR(phy_provider); 69 } 70 71 return 0; 72 } 73