1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
4  * Written by Jean-Jacques Hiblot  <jjhiblot@ti.com>
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <generic-phy.h>
10 
11 #define DRIVER_DATA 0x12345678
12 
13 struct sandbox_phy_priv {
14 	bool initialized;
15 	bool on;
16 	bool broken;
17 };
18 
sandbox_phy_power_on(struct phy * phy)19 static int sandbox_phy_power_on(struct phy *phy)
20 {
21 	struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
22 
23 	if (!priv->initialized)
24 		return -EIO;
25 
26 	if (priv->broken)
27 		return -EIO;
28 
29 	priv->on = true;
30 
31 	return 0;
32 }
33 
sandbox_phy_power_off(struct phy * phy)34 static int sandbox_phy_power_off(struct phy *phy)
35 {
36 	struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
37 
38 	if (!priv->initialized)
39 		return -EIO;
40 
41 	if (priv->broken)
42 		return -EIO;
43 
44 	/*
45 	 * for validation purpose, let's says that power off
46 	 * works only for PHY 0
47 	 */
48 	if (phy->id)
49 		return -EIO;
50 
51 	priv->on = false;
52 
53 	return 0;
54 }
55 
sandbox_phy_init(struct phy * phy)56 static int sandbox_phy_init(struct phy *phy)
57 {
58 	struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
59 
60 	priv->initialized = true;
61 	priv->on = true;
62 
63 	return 0;
64 }
65 
sandbox_phy_exit(struct phy * phy)66 static int sandbox_phy_exit(struct phy *phy)
67 {
68 	struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
69 
70 	priv->initialized = false;
71 	priv->on = false;
72 
73 	return 0;
74 }
75 
sandbox_phy_bind(struct udevice * dev)76 static int sandbox_phy_bind(struct udevice *dev)
77 {
78 	if (dev_get_driver_data(dev) != DRIVER_DATA)
79 		return -ENODATA;
80 
81 	return 0;
82 }
83 
sandbox_phy_probe(struct udevice * dev)84 static int sandbox_phy_probe(struct udevice *dev)
85 {
86 	struct sandbox_phy_priv *priv = dev_get_priv(dev);
87 
88 	priv->initialized = false;
89 	priv->on = false;
90 	priv->broken = dev_read_bool(dev, "broken");
91 
92 	return 0;
93 }
94 
95 static struct phy_ops sandbox_phy_ops = {
96 	.power_on = sandbox_phy_power_on,
97 	.power_off = sandbox_phy_power_off,
98 	.init = sandbox_phy_init,
99 	.exit = sandbox_phy_exit,
100 };
101 
102 static const struct udevice_id sandbox_phy_ids[] = {
103 	{ .compatible = "sandbox,phy_no_driver_data",
104 	},
105 
106 	{ .compatible = "sandbox,phy",
107 	  .data = DRIVER_DATA
108 	},
109 	{ }
110 };
111 
112 U_BOOT_DRIVER(phy_sandbox) = {
113 	.name		= "phy_sandbox",
114 	.id		= UCLASS_PHY,
115 	.bind		= sandbox_phy_bind,
116 	.of_match	= sandbox_phy_ids,
117 	.ops		= &sandbox_phy_ops,
118 	.probe		= sandbox_phy_probe,
119 	.priv_auto	= sizeof(struct sandbox_phy_priv),
120 };
121