blob: e70d20432e036d9c5ebd3ad02d72a9307f957c9b [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +02002/*
Nishanth Menoneaa39c62023-11-01 15:56:03 -05003 * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +02004 * Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +02005 */
6
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +02007#include <dm.h>
8#include <generic-phy.h>
9
Patrice Chotard030dd072020-07-28 09:13:32 +020010#define DRIVER_DATA 0x12345678
11
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +020012struct sandbox_phy_priv {
13 bool initialized;
14 bool on;
15 bool broken;
16};
17
18static int sandbox_phy_power_on(struct phy *phy)
19{
20 struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
21
22 if (!priv->initialized)
23 return -EIO;
24
25 if (priv->broken)
26 return -EIO;
27
28 priv->on = true;
29
30 return 0;
31}
32
33static int sandbox_phy_power_off(struct phy *phy)
34{
35 struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
36
37 if (!priv->initialized)
38 return -EIO;
39
40 if (priv->broken)
41 return -EIO;
42
43 /*
44 * for validation purpose, let's says that power off
45 * works only for PHY 0
46 */
47 if (phy->id)
48 return -EIO;
49
50 priv->on = false;
51
52 return 0;
53}
54
55static int sandbox_phy_init(struct phy *phy)
56{
57 struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
58
59 priv->initialized = true;
60 priv->on = true;
61
62 return 0;
63}
64
65static int sandbox_phy_exit(struct phy *phy)
66{
67 struct sandbox_phy_priv *priv = dev_get_priv(phy->dev);
68
69 priv->initialized = false;
70 priv->on = false;
71
72 return 0;
73}
74
Marek Vasut2c61c152024-09-08 23:09:05 +020075static int
76sandbox_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
77{
78 if (submode)
79 return -EOPNOTSUPP;
80
81 if (mode != PHY_MODE_USB_HOST)
82 return -EINVAL;
83
84 return 0;
85}
86
Patrice Chotard030dd072020-07-28 09:13:32 +020087static int sandbox_phy_bind(struct udevice *dev)
88{
89 if (dev_get_driver_data(dev) != DRIVER_DATA)
90 return -ENODATA;
91
92 return 0;
93}
94
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +020095static int sandbox_phy_probe(struct udevice *dev)
96{
97 struct sandbox_phy_priv *priv = dev_get_priv(dev);
98
99 priv->initialized = false;
100 priv->on = false;
Simon Glasscfe0c902017-05-18 20:09:48 -0600101 priv->broken = dev_read_bool(dev, "broken");
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +0200102
103 return 0;
104}
105
106static struct phy_ops sandbox_phy_ops = {
107 .power_on = sandbox_phy_power_on,
108 .power_off = sandbox_phy_power_off,
109 .init = sandbox_phy_init,
110 .exit = sandbox_phy_exit,
Marek Vasut2c61c152024-09-08 23:09:05 +0200111 .set_mode = sandbox_phy_set_mode,
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +0200112};
113
114static const struct udevice_id sandbox_phy_ids[] = {
Patrice Chotard030dd072020-07-28 09:13:32 +0200115 { .compatible = "sandbox,phy_no_driver_data",
116 },
117
118 { .compatible = "sandbox,phy",
119 .data = DRIVER_DATA
120 },
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +0200121 { }
122};
123
124U_BOOT_DRIVER(phy_sandbox) = {
125 .name = "phy_sandbox",
126 .id = UCLASS_PHY,
Patrice Chotard030dd072020-07-28 09:13:32 +0200127 .bind = sandbox_phy_bind,
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +0200128 .of_match = sandbox_phy_ids,
129 .ops = &sandbox_phy_ops,
130 .probe = sandbox_phy_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700131 .priv_auto = sizeof(struct sandbox_phy_priv),
Jean-Jacques Hiblot7e9db022017-04-24 11:51:28 +0200132};