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