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 ---