Added a variant of the Test script that allows running arbitrary
[AROS.git] / rom / devs / sdcard / sdcard_sdscunit.c
blob32b55baee9d2cb6b7612c3ce2f980c5976452258
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <hardware/mmc.h>
10 #include <hardware/sdhc.h>
12 #include "sdcard_base.h"
13 #include "sdcard_bus.h"
14 #include "sdcard_unit.h"
16 ULONG FNAME_SDCUNIT(SDSCSwitch)(BOOL test, int group, UBYTE value, APTR buf, struct sdcard_Unit *sdcUnit)
18 struct TagItem sdcSwitchTags[] =
20 {SDCARD_TAG_CMD, SD_CMD_SWITCH_FUNC},
21 {SDCARD_TAG_ARG, 0},
22 {SDCARD_TAG_RSPTYPE, MMC_RSP_R1},
23 {SDCARD_TAG_RSP, 0},
24 {SDCARD_TAG_DATA, (IPTR)buf},
25 {SDCARD_TAG_DATALEN, 64},
26 {SDCARD_TAG_DATAFLAGS, MMC_DATA_READ},
27 {TAG_DONE, 0}
29 ULONG retVal;
31 D(bug("[SDCard%02ld] %s()\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
33 sdcSwitchTags[1].ti_Data = ((test) ? 0 : (1 << 31)) | 0xFFFFFF;
34 sdcSwitchTags[1].ti_Data &= ~(0xF << (group * 4));
35 sdcSwitchTags[1].ti_Data |= value << (group * 4);
37 if ((retVal = FNAME_SDCBUS(SendCmd)(sdcSwitchTags, sdcUnit->sdcu_Bus)) != -1)
39 retVal = FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, sdcUnit->sdcu_Bus);
41 return retVal;
44 ULONG FNAME_SDCUNIT(SDSCChangeFrequency)(struct sdcard_Unit *sdcUnit)
46 unsigned int timeout;
47 ULONG sdcRespBuf[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
48 struct TagItem sdcChFreqTags[] =
50 {SDCARD_TAG_CMD, 0},
51 {SDCARD_TAG_ARG, 0},
52 {SDCARD_TAG_RSPTYPE, 0},
53 {SDCARD_TAG_RSP, 0},
54 {0, (IPTR)sdcRespBuf}, /* SDCARD_TAG_DATA */
55 {SDCARD_TAG_DATALEN, 8},
56 {SDCARD_TAG_DATAFLAGS, MMC_DATA_READ},
57 {TAG_DONE, 0}
60 D(bug("[SDCard%02ld] %s()\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
62 /* Read the SCR to find out if higher speeds are supported ..*/
63 timeout = 3;
64 do {
65 D(bug("[SDCard%02ld] %s: Preparing for Card App Command ... \n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
66 sdcChFreqTags[0].ti_Data = MMC_CMD_APP_CMD;
67 sdcChFreqTags[1].ti_Data = sdcUnit->sdcu_CardRCA << 16;
68 sdcChFreqTags[2].ti_Data = MMC_RSP_R1;
69 sdcChFreqTags[4].ti_Tag = TAG_DONE;
71 if ((FNAME_SDCBUS(SendCmd)(sdcChFreqTags, sdcUnit->sdcu_Bus) == -1) || (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, sdcUnit->sdcu_Bus) == -1))
73 D(bug("[SDCard%02ld] %s: App Command Failed\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
74 return -1;
76 D(bug("[SDCard%02ld] %s: App Command Response = %08x\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcChFreqTags[3].ti_Data));
78 sdcChFreqTags[0].ti_Data = SD_CMD_APP_SEND_SCR;
79 sdcChFreqTags[1].ti_Data = 0;
80 sdcChFreqTags[2].ti_Data = MMC_RSP_R1;
81 sdcChFreqTags[4].ti_Tag = SDCARD_TAG_DATA;
83 D(bug("[SDCard%02ld] %s: Querying SCR Register ... \n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
84 if ((FNAME_SDCBUS(SendCmd)(sdcChFreqTags, sdcUnit->sdcu_Bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT|SDHCI_PS_DATA_INHIBIT, 10000, sdcUnit->sdcu_Bus) != -1))
86 D(bug("[SDCard%02ld] %s: Query Response = %08x\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcChFreqTags[3].ti_Data));
87 break;
89 } while (--timeout > 0);
91 if (timeout > 0)
93 if (AROS_BE2LONG(sdcRespBuf[0]) & SD_SCR_DATA4BIT)
94 sdcUnit->sdcu_Flags |= AF_Card_4bitData;
96 /* v1.0 SDCards don't support switching */
97 if (((AROS_BE2LONG(sdcRespBuf[0]) >> 24) & 0xf) < 1)
99 D(bug("[SDCard%02ld] %s: Card doesnt support Switching\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
100 return 0;
103 timeout = 4;
104 while (--timeout > 0) {
105 if (FNAME_SDCUNIT(SDSCSwitch)(TRUE, 0, 1, sdcRespBuf, sdcUnit) != -1)
107 /* The high-speed function is busy. Try again */
108 if (!(AROS_BE2LONG(sdcRespBuf[7]) & SD_SCR_HIGHSPEED))
109 break;
111 else
113 D(bug("[SDCard%02ld] %s: Switch failed\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
114 return -1;
118 if (timeout > 0)
120 /* Is high-speed supported? */
121 if (!(AROS_BE2LONG(sdcRespBuf[3]) & SD_SCR_HIGHSPEED))
123 D(bug("[SDCard%02ld] %s: Card doesnt support Highspeed mode\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
124 return 0;
127 if (FNAME_SDCUNIT(SDSCSwitch)(FALSE, 0, 1, sdcRespBuf, sdcUnit) != -1)
129 if ((AROS_BE2LONG(sdcRespBuf[4]) & 0x0F000000) == 0x01000000)
130 sdcUnit->sdcu_Flags |= AF_Card_HighSpeed;
134 else
136 D(bug("[SDCard%02ld] %s: Timeout Querying SCR\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
137 return -1;
140 return 0;