8#include "irx_imports.h"
10static u32 mmce_sio2_port_ctrl1;
11static u32 mmce_sio2_port_ctrl2;
13static inline void delay_us(
int us)
15 for (
int i = 0; i < us; i++) {
16 for (
int j = 0; j < 36; j++) {
22static int mmce_sio2_tx_rx_pio(
int port, u8 tx_size, u8 rx_size, u8 *tx_buf, u8 *rx_buf)
25 inl_sio2_ctrl_set(0xBC);
29 TR_CTRL_PORT_NR(port) |
31 TR_CTRL_TX_MODE_PIO_DMA(0) |
32 TR_CTRL_RX_MODE_PIO_DMA(0) |
33 TR_CTRL_NORMAL_TR(1) |
34 TR_CTRL_SPECIAL_TR(0) |
36 TR_CTRL_WAIT_ACK_FOREVER(0) |
37 TR_CTRL_TX_DATA_SZ(tx_size) |
38 TR_CTRL_RX_DATA_SZ(rx_size));
41 for (
int i = 0; i < tx_size; i++) {
42 inl_sio2_data_out(tx_buf[i]);
46 inl_sio2_ctrl_set(0xB1);
49 while ((inl_sio2_stat6c_get() & (1 << 12)) == 0) {
55 if ((inl_sio2_stat6c_get() & 0x8000) != 0)
59 for (
int i = 0; i < rx_size; i++) {
60 rx_buf[i] = inl_sio2_data_in();
66static int cmd_get_status(
int port)
74 wrbuf[0x1] = MMCE_CMD_GET_STATUS;
75 wrbuf[0x2] = MMCE_RESERVED;
77 res = mmce_sio2_tx_rx_pio(port,
sizeof(wrbuf),
sizeof(rdbuf), wrbuf, rdbuf);
81 if (rdbuf[0x1] == MMCE_REPLY_CONST)
82 res = rdbuf[0x3] << 8 | rdbuf[0x4];
89static int cmd_set_card(
int port, u8 type, u8 mode, u16 num)
97 wrbuf[0x1] = MMCE_CMD_SET_CARD;
98 wrbuf[0x2] = MMCE_RESERVED;
101 wrbuf[0x5] = num >> 8;
102 wrbuf[0x6] = num & 0xFF;
104 res = mmce_sio2_tx_rx_pio(port,
sizeof(wrbuf),
sizeof(rdbuf), wrbuf, rdbuf);
108 if (rdbuf[0x1] != MMCE_REPLY_CONST)
114int _start(
int argc,
char *argv[])
120 return MODULE_NO_RESIDENT_END;
122 if (argv[1][0] ==
'1')
125 if (argv[1][1] ==
'1')
128 mmce_sio2_port_ctrl1 =
129 PCTRL0_ATT_LOW_PER(0x5) |
130 PCTRL0_ATT_MIN_HIGH_PER(0x0) |
131 PCTRL0_BAUD0_DIV(0x2) |
132 PCTRL0_BAUD1_DIV(0xff);
134 mmce_sio2_port_ctrl2 =
135 PCTRL1_ACK_TIMEOUT_AFTER(0xffff) |
136 PCTRL1_WAIT_CYCLES_AFTER_ACK_LOW(0x5) |
138 PCTRL1_IF_MODE_SPI_DIFF(0x0);
140 u32 sio2_state = inl_sio2_ctrl_get();
142 for (
int i = 0; i < 2; i++) {
145 inl_sio2_portN_ctrl1_set(i + 2, mmce_sio2_port_ctrl1);
146 inl_sio2_portN_ctrl2_set(i + 2, mmce_sio2_port_ctrl2);
149 res = cmd_set_card(i + 2, 1, 0, 0);
152 for (
int j = 0; j < 15; j++) {
155 res = cmd_get_status(i + 2);
166 inl_sio2_ctrl_set(sio2_state | 0xc);
168 return MODULE_NO_RESIDENT_END;