2 Copyright � 2013, The AROS Development Team. All rights reserved.
7 #include <aros/debug.h>
9 #include <aros/bootloader.h>
10 #include <aros/symbolsets.h>
11 #include <exec/exec.h>
12 #include <exec/resident.h>
13 #include <exec/tasks.h>
14 #include <exec/memory.h>
15 #include <exec/nodes.h>
16 #include <utility/utility.h>
17 #include <libraries/expansion.h>
18 #include <libraries/configvars.h>
20 #include <dos/dosextens.h>
21 #include <dos/filehandler.h>
23 #include <proto/exec.h>
24 #include <proto/timer.h>
25 #include <proto/bootloader.h>
26 #include <proto/expansion.h>
27 #include <proto/kernel.h>
29 #include <hardware/mmc.h>
30 #include <hardware/sdhc.h>
35 #include "sdcard_base.h"
36 #include "sdcard_bus.h"
37 #include "sdcard_unit.h"
40 #include LC_LIBDEFS_FILE
42 BOOL
FNAME_SDC(RegisterBus
)(struct sdcard_Bus
*bus
, LIBBASETYPEPTR LIBBASE
)
44 DINIT(bug("[SDCard--] %s(0x%p)\n", __PRETTY_FUNCTION__
, bus
));
46 ObtainSemaphore(&LIBBASE
->sdcard_BusSem
);
47 AddTail(&LIBBASE
->sdcard_Buses
, (struct Node
*)bus
);
48 ReleaseSemaphore(&LIBBASE
->sdcard_BusSem
);
54 * Libinit functions -:
55 * 0: FNAME_SDC(CommonInit) -> common libbase init.
56 * 10: FNAME_SDC(XXXInit) -> chipset/implementation specific bus init.
57 * 120: FNAME_SDC(Scan) -> Scan registered buses for units.
59 static int FNAME_SDC(Scan
)(LIBBASETYPEPTR LIBBASE
)
61 struct sdcard_Bus
*busCurrent
;
64 DINIT(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
66 ForeachNode(&LIBBASE
->sdcard_Buses
, busCurrent
)
69 if ((sdcBusTaskName
= AllocVec(24, MEMF_PUBLIC
)) != NULL
)
71 if (busCurrent
->sdcb_LEDCtrl
)
72 busCurrent
->sdcb_LEDCtrl(LED_OFF
);
74 busCurrent
->sdcb_IntrMask
= SDHCI_INT_BUS_POWER
| SDHCI_INT_DATA_END_BIT
|
75 SDHCI_INT_DATA_CRC
| SDHCI_INT_DATA_TIMEOUT
| SDHCI_INT_INDEX
|
76 SDHCI_INT_END_BIT
| SDHCI_INT_CRC
| SDHCI_INT_TIMEOUT
|
77 SDHCI_INT_CARD_REMOVE
| SDHCI_INT_CARD_INSERT
|
78 SDHCI_INT_DATA_AVAIL
| SDHCI_INT_SPACE_AVAIL
|
79 SDHCI_INT_DATA_END
| SDHCI_INT_RESPONSE
;
81 FNAME_SDCBUS(SetClock
)(busCurrent
->sdcb_ClockMin
, busCurrent
);
83 FNAME_SDCBUS(SetPowerLevel
)(busCurrent
->sdcb_Power
, FALSE
, busCurrent
);
85 sdcReg
= busCurrent
->sdcb_IOReadByte(SDHCI_HOST_CONTROL
, busCurrent
);
86 DINIT(bug("[SDCard--] %s: Setting Min Buswidth... [%x -> %x]\n", __PRETTY_FUNCTION__
, sdcReg
, sdcReg
& ~(SDHCI_HCTRL_8BITBUS
|SDHCI_HCTRL_4BITBUS
|SDHCI_HCTRL_HISPD
)));
87 sdcReg
&= ~(SDHCI_HCTRL_8BITBUS
|SDHCI_HCTRL_4BITBUS
|SDHCI_HCTRL_HISPD
);
88 busCurrent
->sdcb_IOWriteByte(SDHCI_HOST_CONTROL
, sdcReg
, busCurrent
);
90 DINIT(bug("[SDCard--] %s: Launching Bus Task...\n", __PRETTY_FUNCTION__
));
92 sprintf(sdcBusTaskName
, "SDCard bus:%02u Subsystem", busCurrent
->sdcb_BusNum
);
95 TASKTAG_PC
, FNAME_SDCBUS(BusTask
),
96 TASKTAG_NAME
, sdcBusTaskName
,
97 TASKTAG_STACKSIZE
, SDCARD_BUSTASKSTACK
,
98 TASKTAG_PRI
, SDCARD_BUSTASKPRI
,
99 TASKTAG_TASKMSGPORT
, &busCurrent
->sdcb_MsgPort
,
100 TASKTAG_ARG1
, busCurrent
,
108 static int FNAME_SDC(CommonInit
)(LIBBASETYPEPTR LIBBASE
)
110 DINIT(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
112 if ((ExpansionBase
= OpenLibrary("expansion.library", 40L)) == NULL
)
114 bug("[SDCard--] %s: Failed to open expansion.library\n", __PRETTY_FUNCTION__
);
118 if ((KernelBase
= OpenResource("kernel.resource")) == NULL
)
120 bug("[SDCard--] %s: Failed to open kernel.resource\n", __PRETTY_FUNCTION__
);
124 if ((LIBBASE
->sdcard_MemPool
= CreatePool(MEMF_CLEAR
| MEMF_PUBLIC
| MEMF_SEM_PROTECTED
, 8192, 4096)) == NULL
)
126 bug("[SDCard--] %s: Failed to Allocate MemPool\n", __PRETTY_FUNCTION__
);
130 DINIT(bug("[SDCard--] %s: MemPool @ %p\n", __PRETTY_FUNCTION__
, LIBBASE
->sdcard_MemPool
));
132 InitSemaphore(&LIBBASE
->sdcard_BusSem
);
133 NEWLIST(&LIBBASE
->sdcard_Buses
);
138 if (ExpansionBase
) CloseLibrary(ExpansionBase
);
143 static int FNAME_SDC(Open
)
145 LIBBASETYPEPTR LIBBASE
,
146 struct IORequest
*iorq
,
151 struct sdcard_Bus
*busCurrent
;
153 DDEV(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
155 /* Assume it failed */
156 iorq
->io_Error
= IOERR_OPENFAIL
;
158 ForeachNode(&LIBBASE
->sdcard_Buses
, busCurrent
)
160 if ((unitnum
< (busCurrent
->sdcb_BusUnits
->sdcbu_UnitBase
+ busCurrent
->sdcb_BusUnits
->sdcbu_UnitCnt
)) && ((&busCurrent
->sdcb_BusUnits
->sdcbu_Units
)[unitnum
] != NULL
))
162 iorq
->io_Unit
= (struct Unit
*)(&busCurrent
->sdcb_BusUnits
->sdcbu_Units
)[unitnum
];
163 ((struct sdcard_Unit
*)iorq
->io_Unit
)->sdcu_Unit
.unit_OpenCnt
++;
167 if (!(((struct sdcard_Unit
*)iorq
->io_Unit
)->sdcu_Flags
& AF_Card_Active
))
169 if (FNAME_SDCBUS(StartUnit
)((struct sdcard_Unit
*)iorq
->io_Unit
))
171 DDEV(bug("[SDCard%02ld] %s: Unit @ 0x%p configured for operation\n", ((struct sdcard_Unit
*)iorq
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
, iorq
->io_Unit
));
172 ((struct sdcard_Unit
*)iorq
->io_Unit
)->sdcu_Flags
|= AF_Card_Active
;
176 DDEV(bug("[SDCard%02ld] %s: Failed to configure unit\n", ((struct sdcard_Unit
*)iorq
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
181 return iorq
->io_Error
? FALSE
: TRUE
;
184 /* Close given device */
185 static int FNAME_SDC(Close
)
187 LIBBASETYPEPTR LIBBASE
,
188 struct IORequest
*iorq
191 struct sdcard_Unit
*unit
= (struct sdcard_Unit
*)iorq
->io_Unit
;
193 DDEV(bug("[SDCard--] %s()\n", __PRETTY_FUNCTION__
));
195 /* First of all make the important fields of struct IORequest invalid! */
196 iorq
->io_Unit
= (struct Unit
*)~0;
198 /* Decrease use counters of unit */
199 unit
->sdcu_Unit
.unit_OpenCnt
--;
204 ADD2INITLIB(FNAME_SDC(CommonInit
), 0)
205 ADD2INITLIB(FNAME_SDC(Scan
), 127)
206 ADD2OPENDEV(FNAME_SDC(Open
), 0)
207 ADD2CLOSEDEV(FNAME_SDC(Close
), 0)