root/drivers/net/ethernet/arc/emac_mdio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arc_mdio_complete_wait
  2. arc_mdio_read
  3. arc_mdio_write
  4. arc_mdio_reset
  5. arc_mdio_probe
  6. arc_mdio_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
   4  *
   5  * MDIO implementation for ARC EMAC
   6  */
   7 
   8 #include <linux/delay.h>
   9 #include <linux/of_mdio.h>
  10 #include <linux/platform_device.h>
  11 #include <linux/gpio/consumer.h>
  12 
  13 #include "emac.h"
  14 
  15 /* Number of seconds we wait for "MDIO complete" flag to appear */
  16 #define ARC_MDIO_COMPLETE_POLL_COUNT    1
  17 
  18 /**
  19  * arc_mdio_complete_wait - Waits until MDIO transaction is completed.
  20  * @priv:       Pointer to ARC EMAC private data structure.
  21  *
  22  * returns:     0 on success, -ETIMEDOUT on a timeout.
  23  */
  24 static int arc_mdio_complete_wait(struct arc_emac_priv *priv)
  25 {
  26         unsigned int i;
  27 
  28         for (i = 0; i < ARC_MDIO_COMPLETE_POLL_COUNT * 40; i++) {
  29                 unsigned int status = arc_reg_get(priv, R_STATUS);
  30 
  31                 status &= MDIO_MASK;
  32 
  33                 if (status) {
  34                         /* Reset "MDIO complete" flag */
  35                         arc_reg_set(priv, R_STATUS, status);
  36                         return 0;
  37                 }
  38 
  39                 msleep(25);
  40         }
  41 
  42         return -ETIMEDOUT;
  43 }
  44 
  45 /**
  46  * arc_mdio_read - MDIO interface read function.
  47  * @bus:        Pointer to MII bus structure.
  48  * @phy_addr:   Address of the PHY device.
  49  * @reg_num:    PHY register to read.
  50  *
  51  * returns:     The register contents on success, -ETIMEDOUT on a timeout.
  52  *
  53  * Reads the contents of the requested register from the requested PHY
  54  * address.
  55  */
  56 static int arc_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
  57 {
  58         struct arc_emac_priv *priv = bus->priv;
  59         unsigned int value;
  60         int error;
  61 
  62         arc_reg_set(priv, R_MDIO,
  63                     0x60020000 | (phy_addr << 23) | (reg_num << 18));
  64 
  65         error = arc_mdio_complete_wait(priv);
  66         if (error < 0)
  67                 return error;
  68 
  69         value = arc_reg_get(priv, R_MDIO) & 0xffff;
  70 
  71         dev_dbg(priv->dev, "arc_mdio_read(phy_addr=%i, reg_num=%x) = %x\n",
  72                 phy_addr, reg_num, value);
  73 
  74         return value;
  75 }
  76 
  77 /**
  78  * arc_mdio_write - MDIO interface write function.
  79  * @bus:        Pointer to MII bus structure.
  80  * @phy_addr:   Address of the PHY device.
  81  * @reg_num:    PHY register to write to.
  82  * @value:      Value to be written into the register.
  83  *
  84  * returns:     0 on success, -ETIMEDOUT on a timeout.
  85  *
  86  * Writes the value to the requested register.
  87  */
  88 static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
  89                           int reg_num, u16 value)
  90 {
  91         struct arc_emac_priv *priv = bus->priv;
  92 
  93         dev_dbg(priv->dev,
  94                 "arc_mdio_write(phy_addr=%i, reg_num=%x, value=%x)\n",
  95                 phy_addr, reg_num, value);
  96 
  97         arc_reg_set(priv, R_MDIO,
  98                     0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
  99 
 100         return arc_mdio_complete_wait(priv);
 101 }
 102 
 103 /**
 104  * arc_mdio_reset
 105  * @bus: points to the mii_bus structure
 106  * Description: reset the MII bus
 107  */
 108 static int arc_mdio_reset(struct mii_bus *bus)
 109 {
 110         struct arc_emac_priv *priv = bus->priv;
 111         struct arc_emac_mdio_bus_data *data = &priv->bus_data;
 112 
 113         if (data->reset_gpio) {
 114                 gpiod_set_value_cansleep(data->reset_gpio, 1);
 115                 msleep(data->msec);
 116                 gpiod_set_value_cansleep(data->reset_gpio, 0);
 117         }
 118 
 119         return 0;
 120 }
 121 
 122 /**
 123  * arc_mdio_probe - MDIO probe function.
 124  * @priv:       Pointer to ARC EMAC private data structure.
 125  *
 126  * returns:     0 on success, -ENOMEM when mdiobus_alloc
 127  * (to allocate memory for MII bus structure) fails.
 128  *
 129  * Sets up and registers the MDIO interface.
 130  */
 131 int arc_mdio_probe(struct arc_emac_priv *priv)
 132 {
 133         struct arc_emac_mdio_bus_data *data = &priv->bus_data;
 134         struct device_node *np = priv->dev->of_node;
 135         struct mii_bus *bus;
 136         int error;
 137 
 138         bus = mdiobus_alloc();
 139         if (!bus)
 140                 return -ENOMEM;
 141 
 142         priv->bus = bus;
 143         bus->priv = priv;
 144         bus->parent = priv->dev;
 145         bus->name = "Synopsys MII Bus";
 146         bus->read = &arc_mdio_read;
 147         bus->write = &arc_mdio_write;
 148         bus->reset = &arc_mdio_reset;
 149 
 150         /* optional reset-related properties */
 151         data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset",
 152                                                    GPIOD_OUT_LOW);
 153         if (IS_ERR(data->reset_gpio)) {
 154                 error = PTR_ERR(data->reset_gpio);
 155                 dev_err(priv->dev, "Failed to request gpio: %d\n", error);
 156                 return error;
 157         }
 158 
 159         of_property_read_u32(np, "phy-reset-duration", &data->msec);
 160         /* A sane reset duration should not be longer than 1s */
 161         if (data->msec > 1000)
 162                 data->msec = 1;
 163 
 164         snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
 165 
 166         error = of_mdiobus_register(bus, priv->dev->of_node);
 167         if (error) {
 168                 dev_err(priv->dev, "cannot register MDIO bus %s\n", bus->name);
 169                 mdiobus_free(bus);
 170                 return error;
 171         }
 172 
 173         return 0;
 174 }
 175 
 176 /**
 177  * arc_mdio_remove - MDIO remove function.
 178  * @priv:       Pointer to ARC EMAC private data structure.
 179  *
 180  * Unregisters the MDIO and frees any associate memory for MII bus.
 181  */
 182 int arc_mdio_remove(struct arc_emac_priv *priv)
 183 {
 184         mdiobus_unregister(priv->bus);
 185         mdiobus_free(priv->bus);
 186         priv->bus = NULL;
 187 
 188         return 0;
 189 }

/* [<][>][^][v][top][bottom][index][help] */