1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2017 Texas Instruments Incorporated - https://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
13struct sandbox_phy_priv {
14	bool initialized;
15	bool on;
16	bool broken;
17};
18
19static 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
34static 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
56static 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
66static 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
76static 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
84static 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
95static 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
102static 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
112U_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