ste10Xp.c revision f95be1806fde884c1655237d49a7e5f82e4a935f
1f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro/* 2f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * drivers/net/phy/ste10Xp.c 3f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * 4f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * Driver for STMicroelectronics STe10Xp PHYs 5f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * 6f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 7f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * 8f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * Copyright (c) 2008 STMicroelectronics Limited 9f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * 10f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * This program is free software; you can redistribute it and/or modify it 11f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * under the terms of the GNU General Public License as published by the 12f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * Free Software Foundation; either version 2 of the License, or (at your 13f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * option) any later version. 14f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro * 15f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro */ 16f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 17f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/module.h> 18f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/init.h> 19f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/sched.h> 20f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/kernel.h> 21f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/moduleparam.h> 22f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/interrupt.h> 23f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/netdevice.h> 24f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/ethtool.h> 25f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/mii.h> 26f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#include <linux/phy.h> 27f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 28f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#define MII_XCIIS 0x11 /* Configuration Info IRQ & Status Reg */ 29f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#define MII_XIE 0x12 /* Interrupt Enable Register */ 30f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#define MII_XIE_DEFAULT_MASK 0x0070 /* ANE complete, Remote Fault, Link Down */ 31f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 32f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#define STE101P_PHY_ID 0x00061c50 33f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro#define STE100P_PHY_ID 0x1c040011 34f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 35f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallarostatic int ste10Xp_config_init(struct phy_device *phydev) 36f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro{ 37f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro int value, err; 38f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 39f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro /* Software Reset PHY */ 40f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro value = phy_read(phydev, MII_BMCR); 41f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro if (value < 0) 42f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return value; 43f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 44f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro value |= BMCR_RESET; 45f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro err = phy_write(phydev, MII_BMCR, value); 46f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro if (err < 0) 47f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return err; 48f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 49f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro do { 50f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro value = phy_read(phydev, MII_BMCR); 51f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro } while (value & BMCR_RESET); 52f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 53f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return 0; 54f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro} 55f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 56f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallarostatic int ste10Xp_config_intr(struct phy_device *phydev) 57f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro{ 58f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro int err, value; 59f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 60f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 61f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro /* Enable all STe101P interrupts (PR12) */ 62f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro err = phy_write(phydev, MII_XIE, MII_XIE_DEFAULT_MASK); 63f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro /* clear any pending interrupts */ 64f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro if (err == 0) { 65f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro value = phy_read(phydev, MII_XCIIS); 66f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro if (value < 0) 67f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro err = value; 68f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro } 69f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro } else 70f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro err = phy_write(phydev, MII_XIE, 0); 71f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 72f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return err; 73f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro} 74f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 75f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallarostatic int ste10Xp_ack_interrupt(struct phy_device *phydev) 76f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro{ 77f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro int err = phy_read(phydev, MII_XCIIS); 78f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro if (err < 0) 79f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return err; 80f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 81f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return 0; 82f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro} 83f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 84f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallarostatic struct phy_driver ste101p_pdriver = { 85f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .phy_id = STE101P_PHY_ID, 86f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .phy_id_mask = 0xfffffff0, 87f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .name = "STe101p", 88f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .features = PHY_BASIC_FEATURES | SUPPORTED_Pause, 89f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .flags = PHY_HAS_INTERRUPT, 90f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .config_init = ste10Xp_config_init, 91f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .config_aneg = genphy_config_aneg, 92f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .read_status = genphy_read_status, 93f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .ack_interrupt = ste10Xp_ack_interrupt, 94f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .config_intr = ste10Xp_config_intr, 95f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .suspend = genphy_suspend, 96f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .resume = genphy_resume, 97f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .driver = {.owner = THIS_MODULE,} 98f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro}; 99f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 100f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallarostatic struct phy_driver ste100p_pdriver = { 101f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .phy_id = STE100P_PHY_ID, 102f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .phy_id_mask = 0xffffffff, 103f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .name = "STe100p", 104f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .features = PHY_BASIC_FEATURES | SUPPORTED_Pause, 105f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .flags = PHY_HAS_INTERRUPT, 106f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .config_init = ste10Xp_config_init, 107f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .config_aneg = genphy_config_aneg, 108f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .read_status = genphy_read_status, 109f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .ack_interrupt = ste10Xp_ack_interrupt, 110f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .config_intr = ste10Xp_config_intr, 111f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .suspend = genphy_suspend, 112f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .resume = genphy_resume, 113f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro .driver = {.owner = THIS_MODULE,} 114f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro}; 115f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 116f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallarostatic int __init ste10Xp_init(void) 117f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro{ 118f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro int retval; 119f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 120f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro retval = phy_driver_register(&ste100p_pdriver); 121f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro if (retval < 0) 122f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return retval; 123f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro return phy_driver_register(&ste101p_pdriver); 124f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro} 125f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 126f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallarostatic void __exit ste10Xp_exit(void) 127f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro{ 128f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro phy_driver_unregister(&ste100p_pdriver); 129f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro phy_driver_unregister(&ste101p_pdriver); 130f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro} 131f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 132f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaromodule_init(ste10Xp_init); 133f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaromodule_exit(ste10Xp_exit); 134f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe Cavallaro 135f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe CavallaroMODULE_DESCRIPTION("STMicroelectronics STe10Xp PHY driver"); 136f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe CavallaroMODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 137f95be1806fde884c1655237d49a7e5f82e4a935fGiuseppe CavallaroMODULE_LICENSE("GPL"); 138