soft_switch.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * U-Boot - main board file
  3. *
  4. * Copyright (c) 2008-2011 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <common.h>
  9. #include <asm/blackfin.h>
  10. #include <asm/io.h>
  11. #include <i2c.h>
  12. #include "soft_switch.h"
  13. struct switch_config {
  14. uchar dir0; /* IODIRA */
  15. uchar dir1; /* IODIRB */
  16. uchar value0; /* OLATA */
  17. uchar value1; /* OLATB */
  18. };
  19. static struct switch_config switch_config_array[NUM_SWITCH] = {
  20. {
  21. /*
  22. U45 Port A U45 Port B
  23. 7--------------- RMII_CLK_EN | 7--------------- ~TEMP_THERM_EN
  24. | 6------------- ~CNT0ZM_EN | | 6------------- ~TEMP_IRQ_EN
  25. | | 5----------- ~CNT0DG_EN | | | 5----------- ~UART0CTS_146_EN
  26. | | | 4--------- ~CNT0UD_EN | | | | 4--------- ~UART0CTS_RST_EN
  27. | | | | 3------- ~CAN0RX_EN | | | | | 3------- ~UART0CTS_RTS_LPBK
  28. | | | | | 2----- ~CAN0_ERR_EN | | | | | | 2----- ~UART0CTS_EN
  29. | | | | | | 1--- ~CAN_STB | | | | | | | 1--- ~UART0RX_EN
  30. | | | | | | | 0- CAN_EN | | | | | | | | 0- ~UART0RTS_EN
  31. | | | | | | | | | | | | | | | | |
  32. O O O O O O O O | O O O O O O O O (I/O direction)
  33. 1 0 0 0 0 0 1 1 | 1 1 1 1 1 0 0 0 (value being set)
  34. */
  35. .dir0 = 0x0, /* all output */
  36. .dir1 = 0x0, /* all output */
  37. .value0 = RMII_CLK_EN | CAN_STB | CAN_EN,
  38. .value1 = TEMP_THERM_EN | TEMP_IRQ_EN | UART0CTS_146_EN
  39. | UART0CTS_RST_EN | UART0CTS_RTS_LPBK,
  40. },
  41. {
  42. /*
  43. U46 Port A U46 Port B
  44. 7--------------- ~LED4_GPIO_EN | 7--------------- EMPTY
  45. | 6------------- ~LED3_GPIO_EN | | 6------------- ~SPI0D3_EN
  46. | | 5----------- ~LED2_GPIO_EN | | | 5----------- ~SPI0D2_EN
  47. | | | 4--------- ~LED1_GPIO_EN | | | | 4--------- ~SPIFLASH_CS_EN
  48. | | | | 3------- SMC0_LP0_EN | | | | | 3------- ~SD_WP_EN
  49. | | | | | 2----- EMPTY | | | | | | 2----- ~SD_CD_EN
  50. | | | | | | 1--- SMC0_EPPI2 | | | | | | | 1--- ~PUSHBUTTON2_EN
  51. _LP1_SWITCH
  52. | | | | | | | 0- OVERRIDE_SMC0 | | | | | | | | 0- ~PUSHBUTTON1_EN
  53. _LP0_BOOT
  54. | | | | | | | | | | | | | | | | |
  55. O O O O O O O O | O O O O O O O O (I/O direction)
  56. 0 0 0 0 0 X 0 1 | X 0 0 0 0 0 0 0 (value being set)
  57. */
  58. .dir0 = 0x0, /* all output */
  59. .dir1 = 0x0, /* all output */
  60. #ifdef CONFIG_BFIN_LINKPORT
  61. .value0 = OVERRIDE_SMC0_LP0_BOOT,
  62. #else
  63. .value0 = SMC0_EPPI2_LP1_SWITCH,
  64. #endif
  65. .value1 = 0x0,
  66. },
  67. {
  68. /*
  69. U47 Port A U47 Port B
  70. 7--------------- ~PD2_SPI0MISO | 7--------------- EMPTY
  71. _EI3_EN
  72. | 6------------- ~PD1_SPI0D3 | | 6------------- EMPTY
  73. _EPPI1D17
  74. _SPI0SEL2
  75. _EI3_EN
  76. | | 5----------- ~PD0_SPI0D2 | | | 5----------- EMPTY
  77. _EPPI1D16
  78. _SPI0SEL3
  79. _EI3_EN
  80. | | | 4--------- ~WAKE_PUSH | | | | 4--------- EMPTY
  81. BUTTON_EN
  82. | | | | 3------- ~ETHERNET_EN | | | | | 3------- EMPTY
  83. | | | | | 2----- PHYAD0 | | | | | | 2----- EMPTY
  84. | | | | | | 1--- PHY_PWR | | | | | | | 1--- ~PD4_SPI0CK_EI3_EN
  85. _DWN_INT
  86. | | | | | | | 0- ~PHYINT_EN | | | | | | | | 0- ~PD3_SPI0MOSI_EI3_EN
  87. | | | | | | | | | | | | | | | | |
  88. O O O O O I I O | O O O O O O O O (I/O direction)
  89. 1 1 1 0 0 0 0 0 | X X X X X X 1 1 (value being set)
  90. */
  91. .dir0 = 0x6, /* bits 1 and 2 input, all others output */
  92. .dir1 = 0x0, /* all output */
  93. .value0 = PD1_SPI0D3_EN | PD0_SPI0D2_EN,
  94. .value1 = 0,
  95. },
  96. };
  97. static int setup_soft_switch(int addr, struct switch_config *config)
  98. {
  99. int ret = 0;
  100. ret = i2c_write(addr, OLATA, 1, &config->value0, 1);
  101. if (ret)
  102. return ret;
  103. ret = i2c_write(addr, OLATB, 1, &config->value1, 1);
  104. if (ret)
  105. return ret;
  106. ret = i2c_write(addr, IODIRA, 1, &config->dir0, 1);
  107. if (ret)
  108. return ret;
  109. return i2c_write(addr, IODIRB, 1, &config->dir1, 1);
  110. }
  111. int config_switch_bit(int addr, int port, int bit, int dir, uchar value)
  112. {
  113. int ret, data_reg, dir_reg;
  114. uchar tmp;
  115. if (port == IO_PORT_A) {
  116. data_reg = OLATA;
  117. dir_reg = IODIRA;
  118. } else {
  119. data_reg = OLATB;
  120. dir_reg = IODIRB;
  121. }
  122. if (dir == IO_PORT_INPUT) {
  123. ret = i2c_read(addr, dir_reg, 1, &tmp, 1);
  124. if (ret)
  125. return ret;
  126. tmp |= bit;
  127. return i2c_write(addr, dir_reg, 1, &tmp, 1);
  128. } else {
  129. ret = i2c_read(addr, data_reg, 1, &tmp, 1);
  130. if (ret)
  131. return ret;
  132. if (value)
  133. tmp |= bit;
  134. else
  135. tmp &= ~bit;
  136. ret = i2c_write(addr, data_reg, 1, &tmp, 1);
  137. if (ret)
  138. return ret;
  139. ret = i2c_read(addr, dir_reg, 1, &tmp, 1);
  140. if (ret)
  141. return ret;
  142. tmp &= ~bit;
  143. return i2c_write(addr, dir_reg, 1, &tmp, 1);
  144. }
  145. }
  146. int setup_board_switches(void)
  147. {
  148. int ret;
  149. int i;
  150. for (i = 0; i < NUM_SWITCH; i++) {
  151. ret = setup_soft_switch(SWITCH_ADDR + i,
  152. &switch_config_array[i]);
  153. if (ret)
  154. return ret;
  155. }
  156. return 0;
  157. }