00001
00041 #ifndef CHIP_PORTMUX_H_INCLUDED
00042 #define CHIP_PORTMUX_H_INCLUDED
00043
00044 #include <gpio/portmux_gpio.h>
00045
00046 #define PORTMUX_PORT_A ((void *)GPIO_BASE)
00047 #define PORTMUX_PORT_B ((void *)(GPIO_BASE + 0x100))
00048 #define PORTMUX_PORT_C ((void *)(GPIO_BASE + 0x200))
00049 #define PORTMUX_PORT_X0 ((void *)(GPIO_BASE + 0x300))
00050 #define PORTMUX_PORT_X1 ((void *)(GPIO_BASE + 0x400))
00051
00055 static inline unsigned int portmux_gpio_version(void)
00056 {
00057 return PORTMUX_GPIO_VER(1, 1);
00058 }
00059
00060
00061
00062
00063
00064
00065
00066 #define PORTMUX_USART_RX (1 << 0)
00067 #define PORTMUX_USART_TX (1 << 1)
00068
00069 static inline void portmux_enable_usart_inline(unsigned int id,
00070 unsigned long flags, unsigned long drive_strength)
00071 {
00072 unsigned long pin_mask = 0;
00073
00074 switch (id) {
00075 case 0:
00076 if (flags & PORTMUX_USART_RX)
00077 pin_mask |= 1U << 3;
00078 if (flags & PORTMUX_USART_TX)
00079 pin_mask |= 1U << 4;
00080 portmux_select_peripheral(PORTMUX_PORT_A, pin_mask,
00081 PORTMUX_FUNC_A, PORTMUX_PULL_UP);
00082 break;
00083 case 1:
00084 if (flags & PORTMUX_USART_RX)
00085 pin_mask |= 1U << 5;
00086 if (flags & PORTMUX_USART_TX)
00087 pin_mask |= 1U << 6;
00088 portmux_select_peripheral(PORTMUX_PORT_A, pin_mask,
00089 PORTMUX_FUNC_A, PORTMUX_PULL_UP);
00090 break;
00091 case 2:
00092 if (flags & PORTMUX_USART_RX)
00093 portmux_select_peripheral(PORTMUX_PORT_A, 1U << 31,
00094 PORTMUX_FUNC_B, PORTMUX_PULL_UP);
00095 if (flags & PORTMUX_USART_TX)
00096 portmux_select_peripheral(PORTMUX_PORT_B, 1U << 0,
00097 PORTMUX_FUNC_B, PORTMUX_PULL_UP);
00098 break;
00099 case 3:
00100 if (flags & PORTMUX_USART_RX)
00101 portmux_select_peripheral(PORTMUX_PORT_B, 1U << 4,
00102 PORTMUX_FUNC_B, PORTMUX_PULL_UP);
00103 if (flags & PORTMUX_USART_TX)
00104 portmux_select_peripheral(PORTMUX_PORT_A, 1U << 29,
00105 PORTMUX_FUNC_B, PORTMUX_PULL_UP);
00106 break;
00107 default:
00108 portmux_error_bad_id("USART", id);
00109 break;
00110 }
00111 }
00112
00113 extern void portmux_enable_usart_noninline(unsigned int id,
00114 unsigned long flags, unsigned long drive_strength);
00115
00125 static inline void portmux_enable_usart(unsigned int id,
00126 unsigned long flags, unsigned long drive_strength)
00127 {
00128 if (is_constant(id))
00129 portmux_enable_usart_inline(id, flags, drive_strength);
00130 else
00131 portmux_enable_usart_noninline(id, flags, drive_strength);
00132 }
00133
00134 #define PORTMUX_TWI_ALERT (1 << 0)
00135
00136 static inline void portmux_enable_twi(unsigned int id, unsigned long flags)
00137 {
00138 switch (id) {
00139 case 0:
00140 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 25 | 1 << 26,
00141 PORTMUX_FUNC_A, 0);
00142 if (flags & PORTMUX_TWI_ALERT)
00143 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 14,
00144 PORTMUX_FUNC_B, 0);
00145 break;
00146
00147 case 1:
00148 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 14 | 1 << 15,
00149 PORTMUX_FUNC_C, 0);
00150 if (flags & PORTMUX_TWI_ALERT)
00151 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 25,
00152 PORTMUX_FUNC_B, 0);
00153 break;
00154
00155 default:
00156 portmux_error_bad_id("TWI", id);
00157 break;
00158 }
00159 }
00160
00161 #define PORTMUX_USBB_ID (1 << 0)
00162 #define PORTMUX_USBB_VBOF (1 << 1)
00163
00164
00171 static inline void portmux_enable_usbb(unsigned long flags)
00172 {
00173 if (flags & PORTMUX_USBB_ID)
00174 portmux_select_peripheral(PORTMUX_PORT_B, 1 << 5,
00175 PORTMUX_FUNC_A, PORTMUX_PULL_UP);
00176
00177 if (flags & PORTMUX_USBB_VBOF)
00178 portmux_select_peripheral(PORTMUX_PORT_B, 1 << 6,
00179 PORTMUX_FUNC_A, 0);
00180 }
00181
00182 #define PORTMUX_MMCI_4BIT (1 << 0)
00183 #define PORTMUX_MMCI_8BIT (PORTMUX_MMCI_4BIT | (1 << 1))
00184 #define PORTMUX_MMCI_EXT_PULLUP (1 << 2)
00185
00186 static inline void portmux_enable_mmci(unsigned int id, unsigned int slot,
00187 unsigned long flags, unsigned long drive_strength)
00188 {
00189 unsigned long mask_a, mask_b;
00190 unsigned long portmux_flags = drive_strength | PORTMUX_PULL_UP;
00191
00192 if (id != 0) {
00193 portmux_error_bad_id("MMCI", id);
00194 return;
00195 }
00196
00197 if (flags & PORTMUX_MMCI_EXT_PULLUP)
00198 portmux_flags = drive_strength;
00199
00200 switch (slot) {
00201 case 0:
00202
00203 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 27,
00204 PORTMUX_FUNC_A, drive_strength);
00205
00206 mask_a = (1 << 28) | (1 << 29);
00207 mask_b = 0;
00208 if (flags & PORTMUX_MMCI_4BIT) {
00209
00210 mask_a |= (1 << 30) | (1 << 31);
00211
00212 mask_b |= 1 << 0;
00213 }
00214 if (flags & PORTMUX_MMCI_8BIT)
00215
00216 mask_b |= (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
00217
00218 portmux_select_peripheral(PORTMUX_PORT_A, mask_a,
00219 PORTMUX_FUNC_A, portmux_flags);
00220
00221 portmux_select_peripheral(PORTMUX_PORT_B, mask_b,
00222 PORTMUX_FUNC_A, portmux_flags);
00223 break;
00224
00225 case 1:
00226
00227 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 27,
00228 PORTMUX_FUNC_A, drive_strength);
00229
00230 mask_a = (1 << 15) | (1 << 19);
00231 mask_b = 0;
00232 if (flags & PORTMUX_MMCI_4BIT)
00233
00234 mask_a |= (1 << 18) | (1 << 17) | (1 << 16);
00235
00236 portmux_select_peripheral(PORTMUX_PORT_A, mask_a,
00237 PORTMUX_FUNC_A, portmux_flags);
00238 break;
00239 }
00240 }
00241
00242 static inline void portmux_enable_spi_inline(unsigned int id,
00243 unsigned long drive_strength)
00244 {
00245 switch (id) {
00246 case 0:
00247
00248 portmux_select_peripheral(PORTMUX_PORT_A,
00249 (1 << 8) | (1 << 10),
00250 PORTMUX_FUNC_A, drive_strength);
00251
00252
00253 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 11,
00254 PORTMUX_FUNC_A,
00255 drive_strength | PORTMUX_BUSKEEPER);
00256 break;
00257 case 1:
00258
00259 portmux_select_peripheral(PORTMUX_PORT_A,
00260 (1 << 15) | (1 << 16),
00261 PORTMUX_FUNC_B, drive_strength);
00262
00263
00264 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 19,
00265 PORTMUX_FUNC_B,
00266 drive_strength | PORTMUX_BUSKEEPER);
00267 break;
00268 default:
00269 portmux_error_bad_id("SPI", id);
00270 break;
00271 }
00272 }
00273
00274 extern void portmux_enable_spi_noninline(unsigned int id,
00275 unsigned long drive_strength);
00276
00283 static inline void portmux_enable_spi(unsigned int id,
00284 unsigned long drive_strength)
00285 {
00286 if (is_constant(id))
00287 portmux_enable_spi_inline(id, drive_strength);
00288 else
00289 portmux_enable_spi_noninline(id, drive_strength);
00290 }
00291
00292 #endif