2010-04-29 10:12:41 +04:00
/*
* drivers / net / phy / micrel . c
*
* Driver for Micrel PHYs
*
* Author : David J . Choi
*
2013-01-23 18:05:15 +04:00
* Copyright ( c ) 2010 - 2013 Micrel , Inc .
2010-04-29 10:12:41 +04: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 , or ( at your
* option ) any later version .
*
2013-01-23 18:05:15 +04:00
* Support : Micrel Phys :
* Giga phys : ksz9021 , ksz9031
* 100 / 10 Phys : ksz8001 , ksz8721 , ksz8737 , ksz8041
* ksz8021 , ksz8031 , ksz8051 ,
* ksz8081 , ksz8091 ,
* ksz8061 ,
* Switch : ksz8873 , ksz886x
2010-04-29 10:12:41 +04:00
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/phy.h>
2011-02-14 05:05:33 +03:00
# include <linux/micrel_phy.h>
2013-08-21 05:46:12 +04:00
# include <linux/of.h>
2010-04-29 10:12:41 +04:00
2012-09-23 20:58:49 +04:00
/* Operation Mode Strap Override */
# define MII_KSZPHY_OMSO 0x16
# define KSZPHY_OMSO_B_CAST_OFF (1 << 9)
# define KSZPHY_OMSO_RMII_OVERRIDE (1 << 1)
# define KSZPHY_OMSO_MII_OVERRIDE (1 << 0)
2010-06-28 19:23:41 +04:00
/* general Interrupt control/status reg in vendor specific block. */
# define MII_KSZPHY_INTCS 0x1B
# define KSZPHY_INTCS_JABBER (1 << 15)
# define KSZPHY_INTCS_RECEIVE_ERR (1 << 14)
# define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13)
# define KSZPHY_INTCS_PARELLEL (1 << 12)
# define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11)
# define KSZPHY_INTCS_LINK_DOWN (1 << 10)
# define KSZPHY_INTCS_REMOTE_FAULT (1 << 9)
# define KSZPHY_INTCS_LINK_UP (1 << 8)
# define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\
KSZPHY_INTCS_LINK_DOWN )
/* general PHY control reg in vendor specific block. */
# define MII_KSZPHY_CTRL 0x1F
/* bitmap of PHY register to set interrupt mode */
# define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9)
# define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14)
# define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14)
2011-02-14 05:05:33 +03:00
# define KSZ8051_RMII_50MHZ_CLK (1 << 7)
2010-06-28 19:23:41 +04:00
2013-08-21 05:46:12 +04:00
/* Write/read to/from extended registers */
# define MII_KSZPHY_EXTREG 0x0b
# define KSZPHY_EXTREG_WRITE 0x8000
# define MII_KSZPHY_EXTREG_WRITE 0x0c
# define MII_KSZPHY_EXTREG_READ 0x0d
/* Extended registers */
# define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104
# define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105
# define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106
# define PS_TO_REG 200
2013-03-11 02:50:03 +04:00
static int ksz_config_flags ( struct phy_device * phydev )
{
int regval ;
if ( phydev - > dev_flags & MICREL_PHY_50MHZ_CLK ) {
regval = phy_read ( phydev , MII_KSZPHY_CTRL ) ;
regval | = KSZ8051_RMII_50MHZ_CLK ;
return phy_write ( phydev , MII_KSZPHY_CTRL , regval ) ;
}
return 0 ;
}
2013-08-21 05:46:12 +04:00
static int kszphy_extended_write ( struct phy_device * phydev ,
2013-12-18 09:38:11 +04:00
u32 regnum , u16 val )
2013-08-21 05:46:12 +04:00
{
phy_write ( phydev , MII_KSZPHY_EXTREG , KSZPHY_EXTREG_WRITE | regnum ) ;
return phy_write ( phydev , MII_KSZPHY_EXTREG_WRITE , val ) ;
}
static int kszphy_extended_read ( struct phy_device * phydev ,
2013-12-18 09:38:11 +04:00
u32 regnum )
2013-08-21 05:46:12 +04:00
{
phy_write ( phydev , MII_KSZPHY_EXTREG , regnum ) ;
return phy_read ( phydev , MII_KSZPHY_EXTREG_READ ) ;
}
2010-06-28 19:23:41 +04:00
static int kszphy_ack_interrupt ( struct phy_device * phydev )
{
/* bit[7..0] int status, which is a read and clear register. */
int rc ;
rc = phy_read ( phydev , MII_KSZPHY_INTCS ) ;
return ( rc < 0 ) ? rc : 0 ;
}
static int kszphy_set_interrupt ( struct phy_device * phydev )
{
int temp ;
temp = ( PHY_INTERRUPT_ENABLED = = phydev - > interrupts ) ?
KSZPHY_INTCS_ALL : 0 ;
return phy_write ( phydev , MII_KSZPHY_INTCS , temp ) ;
}
static int kszphy_config_intr ( struct phy_device * phydev )
{
int temp , rc ;
/* set the interrupt pin active low */
temp = phy_read ( phydev , MII_KSZPHY_CTRL ) ;
temp & = ~ KSZPHY_CTRL_INT_ACTIVE_HIGH ;
phy_write ( phydev , MII_KSZPHY_CTRL , temp ) ;
rc = kszphy_set_interrupt ( phydev ) ;
return rc < 0 ? rc : 0 ;
}
static int ksz9021_config_intr ( struct phy_device * phydev )
{
int temp , rc ;
/* set the interrupt pin active low */
temp = phy_read ( phydev , MII_KSZPHY_CTRL ) ;
temp & = ~ KSZ9021_CTRL_INT_ACTIVE_HIGH ;
phy_write ( phydev , MII_KSZPHY_CTRL , temp ) ;
rc = kszphy_set_interrupt ( phydev ) ;
return rc < 0 ? rc : 0 ;
}
static int ks8737_config_intr ( struct phy_device * phydev )
{
int temp , rc ;
/* set the interrupt pin active low */
temp = phy_read ( phydev , MII_KSZPHY_CTRL ) ;
temp & = ~ KS8737_CTRL_INT_ACTIVE_HIGH ;
phy_write ( phydev , MII_KSZPHY_CTRL , temp ) ;
rc = kszphy_set_interrupt ( phydev ) ;
return rc < 0 ? rc : 0 ;
}
2010-04-29 10:12:41 +04:00
static int kszphy_config_init ( struct phy_device * phydev )
{
return 0 ;
}
2012-09-23 20:58:49 +04:00
static int ksz8021_config_init ( struct phy_device * phydev )
{
2013-03-11 02:50:03 +04:00
int rc ;
2012-09-23 20:58:49 +04:00
const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE ;
phy_write ( phydev , MII_KSZPHY_OMSO , val ) ;
2013-03-11 02:50:03 +04:00
rc = ksz_config_flags ( phydev ) ;
return rc < 0 ? rc : 0 ;
2012-09-23 20:58:49 +04:00
}
2011-02-14 05:05:33 +03:00
static int ks8051_config_init ( struct phy_device * phydev )
{
2013-03-11 02:50:03 +04:00
int rc ;
2011-02-14 05:05:33 +03:00
2013-03-11 02:50:03 +04:00
rc = ksz_config_flags ( phydev ) ;
return rc < 0 ? rc : 0 ;
2011-02-14 05:05:33 +03:00
}
2013-08-21 05:46:12 +04:00
static int ksz9021_load_values_from_of ( struct phy_device * phydev ,
struct device_node * of_node , u16 reg ,
char * field1 , char * field2 ,
char * field3 , char * field4 )
{
int val1 = - 1 ;
int val2 = - 2 ;
int val3 = - 3 ;
int val4 = - 4 ;
int newval ;
int matches = 0 ;
if ( ! of_property_read_u32 ( of_node , field1 , & val1 ) )
matches + + ;
if ( ! of_property_read_u32 ( of_node , field2 , & val2 ) )
matches + + ;
if ( ! of_property_read_u32 ( of_node , field3 , & val3 ) )
matches + + ;
if ( ! of_property_read_u32 ( of_node , field4 , & val4 ) )
matches + + ;
if ( ! matches )
return 0 ;
if ( matches < 4 )
newval = kszphy_extended_read ( phydev , reg ) ;
else
newval = 0 ;
if ( val1 ! = - 1 )
newval = ( ( newval & 0xfff0 ) | ( ( val1 / PS_TO_REG ) & 0xf ) < < 0 ) ;
if ( val2 ! = - 1 )
newval = ( ( newval & 0xff0f ) | ( ( val2 / PS_TO_REG ) & 0xf ) < < 4 ) ;
if ( val3 ! = - 1 )
newval = ( ( newval & 0xf0ff ) | ( ( val3 / PS_TO_REG ) & 0xf ) < < 8 ) ;
if ( val4 ! = - 1 )
newval = ( ( newval & 0x0fff ) | ( ( val4 / PS_TO_REG ) & 0xf ) < < 12 ) ;
return kszphy_extended_write ( phydev , reg , newval ) ;
}
static int ksz9021_config_init ( struct phy_device * phydev )
{
struct device * dev = & phydev - > dev ;
struct device_node * of_node = dev - > of_node ;
if ( ! of_node & & dev - > parent - > of_node )
of_node = dev - > parent - > of_node ;
if ( of_node ) {
ksz9021_load_values_from_of ( phydev , of_node ,
MII_KSZPHY_CLK_CONTROL_PAD_SKEW ,
" txen-skew-ps " , " txc-skew-ps " ,
" rxdv-skew-ps " , " rxc-skew-ps " ) ;
ksz9021_load_values_from_of ( phydev , of_node ,
MII_KSZPHY_RX_DATA_PAD_SKEW ,
" rxd0-skew-ps " , " rxd1-skew-ps " ,
" rxd2-skew-ps " , " rxd3-skew-ps " ) ;
ksz9021_load_values_from_of ( phydev , of_node ,
MII_KSZPHY_TX_DATA_PAD_SKEW ,
" txd0-skew-ps " , " txd1-skew-ps " ,
" txd2-skew-ps " , " txd3-skew-ps " ) ;
}
return 0 ;
}
2012-11-21 09:38:07 +04:00
# define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
# define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6)
# define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4)
2013-08-06 12:29:35 +04:00
static int ksz8873mll_read_status ( struct phy_device * phydev )
2012-11-21 09:38:07 +04:00
{
int regval ;
/* dummy read */
regval = phy_read ( phydev , KSZ8873MLL_GLOBAL_CONTROL_4 ) ;
regval = phy_read ( phydev , KSZ8873MLL_GLOBAL_CONTROL_4 ) ;
if ( regval & KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX )
phydev - > duplex = DUPLEX_HALF ;
else
phydev - > duplex = DUPLEX_FULL ;
if ( regval & KSZ8873MLL_GLOBAL_CONTROL_4_SPEED )
phydev - > speed = SPEED_10 ;
else
phydev - > speed = SPEED_100 ;
phydev - > link = 1 ;
phydev - > pause = phydev - > asym_pause = 0 ;
return 0 ;
}
static int ksz8873mll_config_aneg ( struct phy_device * phydev )
{
return 0 ;
}
2012-07-04 09:44:34 +04:00
static struct phy_driver ksphy_driver [ ] = {
{
2010-06-28 19:23:41 +04:00
. phy_id = PHY_ID_KS8737 ,
. phy_id_mask = 0x00fffff0 ,
. name = " Micrel KS8737 " ,
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = ks8737_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2010-06-28 19:23:41 +04:00
. driver = { . owner = THIS_MODULE , } ,
2012-09-23 20:58:49 +04:00
} , {
. phy_id = PHY_ID_KSZ8021 ,
. phy_id_mask = 0x00ffffff ,
2013-01-23 18:05:15 +04:00
. name = " Micrel KSZ8021 or KSZ8031 " ,
2012-09-23 20:58:49 +04:00
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = ksz8021_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2012-09-23 20:58:49 +04:00
. driver = { . owner = THIS_MODULE , } ,
2013-03-11 02:50:02 +04:00
} , {
. phy_id = PHY_ID_KSZ8031 ,
. phy_id_mask = 0x00ffffff ,
. name = " Micrel KSZ8031 " ,
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = ksz8021_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2013-03-11 02:50:02 +04:00
. driver = { . owner = THIS_MODULE , } ,
2012-07-04 09:44:34 +04:00
} , {
2012-09-23 20:58:50 +04:00
. phy_id = PHY_ID_KSZ8041 ,
2010-06-28 19:23:41 +04:00
. phy_id_mask = 0x00fffff0 ,
2012-09-23 20:58:50 +04:00
. name = " Micrel KSZ8041 " ,
2010-06-28 19:23:41 +04:00
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause
| SUPPORTED_Asym_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2010-06-28 19:23:41 +04:00
. driver = { . owner = THIS_MODULE , } ,
2013-12-10 03:20:41 +04:00
} , {
. phy_id = PHY_ID_KSZ8041RNLI ,
. phy_id_mask = 0x00fffff0 ,
. name = " Micrel KSZ8041RNLI " ,
. features = PHY_BASIC_FEATURES |
SUPPORTED_Pause | SUPPORTED_Asym_Pause ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
. suspend = genphy_suspend ,
. resume = genphy_resume ,
. driver = { . owner = THIS_MODULE , } ,
2012-07-04 09:44:34 +04:00
} , {
2012-09-23 20:58:50 +04:00
. phy_id = PHY_ID_KSZ8051 ,
2010-04-29 10:12:41 +04:00
. phy_id_mask = 0x00fffff0 ,
2012-09-23 20:58:50 +04:00
. name = " Micrel KSZ8051 " ,
2010-06-28 19:23:41 +04:00
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause
| SUPPORTED_Asym_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
2011-02-14 05:05:33 +03:00
. config_init = ks8051_config_init ,
2010-04-29 10:12:41 +04:00
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
2010-06-28 19:23:41 +04:00
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2010-04-29 10:12:41 +04:00
. driver = { . owner = THIS_MODULE , } ,
2012-07-04 09:44:34 +04:00
} , {
2012-09-23 20:58:50 +04:00
. phy_id = PHY_ID_KSZ8001 ,
. name = " Micrel KSZ8001 or KS8721 " ,
2012-06-18 02:52:09 +04:00
. phy_id_mask = 0x00ffffff ,
2010-06-28 19:23:41 +04:00
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
2010-04-29 10:12:41 +04:00
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
2010-06-28 19:23:41 +04:00
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2010-04-29 10:12:41 +04:00
. driver = { . owner = THIS_MODULE , } ,
2013-01-23 18:05:15 +04:00
} , {
. phy_id = PHY_ID_KSZ8081 ,
. name = " Micrel KSZ8081 or KSZ8091 " ,
. phy_id_mask = 0x00fffff0 ,
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2013-01-23 18:05:15 +04:00
. driver = { . owner = THIS_MODULE , } ,
} , {
. phy_id = PHY_ID_KSZ8061 ,
. name = " Micrel KSZ8061 " ,
. phy_id_mask = 0x00fffff0 ,
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = kszphy_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2013-01-23 18:05:15 +04:00
. driver = { . owner = THIS_MODULE , } ,
2012-07-04 09:44:34 +04:00
} , {
2010-04-29 10:12:41 +04:00
. phy_id = PHY_ID_KSZ9021 ,
2012-06-18 02:52:09 +04:00
. phy_id_mask = 0x000ffffe ,
2010-04-29 10:12:41 +04:00
. name = " Micrel KSZ9021 Gigabit PHY " ,
2013-02-28 12:45:22 +04:00
. features = ( PHY_GBIT_FEATURES | SUPPORTED_Pause ) ,
2010-06-28 19:23:41 +04:00
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
2013-08-21 05:46:12 +04:00
. config_init = ksz9021_config_init ,
2010-04-29 10:12:41 +04:00
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
2010-06-28 19:23:41 +04:00
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = ksz9021_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2010-04-29 10:12:41 +04:00
. driver = { . owner = THIS_MODULE , } ,
2013-01-23 18:05:15 +04:00
} , {
. phy_id = PHY_ID_KSZ9031 ,
. phy_id_mask = 0x00fffff0 ,
. name = " Micrel KSZ9031 Gigabit PHY " ,
. features = ( PHY_GBIT_FEATURES | SUPPORTED_Pause
| SUPPORTED_Asym_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
. ack_interrupt = kszphy_ack_interrupt ,
. config_intr = ksz9021_config_intr ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2013-01-23 18:05:15 +04:00
. driver = { . owner = THIS_MODULE , } ,
2012-11-21 09:38:07 +04:00
} , {
. phy_id = PHY_ID_KSZ8873MLL ,
. phy_id_mask = 0x00fffff0 ,
. name = " Micrel KSZ8873MLL Switch " ,
. features = ( SUPPORTED_Pause | SUPPORTED_Asym_Pause ) ,
. flags = PHY_HAS_MAGICANEG ,
. config_init = kszphy_config_init ,
. config_aneg = ksz8873mll_config_aneg ,
. read_status = ksz8873mll_read_status ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2012-11-21 09:38:07 +04:00
. driver = { . owner = THIS_MODULE , } ,
2013-01-23 18:05:15 +04:00
} , {
. phy_id = PHY_ID_KSZ886X ,
. phy_id_mask = 0x00fffff0 ,
. name = " Micrel KSZ886X Switch " ,
. features = ( PHY_BASIC_FEATURES | SUPPORTED_Pause ) ,
. flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT ,
. config_init = kszphy_config_init ,
. config_aneg = genphy_config_aneg ,
. read_status = genphy_read_status ,
2013-09-19 21:40:48 +04:00
. suspend = genphy_suspend ,
. resume = genphy_resume ,
2013-01-23 18:05:15 +04:00
. driver = { . owner = THIS_MODULE , } ,
2012-07-04 09:44:34 +04:00
} } ;
2010-04-29 10:12:41 +04:00
static int __init ksphy_init ( void )
{
2012-07-04 09:44:34 +04:00
return phy_drivers_register ( ksphy_driver ,
ARRAY_SIZE ( ksphy_driver ) ) ;
2010-04-29 10:12:41 +04:00
}
static void __exit ksphy_exit ( void )
{
2012-07-04 09:44:34 +04:00
phy_drivers_unregister ( ksphy_driver ,
ARRAY_SIZE ( ksphy_driver ) ) ;
2010-04-29 10:12:41 +04:00
}
module_init ( ksphy_init ) ;
module_exit ( ksphy_exit ) ;
MODULE_DESCRIPTION ( " Micrel PHY driver " ) ;
MODULE_AUTHOR ( " David J. Choi " ) ;
MODULE_LICENSE ( " GPL " ) ;
2010-05-04 02:48:29 +04:00
2010-10-04 03:43:32 +04:00
static struct mdio_device_id __maybe_unused micrel_tbl [ ] = {
2012-06-18 02:52:09 +04:00
{ PHY_ID_KSZ9021 , 0x000ffffe } ,
2013-01-23 18:05:15 +04:00
{ PHY_ID_KSZ9031 , 0x00fffff0 } ,
2012-09-23 20:58:50 +04:00
{ PHY_ID_KSZ8001 , 0x00ffffff } ,
2010-06-28 19:23:41 +04:00
{ PHY_ID_KS8737 , 0x00fffff0 } ,
2012-09-23 20:58:49 +04:00
{ PHY_ID_KSZ8021 , 0x00ffffff } ,
2013-03-11 02:50:02 +04:00
{ PHY_ID_KSZ8031 , 0x00ffffff } ,
2012-09-23 20:58:50 +04:00
{ PHY_ID_KSZ8041 , 0x00fffff0 } ,
{ PHY_ID_KSZ8051 , 0x00fffff0 } ,
2013-01-23 18:05:15 +04:00
{ PHY_ID_KSZ8061 , 0x00fffff0 } ,
{ PHY_ID_KSZ8081 , 0x00fffff0 } ,
2012-11-21 09:38:07 +04:00
{ PHY_ID_KSZ8873MLL , 0x00fffff0 } ,
2013-01-23 18:05:15 +04:00
{ PHY_ID_KSZ886X , 0x00fffff0 } ,
2010-05-04 02:48:29 +04:00
{ }
} ;
MODULE_DEVICE_TABLE ( mdio , micrel_tbl ) ;