davicom.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Davicom PHY drivers
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  17. * MA 02111-1307 USA
  18. *
  19. * Copyright 2010-2011 Freescale Semiconductor, Inc.
  20. * author Andy Fleming
  21. *
  22. */
  23. #include <phy.h>
  24. #define MIIM_DM9161_SCR 0x10
  25. #define MIIM_DM9161_SCR_INIT 0x0610
  26. /* DM9161 Specified Configuration and Status Register */
  27. #define MIIM_DM9161_SCSR 0x11
  28. #define MIIM_DM9161_SCSR_100F 0x8000
  29. #define MIIM_DM9161_SCSR_100H 0x4000
  30. #define MIIM_DM9161_SCSR_10F 0x2000
  31. #define MIIM_DM9161_SCSR_10H 0x1000
  32. /* DM9161 10BT Configuration/Status */
  33. #define MIIM_DM9161_10BTCSR 0x12
  34. #define MIIM_DM9161_10BTCSR_INIT 0x7800
  35. /* Davicom DM9161E */
  36. static int dm9161_config(struct phy_device *phydev)
  37. {
  38. phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_ISOLATE);
  39. /* Do not bypass the scrambler/descrambler */
  40. phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCR,
  41. MIIM_DM9161_SCR_INIT);
  42. /* Clear 10BTCSR to default */
  43. phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_10BTCSR,
  44. MIIM_DM9161_10BTCSR_INIT);
  45. genphy_config_aneg(phydev);
  46. return 0;
  47. }
  48. static int dm9161_parse_status(struct phy_device *phydev)
  49. {
  50. int mii_reg;
  51. mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCSR);
  52. if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
  53. phydev->speed = SPEED_100;
  54. else
  55. phydev->speed = SPEED_10;
  56. if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
  57. phydev->duplex = DUPLEX_FULL;
  58. else
  59. phydev->duplex = DUPLEX_HALF;
  60. return 0;
  61. }
  62. static int dm9161_startup(struct phy_device *phydev)
  63. {
  64. genphy_update_link(phydev);
  65. dm9161_parse_status(phydev);
  66. return 0;
  67. }
  68. static struct phy_driver DM9161_driver = {
  69. .name = "Davicom DM9161E",
  70. .uid = 0x181b880,
  71. .mask = 0xffffff0,
  72. .features = PHY_BASIC_FEATURES,
  73. .config = &dm9161_config,
  74. .startup = &dm9161_startup,
  75. .shutdown = &genphy_shutdown,
  76. };
  77. int phy_davicom_init(void)
  78. {
  79. phy_register(&DM9161_driver);
  80. return 0;
  81. }