micrel.c (86dc1342bcbb1905b2ac9653a559b303f62bd728) | micrel.c (c6f9575cc86250422c84972219e2a1bd7ec7e2ae) |
---|---|
1/* 2 * drivers/net/phy/micrel.c 3 * 4 * Driver for Micrel PHYs 5 * 6 * Author: David J. Choi 7 * 8 * Copyright (c) 2010-2013 Micrel, Inc. --- 41 unchanged lines hidden (view full) --- 50/* PHY Control 1 */ 51#define MII_KSZPHY_CTRL_1 0x1e 52 53/* PHY Control 2 / PHY Control (if no PHY Control 1) */ 54#define MII_KSZPHY_CTRL_2 0x1f 55#define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2 56/* bitmap of PHY register to set interrupt mode */ 57#define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9) | 1/* 2 * drivers/net/phy/micrel.c 3 * 4 * Driver for Micrel PHYs 5 * 6 * Author: David J. Choi 7 * 8 * Copyright (c) 2010-2013 Micrel, Inc. --- 41 unchanged lines hidden (view full) --- 50/* PHY Control 1 */ 51#define MII_KSZPHY_CTRL_1 0x1e 52 53/* PHY Control 2 / PHY Control (if no PHY Control 1) */ 54#define MII_KSZPHY_CTRL_2 0x1f 55#define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2 56/* bitmap of PHY register to set interrupt mode */ 57#define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9) |
58#define KSZ9021_CTRL_INT_ACTIVE_HIGH BIT(14) 59#define KS8737_CTRL_INT_ACTIVE_HIGH BIT(14) | |
60#define KSZPHY_RMII_REF_CLK_SEL BIT(7) 61 62/* Write/read to/from extended registers */ 63#define MII_KSZPHY_EXTREG 0x0b 64#define KSZPHY_EXTREG_WRITE 0x8000 65 66#define MII_KSZPHY_EXTREG_WRITE 0x0c 67#define MII_KSZPHY_EXTREG_READ 0x0d 68 69/* Extended registers */ 70#define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104 71#define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105 72#define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106 73 74#define PS_TO_REG 200 75 76struct kszphy_type { 77 u32 led_mode_reg; | 58#define KSZPHY_RMII_REF_CLK_SEL BIT(7) 59 60/* Write/read to/from extended registers */ 61#define MII_KSZPHY_EXTREG 0x0b 62#define KSZPHY_EXTREG_WRITE 0x8000 63 64#define MII_KSZPHY_EXTREG_WRITE 0x0c 65#define MII_KSZPHY_EXTREG_READ 0x0d 66 67/* Extended registers */ 68#define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104 69#define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105 70#define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106 71 72#define PS_TO_REG 200 73 74struct kszphy_type { 75 u32 led_mode_reg; |
76 u16 interrupt_level_mask; |
|
78 bool has_broadcast_disable; 79 bool has_rmii_ref_clk_sel; 80}; 81 82struct kszphy_priv { 83 const struct kszphy_type *type; 84 int led_mode; 85 bool rmii_ref_clk_sel; --- 14 unchanged lines hidden (view full) --- 100}; 101 102static const struct kszphy_type ksz8081_type = { 103 .led_mode_reg = MII_KSZPHY_CTRL_2, 104 .has_broadcast_disable = true, 105 .has_rmii_ref_clk_sel = true, 106}; 107 | 77 bool has_broadcast_disable; 78 bool has_rmii_ref_clk_sel; 79}; 80 81struct kszphy_priv { 82 const struct kszphy_type *type; 83 int led_mode; 84 bool rmii_ref_clk_sel; --- 14 unchanged lines hidden (view full) --- 99}; 100 101static const struct kszphy_type ksz8081_type = { 102 .led_mode_reg = MII_KSZPHY_CTRL_2, 103 .has_broadcast_disable = true, 104 .has_rmii_ref_clk_sel = true, 105}; 106 |
107static const struct kszphy_type ks8737_type = { 108 .interrupt_level_mask = BIT(14), 109}; 110 111static const struct kszphy_type ksz9021_type = { 112 .interrupt_level_mask = BIT(14), 113}; 114 |
|
108static int kszphy_extended_write(struct phy_device *phydev, 109 u32 regnum, u16 val) 110{ 111 phy_write(phydev, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | regnum); 112 return phy_write(phydev, MII_KSZPHY_EXTREG_WRITE, val); 113} 114 115static int kszphy_extended_read(struct phy_device *phydev, --- 8 unchanged lines hidden (view full) --- 124 /* bit[7..0] int status, which is a read and clear register. */ 125 int rc; 126 127 rc = phy_read(phydev, MII_KSZPHY_INTCS); 128 129 return (rc < 0) ? rc : 0; 130} 131 | 115static int kszphy_extended_write(struct phy_device *phydev, 116 u32 regnum, u16 val) 117{ 118 phy_write(phydev, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | regnum); 119 return phy_write(phydev, MII_KSZPHY_EXTREG_WRITE, val); 120} 121 122static int kszphy_extended_read(struct phy_device *phydev, --- 8 unchanged lines hidden (view full) --- 131 /* bit[7..0] int status, which is a read and clear register. */ 132 int rc; 133 134 rc = phy_read(phydev, MII_KSZPHY_INTCS); 135 136 return (rc < 0) ? rc : 0; 137} 138 |
132static int kszphy_set_interrupt(struct phy_device *phydev) | 139static int kszphy_config_intr(struct phy_device *phydev) |
133{ | 140{ |
141 const struct kszphy_type *type = phydev->drv->driver_data; |
|
134 int temp; | 142 int temp; |
135 temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ? 136 KSZPHY_INTCS_ALL : 0; 137 return phy_write(phydev, MII_KSZPHY_INTCS, temp); 138} | 143 u16 mask; |
139 | 144 |
140static int kszphy_config_intr(struct phy_device *phydev) 141{ 142 int temp, rc; | 145 if (type && type->interrupt_level_mask) 146 mask = type->interrupt_level_mask; 147 else 148 mask = KSZPHY_CTRL_INT_ACTIVE_HIGH; |
143 144 /* set the interrupt pin active low */ 145 temp = phy_read(phydev, MII_KSZPHY_CTRL); 146 if (temp < 0) 147 return temp; | 149 150 /* set the interrupt pin active low */ 151 temp = phy_read(phydev, MII_KSZPHY_CTRL); 152 if (temp < 0) 153 return temp; |
148 temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; | 154 temp &= ~mask; |
149 phy_write(phydev, MII_KSZPHY_CTRL, temp); | 155 phy_write(phydev, MII_KSZPHY_CTRL, temp); |
150 rc = kszphy_set_interrupt(phydev); 151 return rc < 0 ? rc : 0; 152} | |
153 | 156 |
154static int ksz9021_config_intr(struct phy_device *phydev) 155{ 156 int temp, rc; | 157 /* enable / disable interrupts */ 158 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 159 temp = KSZPHY_INTCS_ALL; 160 else 161 temp = 0; |
157 | 162 |
158 /* set the interrupt pin active low */ 159 temp = phy_read(phydev, MII_KSZPHY_CTRL); 160 if (temp < 0) 161 return temp; 162 temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH; 163 phy_write(phydev, MII_KSZPHY_CTRL, temp); 164 rc = kszphy_set_interrupt(phydev); 165 return rc < 0 ? rc : 0; | 163 return phy_write(phydev, MII_KSZPHY_INTCS, temp); |
166} 167 | 164} 165 |
168static int ks8737_config_intr(struct phy_device *phydev) 169{ 170 int temp, rc; 171 172 /* set the interrupt pin active low */ 173 temp = phy_read(phydev, MII_KSZPHY_CTRL); 174 if (temp < 0) 175 return temp; 176 temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH; 177 phy_write(phydev, MII_KSZPHY_CTRL, temp); 178 rc = kszphy_set_interrupt(phydev); 179 return rc < 0 ? rc : 0; 180} 181 | |
182static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val) 183{ 184 int ctrl; 185 186 ctrl = phy_read(phydev, MII_KSZPHY_CTRL); 187 if (ctrl < 0) 188 return ctrl; 189 --- 386 unchanged lines hidden (view full) --- 576 577static struct phy_driver ksphy_driver[] = { 578{ 579 .phy_id = PHY_ID_KS8737, 580 .phy_id_mask = 0x00fffff0, 581 .name = "Micrel KS8737", 582 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), 583 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 166static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val) 167{ 168 int ctrl; 169 170 ctrl = phy_read(phydev, MII_KSZPHY_CTRL); 171 if (ctrl < 0) 172 return ctrl; 173 --- 386 unchanged lines hidden (view full) --- 560 561static struct phy_driver ksphy_driver[] = { 562{ 563 .phy_id = PHY_ID_KS8737, 564 .phy_id_mask = 0x00fffff0, 565 .name = "Micrel KS8737", 566 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), 567 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
568 .driver_data = &ks8737_type, |
|
584 .config_init = kszphy_config_init, 585 .config_aneg = genphy_config_aneg, 586 .read_status = genphy_read_status, 587 .ack_interrupt = kszphy_ack_interrupt, | 569 .config_init = kszphy_config_init, 570 .config_aneg = genphy_config_aneg, 571 .read_status = genphy_read_status, 572 .ack_interrupt = kszphy_ack_interrupt, |
588 .config_intr = ks8737_config_intr, | 573 .config_intr = kszphy_config_intr, |
589 .suspend = genphy_suspend, 590 .resume = genphy_resume, 591 .driver = { .owner = THIS_MODULE,}, 592}, { 593 .phy_id = PHY_ID_KSZ8021, 594 .phy_id_mask = 0x00ffffff, 595 .name = "Micrel KSZ8021 or KSZ8031", 596 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | --- 124 unchanged lines hidden (view full) --- 721 .resume = genphy_resume, 722 .driver = { .owner = THIS_MODULE,}, 723}, { 724 .phy_id = PHY_ID_KSZ9021, 725 .phy_id_mask = 0x000ffffe, 726 .name = "Micrel KSZ9021 Gigabit PHY", 727 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), 728 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 574 .suspend = genphy_suspend, 575 .resume = genphy_resume, 576 .driver = { .owner = THIS_MODULE,}, 577}, { 578 .phy_id = PHY_ID_KSZ8021, 579 .phy_id_mask = 0x00ffffff, 580 .name = "Micrel KSZ8021 or KSZ8031", 581 .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | --- 124 unchanged lines hidden (view full) --- 706 .resume = genphy_resume, 707 .driver = { .owner = THIS_MODULE,}, 708}, { 709 .phy_id = PHY_ID_KSZ9021, 710 .phy_id_mask = 0x000ffffe, 711 .name = "Micrel KSZ9021 Gigabit PHY", 712 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), 713 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
714 .driver_data = &ksz9021_type, |
|
729 .config_init = ksz9021_config_init, 730 .config_aneg = genphy_config_aneg, 731 .read_status = genphy_read_status, 732 .ack_interrupt = kszphy_ack_interrupt, | 715 .config_init = ksz9021_config_init, 716 .config_aneg = genphy_config_aneg, 717 .read_status = genphy_read_status, 718 .ack_interrupt = kszphy_ack_interrupt, |
733 .config_intr = ksz9021_config_intr, | 719 .config_intr = kszphy_config_intr, |
734 .suspend = genphy_suspend, 735 .resume = genphy_resume, 736 .read_mmd_indirect = ksz9021_rd_mmd_phyreg, 737 .write_mmd_indirect = ksz9021_wr_mmd_phyreg, 738 .driver = { .owner = THIS_MODULE, }, 739}, { 740 .phy_id = PHY_ID_KSZ9031, 741 .phy_id_mask = 0x00fffff0, 742 .name = "Micrel KSZ9031 Gigabit PHY", 743 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), 744 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 720 .suspend = genphy_suspend, 721 .resume = genphy_resume, 722 .read_mmd_indirect = ksz9021_rd_mmd_phyreg, 723 .write_mmd_indirect = ksz9021_wr_mmd_phyreg, 724 .driver = { .owner = THIS_MODULE, }, 725}, { 726 .phy_id = PHY_ID_KSZ9031, 727 .phy_id_mask = 0x00fffff0, 728 .name = "Micrel KSZ9031 Gigabit PHY", 729 .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), 730 .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
731 .driver_data = &ksz9021_type, |
|
745 .config_init = ksz9031_config_init, 746 .config_aneg = genphy_config_aneg, 747 .read_status = genphy_read_status, 748 .ack_interrupt = kszphy_ack_interrupt, | 732 .config_init = ksz9031_config_init, 733 .config_aneg = genphy_config_aneg, 734 .read_status = genphy_read_status, 735 .ack_interrupt = kszphy_ack_interrupt, |
749 .config_intr = ksz9021_config_intr, | 736 .config_intr = kszphy_config_intr, |
750 .suspend = genphy_suspend, 751 .resume = genphy_resume, 752 .driver = { .owner = THIS_MODULE, }, 753}, { 754 .phy_id = PHY_ID_KSZ8873MLL, 755 .phy_id_mask = 0x00fffff0, 756 .name = "Micrel KSZ8873MLL Switch", 757 .features = (SUPPORTED_Pause | SUPPORTED_Asym_Pause), --- 44 unchanged lines hidden --- | 737 .suspend = genphy_suspend, 738 .resume = genphy_resume, 739 .driver = { .owner = THIS_MODULE, }, 740}, { 741 .phy_id = PHY_ID_KSZ8873MLL, 742 .phy_id_mask = 0x00fffff0, 743 .name = "Micrel KSZ8873MLL Switch", 744 .features = (SUPPORTED_Pause | SUPPORTED_Asym_Pause), --- 44 unchanged lines hidden --- |