xref: /rk3399_rockchip-uboot/drivers/phy/phy-uclass.c (revision 72e5016f878d142e925f0016cee4ee7cbf42ae5b)
1*72e5016fSJean-Jacques Hiblot /*
2*72e5016fSJean-Jacques Hiblot  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
3*72e5016fSJean-Jacques Hiblot  * Written by Jean-Jacques Hiblot  <jjhiblot@ti.com>
4*72e5016fSJean-Jacques Hiblot  *
5*72e5016fSJean-Jacques Hiblot  * SPDX-License-Identifier:	GPL-2.0+
6*72e5016fSJean-Jacques Hiblot  */
7*72e5016fSJean-Jacques Hiblot 
8*72e5016fSJean-Jacques Hiblot #include <common.h>
9*72e5016fSJean-Jacques Hiblot #include <dm.h>
10*72e5016fSJean-Jacques Hiblot #include <generic-phy.h>
11*72e5016fSJean-Jacques Hiblot 
12*72e5016fSJean-Jacques Hiblot DECLARE_GLOBAL_DATA_PTR;
13*72e5016fSJean-Jacques Hiblot 
14*72e5016fSJean-Jacques Hiblot static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
15*72e5016fSJean-Jacques Hiblot {
16*72e5016fSJean-Jacques Hiblot 	return (struct phy_ops *)dev->driver->ops;
17*72e5016fSJean-Jacques Hiblot }
18*72e5016fSJean-Jacques Hiblot 
19*72e5016fSJean-Jacques Hiblot static int generic_phy_xlate_offs_flags(struct phy *phy,
20*72e5016fSJean-Jacques Hiblot 				 struct fdtdec_phandle_args *args)
21*72e5016fSJean-Jacques Hiblot {
22*72e5016fSJean-Jacques Hiblot 	debug("%s(phy=%p)\n", __func__, phy);
23*72e5016fSJean-Jacques Hiblot 
24*72e5016fSJean-Jacques Hiblot 	if (args->args_count > 1) {
25*72e5016fSJean-Jacques Hiblot 		debug("Invaild args_count: %d\n", args->args_count);
26*72e5016fSJean-Jacques Hiblot 		return -EINVAL;
27*72e5016fSJean-Jacques Hiblot 	}
28*72e5016fSJean-Jacques Hiblot 
29*72e5016fSJean-Jacques Hiblot 	if (args->args_count)
30*72e5016fSJean-Jacques Hiblot 		phy->id = args->args[0];
31*72e5016fSJean-Jacques Hiblot 	else
32*72e5016fSJean-Jacques Hiblot 		phy->id = 0;
33*72e5016fSJean-Jacques Hiblot 
34*72e5016fSJean-Jacques Hiblot 
35*72e5016fSJean-Jacques Hiblot 	return 0;
36*72e5016fSJean-Jacques Hiblot }
37*72e5016fSJean-Jacques Hiblot 
38*72e5016fSJean-Jacques Hiblot int generic_phy_get_by_index(struct udevice *dev, int index,
39*72e5016fSJean-Jacques Hiblot 			     struct phy *phy)
40*72e5016fSJean-Jacques Hiblot {
41*72e5016fSJean-Jacques Hiblot 	struct fdtdec_phandle_args args;
42*72e5016fSJean-Jacques Hiblot 	struct phy_ops *ops;
43*72e5016fSJean-Jacques Hiblot 	int ret;
44*72e5016fSJean-Jacques Hiblot 	struct udevice *phydev;
45*72e5016fSJean-Jacques Hiblot 
46*72e5016fSJean-Jacques Hiblot 	debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
47*72e5016fSJean-Jacques Hiblot 
48*72e5016fSJean-Jacques Hiblot 	assert(phy);
49*72e5016fSJean-Jacques Hiblot 	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
50*72e5016fSJean-Jacques Hiblot 					     "phys", "#phy-cells", 0, index,
51*72e5016fSJean-Jacques Hiblot 					     &args);
52*72e5016fSJean-Jacques Hiblot 	if (ret) {
53*72e5016fSJean-Jacques Hiblot 		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
54*72e5016fSJean-Jacques Hiblot 		      __func__, ret);
55*72e5016fSJean-Jacques Hiblot 		return ret;
56*72e5016fSJean-Jacques Hiblot 	}
57*72e5016fSJean-Jacques Hiblot 
58*72e5016fSJean-Jacques Hiblot 	ret = uclass_get_device_by_of_offset(UCLASS_PHY, args.node, &phydev);
59*72e5016fSJean-Jacques Hiblot 	if (ret) {
60*72e5016fSJean-Jacques Hiblot 		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
61*72e5016fSJean-Jacques Hiblot 		      __func__, ret);
62*72e5016fSJean-Jacques Hiblot 		return ret;
63*72e5016fSJean-Jacques Hiblot 	}
64*72e5016fSJean-Jacques Hiblot 
65*72e5016fSJean-Jacques Hiblot 	phy->dev = phydev;
66*72e5016fSJean-Jacques Hiblot 
67*72e5016fSJean-Jacques Hiblot 	ops = phy_dev_ops(phydev);
68*72e5016fSJean-Jacques Hiblot 
69*72e5016fSJean-Jacques Hiblot 	if (ops->of_xlate)
70*72e5016fSJean-Jacques Hiblot 		ret = ops->of_xlate(phy, &args);
71*72e5016fSJean-Jacques Hiblot 	else
72*72e5016fSJean-Jacques Hiblot 		ret = generic_phy_xlate_offs_flags(phy, &args);
73*72e5016fSJean-Jacques Hiblot 	if (ret) {
74*72e5016fSJean-Jacques Hiblot 		debug("of_xlate() failed: %d\n", ret);
75*72e5016fSJean-Jacques Hiblot 		goto err;
76*72e5016fSJean-Jacques Hiblot 	}
77*72e5016fSJean-Jacques Hiblot 
78*72e5016fSJean-Jacques Hiblot 	return 0;
79*72e5016fSJean-Jacques Hiblot 
80*72e5016fSJean-Jacques Hiblot err:
81*72e5016fSJean-Jacques Hiblot 	return ret;
82*72e5016fSJean-Jacques Hiblot }
83*72e5016fSJean-Jacques Hiblot 
84*72e5016fSJean-Jacques Hiblot int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
85*72e5016fSJean-Jacques Hiblot 			    struct phy *phy)
86*72e5016fSJean-Jacques Hiblot {
87*72e5016fSJean-Jacques Hiblot 	int index;
88*72e5016fSJean-Jacques Hiblot 
89*72e5016fSJean-Jacques Hiblot 	debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
90*72e5016fSJean-Jacques Hiblot 
91*72e5016fSJean-Jacques Hiblot 	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
92*72e5016fSJean-Jacques Hiblot 				      "phy-names", phy_name);
93*72e5016fSJean-Jacques Hiblot 	if (index < 0) {
94*72e5016fSJean-Jacques Hiblot 		debug("fdt_stringlist_search() failed: %d\n", index);
95*72e5016fSJean-Jacques Hiblot 		return index;
96*72e5016fSJean-Jacques Hiblot 	}
97*72e5016fSJean-Jacques Hiblot 
98*72e5016fSJean-Jacques Hiblot 	return generic_phy_get_by_index(dev, index, phy);
99*72e5016fSJean-Jacques Hiblot }
100*72e5016fSJean-Jacques Hiblot 
101*72e5016fSJean-Jacques Hiblot int generic_phy_init(struct phy *phy)
102*72e5016fSJean-Jacques Hiblot {
103*72e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
104*72e5016fSJean-Jacques Hiblot 
105*72e5016fSJean-Jacques Hiblot 	return ops->init ? ops->init(phy) : 0;
106*72e5016fSJean-Jacques Hiblot }
107*72e5016fSJean-Jacques Hiblot 
108*72e5016fSJean-Jacques Hiblot int generic_phy_reset(struct phy *phy)
109*72e5016fSJean-Jacques Hiblot {
110*72e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
111*72e5016fSJean-Jacques Hiblot 
112*72e5016fSJean-Jacques Hiblot 	return ops->reset ? ops->reset(phy) : 0;
113*72e5016fSJean-Jacques Hiblot }
114*72e5016fSJean-Jacques Hiblot 
115*72e5016fSJean-Jacques Hiblot int generic_phy_exit(struct phy *phy)
116*72e5016fSJean-Jacques Hiblot {
117*72e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
118*72e5016fSJean-Jacques Hiblot 
119*72e5016fSJean-Jacques Hiblot 	return ops->exit ? ops->exit(phy) : 0;
120*72e5016fSJean-Jacques Hiblot }
121*72e5016fSJean-Jacques Hiblot 
122*72e5016fSJean-Jacques Hiblot int generic_phy_power_on(struct phy *phy)
123*72e5016fSJean-Jacques Hiblot {
124*72e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
125*72e5016fSJean-Jacques Hiblot 
126*72e5016fSJean-Jacques Hiblot 	return ops->power_on ? ops->power_on(phy) : 0;
127*72e5016fSJean-Jacques Hiblot }
128*72e5016fSJean-Jacques Hiblot 
129*72e5016fSJean-Jacques Hiblot int generic_phy_power_off(struct phy *phy)
130*72e5016fSJean-Jacques Hiblot {
131*72e5016fSJean-Jacques Hiblot 	struct phy_ops const *ops = phy_dev_ops(phy->dev);
132*72e5016fSJean-Jacques Hiblot 
133*72e5016fSJean-Jacques Hiblot 	return ops->power_off ? ops->power_off(phy) : 0;
134*72e5016fSJean-Jacques Hiblot }
135*72e5016fSJean-Jacques Hiblot 
136*72e5016fSJean-Jacques Hiblot UCLASS_DRIVER(phy) = {
137*72e5016fSJean-Jacques Hiblot 	.id		= UCLASS_PHY,
138*72e5016fSJean-Jacques Hiblot 	.name		= "phy",
139*72e5016fSJean-Jacques Hiblot };
140