19082eeacSAndy Fleming /*
29082eeacSAndy Fleming * Davicom PHY drivers
39082eeacSAndy Fleming *
41a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
59082eeacSAndy Fleming *
69082eeacSAndy Fleming * Copyright 2010-2011 Freescale Semiconductor, Inc.
79082eeacSAndy Fleming * author Andy Fleming
89082eeacSAndy Fleming */
99082eeacSAndy Fleming #include <phy.h>
109082eeacSAndy Fleming
119082eeacSAndy Fleming #define MIIM_DM9161_SCR 0x10
129082eeacSAndy Fleming #define MIIM_DM9161_SCR_INIT 0x0610
139082eeacSAndy Fleming
149082eeacSAndy Fleming /* DM9161 Specified Configuration and Status Register */
159082eeacSAndy Fleming #define MIIM_DM9161_SCSR 0x11
169082eeacSAndy Fleming #define MIIM_DM9161_SCSR_100F 0x8000
179082eeacSAndy Fleming #define MIIM_DM9161_SCSR_100H 0x4000
189082eeacSAndy Fleming #define MIIM_DM9161_SCSR_10F 0x2000
199082eeacSAndy Fleming #define MIIM_DM9161_SCSR_10H 0x1000
209082eeacSAndy Fleming
219082eeacSAndy Fleming /* DM9161 10BT Configuration/Status */
229082eeacSAndy Fleming #define MIIM_DM9161_10BTCSR 0x12
239082eeacSAndy Fleming #define MIIM_DM9161_10BTCSR_INIT 0x7800
249082eeacSAndy Fleming
259082eeacSAndy Fleming
269082eeacSAndy Fleming /* Davicom DM9161E */
dm9161_config(struct phy_device * phydev)279082eeacSAndy Fleming static int dm9161_config(struct phy_device *phydev)
289082eeacSAndy Fleming {
299082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_ISOLATE);
309082eeacSAndy Fleming /* Do not bypass the scrambler/descrambler */
319082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCR,
329082eeacSAndy Fleming MIIM_DM9161_SCR_INIT);
339082eeacSAndy Fleming /* Clear 10BTCSR to default */
349082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_10BTCSR,
359082eeacSAndy Fleming MIIM_DM9161_10BTCSR_INIT);
369082eeacSAndy Fleming
379082eeacSAndy Fleming genphy_config_aneg(phydev);
389082eeacSAndy Fleming
399082eeacSAndy Fleming return 0;
409082eeacSAndy Fleming }
419082eeacSAndy Fleming
dm9161_parse_status(struct phy_device * phydev)429082eeacSAndy Fleming static int dm9161_parse_status(struct phy_device *phydev)
439082eeacSAndy Fleming {
449082eeacSAndy Fleming int mii_reg;
459082eeacSAndy Fleming
469082eeacSAndy Fleming mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCSR);
479082eeacSAndy Fleming
489082eeacSAndy Fleming if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
499082eeacSAndy Fleming phydev->speed = SPEED_100;
509082eeacSAndy Fleming else
519082eeacSAndy Fleming phydev->speed = SPEED_10;
529082eeacSAndy Fleming
539082eeacSAndy Fleming if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
549082eeacSAndy Fleming phydev->duplex = DUPLEX_FULL;
559082eeacSAndy Fleming else
569082eeacSAndy Fleming phydev->duplex = DUPLEX_HALF;
579082eeacSAndy Fleming
589082eeacSAndy Fleming return 0;
599082eeacSAndy Fleming }
609082eeacSAndy Fleming
dm9161_startup(struct phy_device * phydev)619082eeacSAndy Fleming static int dm9161_startup(struct phy_device *phydev)
629082eeacSAndy Fleming {
63*b733c278SMichal Simek int ret;
649082eeacSAndy Fleming
65*b733c278SMichal Simek ret = genphy_update_link(phydev);
66*b733c278SMichal Simek if (ret)
67*b733c278SMichal Simek return ret;
68*b733c278SMichal Simek
69*b733c278SMichal Simek return dm9161_parse_status(phydev);
709082eeacSAndy Fleming }
719082eeacSAndy Fleming
729082eeacSAndy Fleming static struct phy_driver DM9161_driver = {
739082eeacSAndy Fleming .name = "Davicom DM9161E",
749082eeacSAndy Fleming .uid = 0x181b880,
759082eeacSAndy Fleming .mask = 0xffffff0,
769082eeacSAndy Fleming .features = PHY_BASIC_FEATURES,
779082eeacSAndy Fleming .config = &dm9161_config,
789082eeacSAndy Fleming .startup = &dm9161_startup,
799082eeacSAndy Fleming .shutdown = &genphy_shutdown,
809082eeacSAndy Fleming };
819082eeacSAndy Fleming
phy_davicom_init(void)829082eeacSAndy Fleming int phy_davicom_init(void)
839082eeacSAndy Fleming {
849082eeacSAndy Fleming phy_register(&DM9161_driver);
859082eeacSAndy Fleming
869082eeacSAndy Fleming return 0;
879082eeacSAndy Fleming }
88