uboot/drivers/phy/phy-uclass.c
<<
>>
Prefs
   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
  11static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
  12{
  13        return (struct phy_ops *)dev->driver->ops;
  14}
  15
  16static int generic_phy_xlate_offs_flags(struct phy *phy,
  17                                        struct ofnode_phandle_args *args)
  18{
  19        debug("%s(phy=%p)\n", __func__, phy);
  20
  21        if (args->args_count > 1) {
  22                debug("Invaild args_count: %d\n", args->args_count);
  23                return -EINVAL;
  24        }
  25
  26        if (args->args_count)
  27                phy->id = args->args[0];
  28        else
  29                phy->id = 0;
  30
  31        return 0;
  32}
  33
  34int generic_phy_get_by_index(struct udevice *dev, int index,
  35                             struct phy *phy)
  36{
  37        struct ofnode_phandle_args args;
  38        struct phy_ops *ops;
  39        struct udevice *phydev;
  40        int i, ret;
  41
  42        debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
  43
  44        assert(phy);
  45        phy->dev = NULL;
  46        ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
  47                                         &args);
  48        if (ret) {
  49                debug("%s: dev_read_phandle_with_args failed: err=%d\n",
  50                      __func__, ret);
  51                return ret;
  52        }
  53
  54        ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
  55        if (ret) {
  56                debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
  57                      __func__, ret);
  58
  59                /* Check if args.node's parent is a PHY provider */
  60                ret = uclass_get_device_by_ofnode(UCLASS_PHY,
  61                                                  ofnode_get_parent(args.node),
  62                                                  &phydev);
  63                if (ret)
  64                        return ret;
  65
  66                /* insert phy idx at first position into args array */
  67                for (i = args.args_count; i >= 1 ; i--)
  68                        args.args[i] = args.args[i - 1];
  69
  70                args.args_count++;
  71                args.args[0] = ofnode_read_u32_default(args.node, "reg", -1);
  72        }
  73
  74        phy->dev = phydev;
  75
  76        ops = phy_dev_ops(phydev);
  77
  78        if (ops->of_xlate)
  79                ret = ops->of_xlate(phy, &args);
  80        else
  81                ret = generic_phy_xlate_offs_flags(phy, &args);
  82        if (ret) {
  83                debug("of_xlate() failed: %d\n", ret);
  84                goto err;
  85        }
  86
  87        return 0;
  88
  89err:
  90        return ret;
  91}
  92
  93int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
  94                            struct phy *phy)
  95{
  96        int index;
  97
  98        debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
  99
 100        index = dev_read_stringlist_search(dev, "phy-names", phy_name);
 101        if (index < 0) {
 102                debug("dev_read_stringlist_search() failed: %d\n", index);
 103                return index;
 104        }
 105
 106        return generic_phy_get_by_index(dev, index, phy);
 107}
 108
 109int generic_phy_init(struct phy *phy)
 110{
 111        struct phy_ops const *ops;
 112
 113        if (!phy)
 114                return 0;
 115        ops = phy_dev_ops(phy->dev);
 116
 117        return ops->init ? ops->init(phy) : 0;
 118}
 119
 120int generic_phy_reset(struct phy *phy)
 121{
 122        struct phy_ops const *ops;
 123
 124        if (!phy)
 125                return 0;
 126        ops = phy_dev_ops(phy->dev);
 127
 128        return ops->reset ? ops->reset(phy) : 0;
 129}
 130
 131int generic_phy_exit(struct phy *phy)
 132{
 133        struct phy_ops const *ops;
 134
 135        if (!phy)
 136                return 0;
 137        ops = phy_dev_ops(phy->dev);
 138
 139        return ops->exit ? ops->exit(phy) : 0;
 140}
 141
 142int generic_phy_power_on(struct phy *phy)
 143{
 144        struct phy_ops const *ops;
 145
 146        if (!phy)
 147                return 0;
 148        ops = phy_dev_ops(phy->dev);
 149
 150        return ops->power_on ? ops->power_on(phy) : 0;
 151}
 152
 153int generic_phy_power_off(struct phy *phy)
 154{
 155        struct phy_ops const *ops;
 156
 157        if (!phy)
 158                return 0;
 159        ops = phy_dev_ops(phy->dev);
 160
 161        return ops->power_off ? ops->power_off(phy) : 0;
 162}
 163
 164UCLASS_DRIVER(phy) = {
 165        .id             = UCLASS_PHY,
 166        .name           = "phy",
 167};
 168