/*
 * (C) Copyright 2001
 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * This provides a bit-banged interface to the ethernet MII management
 * channel.
 */

#include <common.h>
#include <ioports.h>
#include <ppc_asm.tmpl>

#ifdef CONFIG_BITBANGMII


/*****************************************************************************
 *
 * Utility to send the preamble, address, and register (common to read
 * and write).
 */
static void miiphy_pre(char	      read,
		       unsigned char  addr,
		       unsigned char  reg)
{
  int   j;	/* counter */
  volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, MDIO_PORT);

  /*
   * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
   * The IEEE spec says this is a PHY optional requirement.  The AMD
   * 79C874 requires one after power up and one after a MII communications
   * error.  This means that we are doing more preambles than we need,
   * but it is safer and will be much more robust.
   */

  MDIO_ACTIVE;
  MDIO(1);
  for(j = 0; j < 32; j++)
  {
    MDC(0);
    MIIDELAY;
    MDC(1);
    MIIDELAY;
  }

  /* send the start bit (01) and the read opcode (10) or write (10) */
  MDC(0); MDIO(0); MIIDELAY; MDC(1); MIIDELAY;
  MDC(0); MDIO(1); MIIDELAY; MDC(1); MIIDELAY;
  MDC(0); MDIO(read);  MIIDELAY; MDC(1); MIIDELAY;
  MDC(0); MDIO(!read); MIIDELAY; MDC(1); MIIDELAY;

  /* send the PHY address */
  for(j = 0; j < 5; j++)
  {
    MDC(0);
    if((addr & 0x10) == 0)
    {
      MDIO(0);
    }
    else
    {
      MDIO(1);
    }
    MIIDELAY;
    MDC(1);
    MIIDELAY;
    addr <<= 1;
  }

  /* send the register address */
  for(j = 0; j < 5; j++)
  {
    MDC(0);
    if((reg & 0x10) == 0)
    {
      MDIO(0);
    }
    else
    {
      MDIO(1);
    }
    MIIDELAY;
    MDC(1);
    MIIDELAY;
    reg <<= 1;
  }
}


/*****************************************************************************
 *
 * Read a MII PHY register.
 *
 * Returns:
 *   0 on success
 */
int miiphy_read(unsigned char  addr,
		unsigned char  reg,
		unsigned short *value)
{
  short rdreg;	/* register working value */
  int   j;	/* counter */
  volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, MDIO_PORT);

  miiphy_pre(1, addr, reg);

  /* tri-state our MDIO I/O pin so we can read */
  MDC(0);
  MDIO_TRISTATE;
  MIIDELAY;
  MDC(1);
  MIIDELAY;

  /* check the turnaround bit: the PHY should be driving it to zero */
  if(MDIO_READ != 0)
  {
    /* printf("PHY didn't drive TA low\n"); */
    for(j = 0; j < 32; j++)
    {
      MDC(0);
      MIIDELAY;
      MDC(1);
      MIIDELAY;
    }
    return(-1);
  }

  MDC(0);
  MIIDELAY;

  /* read 16 bits of register data, MSB first */
  rdreg = 0;
  for(j = 0; j < 16; j++)
  {
    MDC(1);
    MIIDELAY;
    rdreg <<= 1;
    rdreg |= MDIO_READ;
    MDC(0);
    MIIDELAY;
  }

  MDC(1);
  MIIDELAY;
  MDC(0);
  MIIDELAY;
  MDC(1);
  MIIDELAY;

  *value = rdreg;

#ifdef DEBUG
  printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
#endif

  return 0;
}


/*****************************************************************************
 *
 * Write a MII PHY register.
 *
 * Returns:
 *   0 on success
 */
int miiphy_write(unsigned char  addr,
		 unsigned char  reg,
		 unsigned short value)
{
  int   j;	/* counter */
  volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, MDIO_PORT);

  miiphy_pre(0, addr, reg);

  /* send the turnaround (10) */
  MDC(0); MDIO(1); MIIDELAY; MDC(1); MIIDELAY;
  MDC(0); MDIO(0); MIIDELAY; MDC(1); MIIDELAY;

  /* write 16 bits of register data, MSB first */
  for(j = 0; j < 16; j++)
  {
    MDC(0);
    if((value & 0x00008000) == 0)
    {
      MDIO(0);
    }
    else
    {
      MDIO(1);
    }
    MIIDELAY;
    MDC(1);
    MIIDELAY;
    value <<= 1;
  }

  /*
   * Tri-state the MDIO line.
   */
  MDIO_TRISTATE;
  MDC(0);
  MIIDELAY;
  MDC(1);
  MIIDELAY;

  return 0;
}

#endif /* CONFIG_BITBANGMII */

