2 Copyright © 2013, The AROS Development Team. All rights reserved.
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
},
22 {SDCARD_TAG_RSPTYPE
, MMC_RSP_R1
},
24 {SDCARD_TAG_DATA
, (IPTR
)buf
},
25 {SDCARD_TAG_DATALEN
, 64},
26 {SDCARD_TAG_DATAFLAGS
, MMC_DATA_READ
},
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
|SDHCI_PS_DATA_INHIBIT
, 1000, sdcUnit
->sdcu_Bus
);
44 ULONG
FNAME_SDCUNIT(SDSCChangeFrequency
)(struct sdcard_Unit
*sdcUnit
)
47 ULONG sdcRespBuf
[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
48 struct TagItem sdcChFreqTags
[] =
52 {SDCARD_TAG_RSPTYPE
, 0},
54 {0, (IPTR
)sdcRespBuf
}, /* SDCARD_TAG_DATA */
55 {SDCARD_TAG_DATALEN
, 8},
56 {SDCARD_TAG_DATAFLAGS
, MMC_DATA_READ
},
60 D(bug("[SDCard%02ld] %s()\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
62 /* Read the SCR to find out if higher speeds are supported ..*/
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
|SDHCI_PS_DATA_INHIBIT
, 1000, sdcUnit
->sdcu_Bus
) == -1))
73 D(bug("[SDCard%02ld] %s: App Command Failed\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
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
));
89 } while (--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__
));
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
))
113 D(bug("[SDCard%02ld] %s: Switch failed\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
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__
));
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
;
136 D(bug("[SDCard%02ld] %s: Timeout Querying SCR\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));