blob: 7b3d988613bd08bfc765eb0166c75845ac3e4e8a [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +02002/*
3 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
4 * Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +02005 */
6
7#include <common.h>
8#include <dm.h>
9#include <generic-phy.h>
10
Patrice Chotardcfa3ed42020-07-28 09:13:32 +020011#define DRIVER_DATA 0x12345678
12
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +020013struct 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
Patrice Chotardcfa3ed42020-07-28 09:13:32 +020076static 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
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +020084static 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;
Simon Glass5204e9b2017-05-18 20:09:48 -060090 priv->broken = dev_read_bool(dev, "broken");
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +020091
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[] = {
Patrice Chotardcfa3ed42020-07-28 09:13:32 +0200103 { .compatible = "sandbox,phy_no_driver_data",
104 },
105
106 { .compatible = "sandbox,phy",
107 .data = DRIVER_DATA
108 },
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +0200109 { }
110};
111
112U_BOOT_DRIVER(phy_sandbox) = {
113 .name = "phy_sandbox",
114 .id = UCLASS_PHY,
Patrice Chotardcfa3ed42020-07-28 09:13:32 +0200115 .bind = sandbox_phy_bind,
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +0200116 .of_match = sandbox_phy_ids,
117 .ops = &sandbox_phy_ops,
118 .probe = sandbox_phy_probe,
Simon Glass41575d82020-12-03 16:55:17 -0700119 .priv_auto = sizeof(struct sandbox_phy_priv),
Jean-Jacques Hiblot86322f52017-04-24 11:51:28 +0200120};