static int mdiobb_read(struct mii_bus *bus, int phy, int reg) { struct mdiobb_ctrl *ctrl = bus->priv; int ret, i; if (reg & MII_ADDR_C45) { reg = mdiobb_cmd_addr(ctrl, phy, reg); mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg); } else mdiobb_cmd(ctrl, MDIO_READ, phy, reg); ctrl->ops->set_mdio_dir(ctrl, 0); /* check the turnaround bit: the PHY should be driving it to zero */ if (mdiobb_get_bit(ctrl) != 0) { /* PHY didn't drive TA low -- flush any bits it * may be trying to send. */ for (i = 0; i < 32; i++) mdiobb_get_bit(ctrl); return 0xffff; } ret = mdiobb_get_num(ctrl, 16); mdiobb_get_bit(ctrl); return ret; }
/* MDIO must already be configured as input. */ static u16 mdiobb_get_num(struct mdiobb_ctrl *ctrl, int bits) { int i; u16 ret = 0; for (i = bits - 1; i >= 0; i--) { ret <<= 1; ret |= mdiobb_get_bit(ctrl); } return ret; }
/* MDIO must already be configured as input. */ static u16 mdiobb_get_num(int bits) { int i; u16 ret = 0; for (i = bits - 1; i >= 0; i--) { ret <<= 1; ret |= mdiobb_get_bit(); } return ret; }
u32 mdiobb_read(int phy_base, int phy, int reg) { u32 ret; /* * Get Right Phy Address */ phy = phy + phy_base; mdiobb_cmd(MDIO_READ, phy, reg); gpio_direction_input(MDIO); mdiobb_get_bit(); /* check the turnaround bit: the PHY should be driving it to zero */ if (mdiobb_get_bit() != 0) { //printk(KERN_WARNING "MDIO BAD READ FFFF from PHY(0x%x)/REG(0x%x)\n", phy, reg); } ret = mdiobb_get_num(16); return ret; }
static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) { struct mdiobb_ctrl *ctrl = bus->priv; mdiobb_cmd(ctrl, MDIO_WRITE, phy, reg); /* send the turnaround (10) */ mdiobb_send_bit(ctrl, 1); mdiobb_send_bit(ctrl, 0); mdiobb_send_num(ctrl, val, 16); ctrl->ops->set_mdio_dir(ctrl, 0); mdiobb_get_bit(ctrl); return 0; }
/* In clause 45 mode all commands are prefixed by MDIO_ADDR to specify the lower 16 bits of the 21 bit address. This transfer is done identically to a MDIO_WRITE except for a different code. To enable clause 45 mode or MII_ADDR_C45 into the address. Theoretically clause 45 and normal devices can exist on the same bus. Normal devices should ignore the MDIO_ADDR phase. */ static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr) { unsigned int dev_addr = (addr >> 16) & 0x1F; unsigned int reg = addr & 0xFFFF; mdiobb_cmd(ctrl, MDIO_C45_ADDR, phy, dev_addr); /* send the turnaround (10) */ mdiobb_send_bit(ctrl, 1); mdiobb_send_bit(ctrl, 0); mdiobb_send_num(ctrl, reg, 16); ctrl->ops->set_mdio_dir(ctrl, 0); mdiobb_get_bit(ctrl); return dev_addr; }