led.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /****************************************************
  2. * LED1 ---- PG6 LED2 ---- PG7 *
  3. * LED3 ---- PG8 LED4 ---- PG9 *
  4. * LED5 ---- PG10 LED6 ---- PG11 *
  5. ****************************************************/
  6. #include <linux/linkage.h>
  7. #include <asm/blackfin.h>
  8. /* All functions in this file save the registers they uses.
  9. So there is no need to save any registers before calling them. */
  10. .text;
  11. /* Initialize LEDs. */
  12. ENTRY(_led_init)
  13. LINK 0;
  14. [--SP] = P0;
  15. [--SP] = R0;
  16. [--SP] = R1;
  17. [--SP] = R2;
  18. R1 = (PG6|PG7|PG8|PG9|PG10|PG11)(Z);
  19. R2 = ~R1;
  20. P0.H = hi(PORTG_FER);
  21. P0.L = lo(PORTG_FER);
  22. R0 = W[P0](Z);
  23. SSYNC;
  24. R0 = R0 & R2;
  25. W[P0] = R0.L;
  26. SSYNC;
  27. P0.H = hi(PORTG_DIR_SET);
  28. P0.L = lo(PORTG_DIR_SET);
  29. W[P0] = R1.L;
  30. SSYNC;
  31. P0.H = hi(PORTG_INEN);
  32. P0.L = lo(PORTG_INEN);
  33. R0 = W[P0](Z);
  34. SSYNC;
  35. R0 = R0 & R2;
  36. W[P0] = R0.L;
  37. SSYNC;
  38. R2 = [SP++];
  39. R1 = [SP++];
  40. R0 = [SP++];
  41. P0 = [SP++];
  42. RTS;
  43. .size _led_init, .-_led_init
  44. /* Set one LED on. Leave other LEDs unchanged.
  45. It expects the LED number passed through R0. */
  46. ENTRY(_led_on)
  47. LINK 0;
  48. [--SP] = P0;
  49. [--SP] = R1;
  50. CALL _led_init;
  51. R1 = 1;
  52. R0 += 5;
  53. R1 <<= R0;
  54. P0.H = hi(PORTG_SET);
  55. P0.L = lo(PORTG_SET);
  56. W[P0] = R1.L;
  57. SSYNC;
  58. R1 = [SP++];
  59. P0 = [SP++];
  60. UNLINK;
  61. RTS;
  62. .size _led_on, .-_led_on
  63. /* Set one LED off. Leave other LEDs unchanged. */
  64. ENTRY(_led_off)
  65. LINK 0;
  66. [--SP] = P0;
  67. [--SP] = R1;
  68. CALL _led_init;
  69. R1 = 1;
  70. R0 += 5;
  71. R1 <<= R0;
  72. P0.H = hi(PORTG_CLEAR);
  73. P0.L = lo(PORTG_CLEAR);
  74. W[P0] = R1.L;
  75. SSYNC;
  76. R1 = [SP++];
  77. P0 = [SP++];
  78. UNLINK;
  79. RTS;
  80. .size _led_off, .-_led_off
  81. /* Toggle one LED. Leave other LEDs unchanged. */
  82. ENTRY(_led_toggle)
  83. LINK 0;
  84. [--SP] = P0;
  85. [--SP] = R1;
  86. CALL _led_init;
  87. R1 = 1;
  88. R0 += 5;
  89. R1 <<= R0;
  90. P0.H = hi(PORTG);
  91. P0.L = lo(PORTG);
  92. R0 = W[P0](Z);
  93. SSYNC;
  94. R0 = R0 ^ R1;
  95. W[P0] = R0.L;
  96. SSYNC;
  97. R1 = [SP++];
  98. P0 = [SP++];
  99. UNLINK;
  100. RTS;
  101. .size _led_toggle, .-_led_toggle
  102. /* Display the number using LEDs in binary format. */
  103. ENTRY(_led_disp_num)
  104. LINK 0;
  105. [--SP] = P0;
  106. [--SP] = R1;
  107. [--SP] = R2;
  108. CALL _led_init;
  109. R1 = 0x3f(X);
  110. R0 = R0 & R1;
  111. R2 = 6(X);
  112. R0 <<= R2;
  113. R1 <<= R2;
  114. P0.H = hi(PORTG);
  115. P0.L = lo(PORTG);
  116. R2 = W[P0](Z);
  117. SSYNC;
  118. R1 = ~R1;
  119. R2 = R2 & R1;
  120. R2 = R2 | R0;
  121. W[P0] = R2.L;
  122. SSYNC;
  123. R2 = [SP++];
  124. R1 = [SP++];
  125. P0 = [SP++];
  126. UNLINK;
  127. RTS;
  128. .size _led_disp_num, .-_led_disp_num
  129. /* Toggle the number using LEDs in binary format. */
  130. ENTRY(_led_toggle_num)
  131. LINK 0;
  132. [--SP] = P0;
  133. [--SP] = R1;
  134. [--SP] = R2;
  135. CALL _led_init;
  136. R1 = 0x3f(X);
  137. R0 = R0 & R1;
  138. R1 = 6(X);
  139. R0 <<= R1;
  140. P0.H = hi(PORTG);
  141. P0.L = lo(PORTG);
  142. R1 = W[P0](Z);
  143. SSYNC;
  144. R1 = R1 ^ R0;
  145. W[P0] = R1.L;
  146. SSYNC;
  147. R2 = [SP++];
  148. R1 = [SP++];
  149. P0 = [SP++];
  150. UNLINK;
  151. RTS;
  152. .size _led_toggle_num, .-_led_toggle_num