1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Davicom PHY drivers 4 * 5 * Copyright 2010-2011 Freescale Semiconductor, Inc. 6 * author Andy Fleming 7 */ 8 #include <phy.h> 9 10 #define MIIM_DM9161_SCR 0x10 11 #define MIIM_DM9161_SCR_INIT 0x0610 12 13 /* DM9161 Specified Configuration and Status Register */ 14 #define MIIM_DM9161_SCSR 0x11 15 #define MIIM_DM9161_SCSR_100F 0x8000 16 #define MIIM_DM9161_SCSR_100H 0x4000 17 #define MIIM_DM9161_SCSR_10F 0x2000 18 #define MIIM_DM9161_SCSR_10H 0x1000 19 20 /* DM9161 10BT Configuration/Status */ 21 #define MIIM_DM9161_10BTCSR 0x12 22 #define MIIM_DM9161_10BTCSR_INIT 0x7800 23 24 25 /* Davicom DM9161E */ 26 static int dm9161_config(struct phy_device *phydev) 27 { 28 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_ISOLATE); 29 /* Do not bypass the scrambler/descrambler */ 30 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCR, 31 MIIM_DM9161_SCR_INIT); 32 /* Clear 10BTCSR to default */ 33 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_10BTCSR, 34 MIIM_DM9161_10BTCSR_INIT); 35 36 genphy_config_aneg(phydev); 37 38 return 0; 39 } 40 41 static int dm9161_parse_status(struct phy_device *phydev) 42 { 43 int mii_reg; 44 45 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCSR); 46 47 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H)) 48 phydev->speed = SPEED_100; 49 else 50 phydev->speed = SPEED_10; 51 52 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F)) 53 phydev->duplex = DUPLEX_FULL; 54 else 55 phydev->duplex = DUPLEX_HALF; 56 57 return 0; 58 } 59 60 static int dm9161_startup(struct phy_device *phydev) 61 { 62 int ret; 63 64 ret = genphy_update_link(phydev); 65 if (ret) 66 return ret; 67 68 return dm9161_parse_status(phydev); 69 } 70 71 static struct phy_driver DM9161_driver = { 72 .name = "Davicom DM9161E", 73 .uid = 0x181b880, 74 .mask = 0xffffff0, 75 .features = PHY_BASIC_FEATURES, 76 .config = &dm9161_config, 77 .startup = &dm9161_startup, 78 .shutdown = &genphy_shutdown, 79 }; 80 81 int phy_davicom_init(void) 82 { 83 phy_register(&DM9161_driver); 84 85 return 0; 86 } 87