/* The 32-pin IP101GR package can re-configure the mode of the RXER/INTR_32 pin * (pin number 21). The hardware default is RXER (receive error) mode. But it * can be configured to interrupt mode manually.
*/ enum ip101gr_sel_intr32 {
IP101GR_SEL_INTR32_KEEP,
IP101GR_SEL_INTR32_INTR,
IP101GR_SEL_INTR32_RXER,
};
struct ip101g_hw_stat { constchar *name; int page;
};
staticint ip1001_config_init(struct phy_device *phydev)
{ int c;
/* Enable Auto Power Saving mode */
c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2); if (c < 0) return c;
c |= IP1001_APS_ON;
c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c); if (c < 0) return c;
if (phy_interface_is_rgmii(phydev)) {
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); if (c < 0) return c;
c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL); elseif (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
c |= IP1001_RXPHASE_SEL; elseif (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
c |= IP1001_TXPHASE_SEL;
c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); if (c < 0) return c;
}
return 0;
}
staticint ip175c_read_status(struct phy_device *phydev)
{ if (phydev->mdio.addr == 4) /* WAN port */
genphy_read_status(phydev); else /* Don't need to read status for switch ports */
phydev->irq = PHY_MAC_INTERRUPT;
return 0;
}
staticint ip175c_config_aneg(struct phy_device *phydev)
{ if (phydev->mdio.addr == 4) /* WAN port */
genphy_config_aneg(phydev);
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
/* Both functions (RX error and interrupt status) are sharing the same * pin on the 32-pin IP101GR, so this is an exclusive choice.
*/ if (device_property_read_bool(dev, "icplus,select-rx-error") &&
device_property_read_bool(dev, "icplus,select-interrupt")) {
dev_err(dev, "RXER and INTR mode cannot be selected together\n"); return -EINVAL;
}
oldpage = phy_select_page(phydev, IP101G_DEFAULT_PAGE); if (oldpage < 0) goto out;
/* configure the RXER/INTR_32 pin of the 32-pin IP101GR if needed: */ switch (priv->sel_intr32) { case IP101GR_SEL_INTR32_RXER:
err = __phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, 0); if (err < 0) goto out; break;
case IP101GR_SEL_INTR32_INTR:
err = __phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32,
IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32); if (err < 0) goto out; break;
default: /* Don't touch IP101G_DIGITAL_IO_SPEC_CTRL because it's not * documented on IP101A and it's not clear whether this would * cause problems. * For the 32-pin IP101GR we simply keep the SEL_INTR32 * configuration as set by the bootloader when not configured * to one of the special functions.
*/ break;
}
if (!(irq_status & (IP101A_G_IRQ_SPEED_CHANGE |
IP101A_G_IRQ_DUPLEX_CHANGE |
IP101A_G_IRQ_LINK_CHANGE))) return IRQ_NONE;
phy_trigger_machine(phydev);
return IRQ_HANDLED;
}
/* The IP101A doesn't really have a page register. We just pretend to have one * so we can use the paged versions of the callbacks of the IP101G.
*/ staticint ip101a_read_page(struct phy_device *phydev)
{ return IP101G_DEFAULT_PAGE;
}
staticint ip101a_g_has_page_register(struct phy_device *phydev)
{ int oldval, val, ret;
oldval = phy_read(phydev, IP101G_PAGE_CONTROL); if (oldval < 0) return oldval;
ret = phy_write(phydev, IP101G_PAGE_CONTROL, 0xffff); if (ret) return ret;
val = phy_read(phydev, IP101G_PAGE_CONTROL); if (val < 0) return val;
ret = phy_write(phydev, IP101G_PAGE_CONTROL, oldval); if (ret) return ret;
return val == IP101G_PAGE_CONTROL_MASK;
}
staticint ip101a_g_match_phy_device(struct phy_device *phydev, bool ip101a)
{ int ret;
if (phydev->phy_id != IP101A_PHY_ID) return 0;
/* The IP101A and the IP101G share the same PHY identifier.The IP101G * seems to be a successor of the IP101A and implements more functions. * Amongst other things there is a page select register, which is not * available on the IP101A. Use this to distinguish these two.
*/
ret = ip101a_g_has_page_register(phydev); if (ret < 0) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.