2015-10-21 00:28:57 +03:00
/*
* Driver for the Texas Instruments DP83848 PHY
*
2016-02-07 20:47:17 +03:00
* Copyright ( C ) 2015 - 2016 Texas Instruments Incorporated - http : //www.ti.com/
2015-10-21 00:28:57 +03:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# include <linux/module.h>
# include <linux/phy.h>
2016-02-07 20:47:18 +03:00
# define TI_DP83848C_PHY_ID 0x20005ca0
2017-01-17 11:08:16 +03:00
# define TI_DP83620_PHY_ID 0x20005ce0
2016-02-07 20:47:18 +03:00
# define NS_DP83848C_PHY_ID 0x20005c90
2016-02-07 20:47:20 +03:00
# define TLK10X_PHY_ID 0x2000a210
2015-10-21 00:28:57 +03:00
/* Registers */
2016-02-07 20:47:21 +03:00
# define DP83848_MICR 0x11 /* MII Interrupt Control Register */
# define DP83848_MISR 0x12 /* MII Interrupt Status Register */
2015-10-21 00:28:57 +03:00
/* MICR Register Fields */
# define DP83848_MICR_INT_OE BIT(0) /* Interrupt Output Enable */
# define DP83848_MICR_INTEN BIT(1) /* Interrupt Enable */
/* MISR Register Fields */
# define DP83848_MISR_RHF_INT_EN BIT(0) /* Receive Error Counter */
# define DP83848_MISR_FHF_INT_EN BIT(1) /* False Carrier Counter */
# define DP83848_MISR_ANC_INT_EN BIT(2) /* Auto-negotiation complete */
# define DP83848_MISR_DUP_INT_EN BIT(3) /* Duplex Status */
# define DP83848_MISR_SPD_INT_EN BIT(4) /* Speed status */
# define DP83848_MISR_LINK_INT_EN BIT(5) /* Link status */
# define DP83848_MISR_ED_INT_EN BIT(6) /* Energy detect */
# define DP83848_MISR_LQM_INT_EN BIT(7) /* Link Quality Monitor */
2016-02-07 20:47:19 +03:00
# define DP83848_INT_EN_MASK \
( DP83848_MISR_ANC_INT_EN | \
DP83848_MISR_DUP_INT_EN | \
DP83848_MISR_SPD_INT_EN | \
DP83848_MISR_LINK_INT_EN )
2015-10-21 00:28:57 +03:00
static int dp83848_ack_interrupt ( struct phy_device * phydev )
{
int err = phy_read ( phydev , DP83848_MISR ) ;
return err < 0 ? err : 0 ;
}
static int dp83848_config_intr ( struct phy_device * phydev )
{
2016-02-07 20:47:19 +03:00
int control , ret ;
control = phy_read ( phydev , DP83848_MICR ) ;
if ( control < 0 )
return control ;
2015-10-21 00:28:57 +03:00
if ( phydev - > interrupts = = PHY_INTERRUPT_ENABLED ) {
2016-02-07 20:47:19 +03:00
control | = DP83848_MICR_INT_OE ;
control | = DP83848_MICR_INTEN ;
2015-10-21 00:28:57 +03:00
2016-02-07 20:47:19 +03:00
ret = phy_write ( phydev , DP83848_MISR , DP83848_INT_EN_MASK ) ;
if ( ret < 0 )
return ret ;
} else {
control & = ~ DP83848_MICR_INTEN ;
2015-10-21 00:28:57 +03:00
}
2016-02-07 20:47:19 +03:00
return phy_write ( phydev , DP83848_MICR , control ) ;
2015-10-21 00:28:57 +03:00
}
static struct mdio_device_id __maybe_unused dp83848_tbl [ ] = {
2016-02-07 20:47:18 +03:00
{ TI_DP83848C_PHY_ID , 0xfffffff0 } ,
{ NS_DP83848C_PHY_ID , 0xfffffff0 } ,
2017-01-17 11:08:16 +03:00
{ TI_DP83620_PHY_ID , 0xfffffff0 } ,
2016-02-07 20:47:20 +03:00
{ TLK10X_PHY_ID , 0xfffffff0 } ,
2015-10-21 00:28:57 +03:00
{ }
} ;
MODULE_DEVICE_TABLE ( mdio , dp83848_tbl ) ;
2016-02-07 20:47:17 +03:00
# define DP83848_PHY_DRIVER(_id, _name) \
{ \
. phy_id = _id , \
. phy_id_mask = 0xfffffff0 , \
. name = _name , \
. features = PHY_BASIC_FEATURES , \
. flags = PHY_HAS_INTERRUPT , \
\
. soft_reset = genphy_soft_reset , \
. config_init = genphy_config_init , \
. suspend = genphy_suspend , \
. resume = genphy_resume , \
\
/* IRQ related */ \
. ack_interrupt = dp83848_ack_interrupt , \
. config_intr = dp83848_config_intr , \
}
2015-10-21 00:28:57 +03:00
2016-02-07 20:47:17 +03:00
static struct phy_driver dp83848_driver [ ] = {
2016-02-07 20:47:18 +03:00
DP83848_PHY_DRIVER ( TI_DP83848C_PHY_ID , " TI DP83848C 10/100 Mbps PHY " ) ,
2016-02-18 03:10:00 +03:00
DP83848_PHY_DRIVER ( NS_DP83848C_PHY_ID , " NS DP83848C 10/100 Mbps PHY " ) ,
2017-01-17 11:08:16 +03:00
DP83848_PHY_DRIVER ( TI_DP83620_PHY_ID , " TI DP83620 10/100 Mbps PHY " ) ,
2016-02-07 20:47:20 +03:00
DP83848_PHY_DRIVER ( TLK10X_PHY_ID , " TI TLK10X 10/100 Mbps PHY " ) ,
2015-10-21 00:28:57 +03:00
} ;
module_phy_driver ( dp83848_driver ) ;
MODULE_DESCRIPTION ( " Texas Instruments DP83848 PHY driver " ) ;
2017-01-05 23:44:50 +03:00
MODULE_AUTHOR ( " Andrew F. Davis <afd@ti.com> " ) ;
2015-10-21 00:28:57 +03:00
MODULE_LICENSE ( " GPL " ) ;