Merge tag 'u-boot-imx-20200825' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
[platform/kernel/u-boot.git] / drivers / phy / sandbox-phy.c
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
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
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
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
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
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
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_alloc_size = sizeof(struct sandbox_phy_priv),
120 };