lxt.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * drivers/net/phy/lxt.c
  3. *
  4. * Driver for Intel LXT PHYs
  5. *
  6. * Author: Andy Fleming
  7. *
  8. * Copyright (c) 2004 Freescale Semiconductor, Inc.
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2 of the License, or (at your
  13. * option) any later version.
  14. *
  15. */
  16. #include <linux/config.h>
  17. #include <linux/kernel.h>
  18. #include <linux/sched.h>
  19. #include <linux/string.h>
  20. #include <linux/errno.h>
  21. #include <linux/unistd.h>
  22. #include <linux/slab.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/init.h>
  25. #include <linux/delay.h>
  26. #include <linux/netdevice.h>
  27. #include <linux/etherdevice.h>
  28. #include <linux/skbuff.h>
  29. #include <linux/spinlock.h>
  30. #include <linux/mm.h>
  31. #include <linux/module.h>
  32. #include <linux/mii.h>
  33. #include <linux/ethtool.h>
  34. #include <linux/phy.h>
  35. #include <asm/io.h>
  36. #include <asm/irq.h>
  37. #include <asm/uaccess.h>
  38. /* The Level one LXT970 is used by many boards */
  39. #define MII_LXT970_IER 17 /* Interrupt Enable Register */
  40. #define MII_LXT970_IER_IEN 0x0002
  41. #define MII_LXT970_ISR 18 /* Interrupt Status Register */
  42. #define MII_LXT970_CONFIG 19 /* Configuration Register */
  43. /* ------------------------------------------------------------------------- */
  44. /* The Level one LXT971 is used on some of my custom boards */
  45. /* register definitions for the 971 */
  46. #define MII_LXT971_IER 18 /* Interrupt Enable Register */
  47. #define MII_LXT971_IER_IEN 0x00f2
  48. #define MII_LXT971_ISR 19 /* Interrupt Status Register */
  49. MODULE_DESCRIPTION("Intel LXT PHY driver");
  50. MODULE_AUTHOR("Andy Fleming");
  51. MODULE_LICENSE("GPL");
  52. static int lxt970_ack_interrupt(struct phy_device *phydev)
  53. {
  54. int err;
  55. err = phy_read(phydev, MII_BMSR);
  56. if (err < 0)
  57. return err;
  58. err = phy_read(phydev, MII_LXT970_ISR);
  59. if (err < 0)
  60. return err;
  61. return 0;
  62. }
  63. static int lxt970_config_intr(struct phy_device *phydev)
  64. {
  65. int err;
  66. if(phydev->interrupts == PHY_INTERRUPT_ENABLED)
  67. err = phy_write(phydev, MII_LXT970_IER, MII_LXT970_IER_IEN);
  68. else
  69. err = phy_write(phydev, MII_LXT970_IER, 0);
  70. return err;
  71. }
  72. static int lxt970_config_init(struct phy_device *phydev)
  73. {
  74. int err;
  75. err = phy_write(phydev, MII_LXT970_CONFIG, 0);
  76. return err;
  77. }
  78. static int lxt971_ack_interrupt(struct phy_device *phydev)
  79. {
  80. int err = phy_read(phydev, MII_LXT971_ISR);
  81. if (err < 0)
  82. return err;
  83. return 0;
  84. }
  85. static int lxt971_config_intr(struct phy_device *phydev)
  86. {
  87. int err;
  88. if(phydev->interrupts == PHY_INTERRUPT_ENABLED)
  89. err = phy_write(phydev, MII_LXT971_IER, MII_LXT971_IER_IEN);
  90. else
  91. err = phy_write(phydev, MII_LXT971_IER, 0);
  92. return err;
  93. }
  94. static struct phy_driver lxt970_driver = {
  95. .phy_id = 0x07810000,
  96. .name = "LXT970",
  97. .phy_id_mask = 0x0fffffff,
  98. .features = PHY_BASIC_FEATURES,
  99. .flags = PHY_HAS_INTERRUPT,
  100. .config_init = lxt970_config_init,
  101. .config_aneg = genphy_config_aneg,
  102. .read_status = genphy_read_status,
  103. .ack_interrupt = lxt970_ack_interrupt,
  104. .config_intr = lxt970_config_intr,
  105. .driver = { .owner = THIS_MODULE,},
  106. };
  107. static struct phy_driver lxt971_driver = {
  108. .phy_id = 0x0001378e,
  109. .name = "LXT971",
  110. .phy_id_mask = 0x0fffffff,
  111. .features = PHY_BASIC_FEATURES,
  112. .flags = PHY_HAS_INTERRUPT,
  113. .config_aneg = genphy_config_aneg,
  114. .read_status = genphy_read_status,
  115. .ack_interrupt = lxt971_ack_interrupt,
  116. .config_intr = lxt971_config_intr,
  117. .driver = { .owner = THIS_MODULE,},
  118. };
  119. static int __init lxt_init(void)
  120. {
  121. int ret;
  122. ret = phy_driver_register(&lxt970_driver);
  123. if (ret)
  124. goto err1;
  125. ret = phy_driver_register(&lxt971_driver);
  126. if (ret)
  127. goto err2;
  128. return 0;
  129. err2:
  130. phy_driver_unregister(&lxt970_driver);
  131. err1:
  132. return ret;
  133. }
  134. static void __exit lxt_exit(void)
  135. {
  136. phy_driver_unregister(&lxt970_driver);
  137. phy_driver_unregister(&lxt971_driver);
  138. }
  139. module_init(lxt_init);
  140. module_exit(lxt_exit);