uboot/drivers/net/phy/et1011c.c
<<
>>
Prefs
   1/*
   2 * ET1011C PHY driver
   3 *
   4 * Derived from Linux kernel driver by Chaithrika U S
   5 * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9#include <config.h>
  10#include <phy.h>
  11
  12#define ET1011C_CONFIG_REG              (0x16)
  13#define ET1011C_TX_FIFO_MASK            (0x3 << 12)
  14#define ET1011C_TX_FIFO_DEPTH_8         (0x0 << 12)
  15#define ET1011C_TX_FIFO_DEPTH_16        (0x1 << 12)
  16#define ET1011C_INTERFACE_MASK          (0x7 << 0)
  17#define ET1011C_GMII_INTERFACE          (0x2 << 0)
  18#define ET1011C_SYS_CLK_EN              (0x1 << 4)
  19#define ET1011C_TX_CLK_EN               (0x1 << 5)
  20
  21#define ET1011C_STATUS_REG              (0x1A)
  22#define ET1011C_DUPLEX_STATUS           (0x1 << 7)
  23#define ET1011C_SPEED_MASK              (0x3 << 8)
  24#define ET1011C_SPEED_1000              (0x2 << 8)
  25#define ET1011C_SPEED_100               (0x1 << 8)
  26#define ET1011C_SPEED_10                (0x0 << 8)
  27
  28static int et1011c_config(struct phy_device *phydev)
  29{
  30        int ctl = 0;
  31        ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  32        if (ctl < 0)
  33                return ctl;
  34        ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 |
  35                 BMCR_ANENABLE);
  36        /* First clear the PHY */
  37        phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl | BMCR_RESET);
  38
  39        return genphy_config_aneg(phydev);
  40}
  41
  42static int et1011c_parse_status(struct phy_device *phydev)
  43{
  44        int mii_reg;
  45        int speed;
  46
  47        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_STATUS_REG);
  48
  49        if (mii_reg & ET1011C_DUPLEX_STATUS)
  50                phydev->duplex = DUPLEX_FULL;
  51        else
  52                phydev->duplex = DUPLEX_HALF;
  53
  54        speed = mii_reg & ET1011C_SPEED_MASK;
  55        switch (speed) {
  56        case ET1011C_SPEED_1000:
  57                phydev->speed = SPEED_1000;
  58                mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG);
  59                mii_reg &= ~ET1011C_TX_FIFO_MASK;
  60                phy_write(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG,
  61                          mii_reg |
  62                          ET1011C_GMII_INTERFACE |
  63                          ET1011C_SYS_CLK_EN |
  64#ifdef CONFIG_PHY_ET1011C_TX_CLK_FIX
  65                          ET1011C_TX_CLK_EN |
  66#endif
  67                          ET1011C_TX_FIFO_DEPTH_16);
  68                break;
  69        case ET1011C_SPEED_100:
  70                phydev->speed = SPEED_100;
  71                break;
  72        case ET1011C_SPEED_10:
  73                phydev->speed = SPEED_10;
  74                break;
  75        }
  76
  77        return 0;
  78}
  79
  80static int et1011c_startup(struct phy_device *phydev)
  81{
  82        int ret;
  83
  84        ret = genphy_update_link(phydev);
  85        if (ret)
  86                return ret;
  87
  88        return et1011c_parse_status(phydev);
  89}
  90
  91static struct phy_driver et1011c_driver = {
  92        .name           = "ET1011C",
  93        .uid            = 0x0282f014,
  94        .mask           = 0xfffffff0,
  95        .features       = PHY_GBIT_FEATURES,
  96        .config         = &et1011c_config,
  97        .startup        = &et1011c_startup,
  98};
  99
 100int phy_et1011c_init(void)
 101{
 102        phy_register(&et1011c_driver);
 103
 104        return 0;
 105}
 106