1# MMC<a name="EN-US_TOPIC_0000001153669000"></a> 2 3## Overview<a name="section1846388309162704"></a> 4 5In the Hardware Driver Foundation \(HDF\) framework, the MultiMedia Card \(MMC\) uses the independent service mode for API adaptation. In this mode, each device independently publishes a device service to handle external access requests. After receiving an access request from an API, the device manager extracts the parameters in the request to call the internal method of the target device. In the independent service mode, the service management capabilities of the HDFDeviceManager can be directly used. However, you need to configure a device node for each device, which increases the memory usage. 6 7**Figure 1** Independent service mode<a name="fig19517114132810"></a> 8 9 10## Available APIs<a name="section752964871810"></a> 11 12MmcCntlrOps 13 14``` 15struct MmcCntlrOps { 16 int32_t (*request)(struct MmcCntlr *cntlr, struct MmcCmd *cmd); 17 int32_t (*setClock)(struct MmcCntlr *cntlr, uint32_t clock); 18 int32_t (*setPowerMode)(struct MmcCntlr *cntlr, enum MmcPowerMode mode); 19 int32_t (*setBusWidth)(struct MmcCntlr *cntlr, enum MmcBusWidth width); 20 int32_t (*setBusTiming)(struct MmcCntlr *cntlr, enum MmcBusTiming timing); 21 int32_t (*setSdioIrq)(struct MmcCntlr *cntlr, bool enable); 22 int32_t (*hardwareReset)(struct MmcCntlr *cntlr); 23 int32_t (*systemInit)(struct MmcCntlr *cntlr); 24 int32_t (*setEnhanceSrobe)(struct MmcCntlr *cntlr, bool enable); 25 int32_t (*switchVoltage)(struct MmcCntlr *cntlr, enum MmcVolt volt); 26 bool (*devReadOnly)(struct MmcCntlr *cntlr); 27 bool (*devPluged)(struct MmcCntlr *cntlr); 28 bool (*devBusy)(struct MmcCntlr *cntlr); 29 int32_t (*tune)(struct MmcCntlr *cntlr, uint32_t cmdCode); 30 int32_t (*rescanSdioDev)(struct MmcCntlr *cntlr); 31}; 32``` 33 34**Table 1** Callbacks for the members in the MmcCntlrOps structure 35 36<a name="table99129433019"></a> 37<table><thead align="left"><tr id="row1891214163012"><th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.1"><p id="p79129483017"><a name="p79129483017"></a><a name="p79129483017"></a>Callback</p> 38</th> 39<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.2"><p id="p1591213403019"><a name="p1591213403019"></a><a name="p1591213403019"></a>Input Parameter</p> 40</th> 41<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.3"><p id="p491312483012"><a name="p491312483012"></a><a name="p491312483012"></a>Return Value</p> 42</th> 43<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.4"><p id="p8913144203017"><a name="p8913144203017"></a><a name="p8913144203017"></a>Description</p> 44</th> 45</tr> 46</thead> 47<tbody><tr id="row4913844307"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p17913149309"><a name="p17913149309"></a><a name="p17913149309"></a>doRequest</p> 48</td> 49<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p359655512340"><a name="p359655512340"></a><a name="p359655512340"></a><strong id="b1596155533411"><a name="b1596155533411"></a><a name="b1596155533411"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 50<p id="p159131449308"><a name="p159131449308"></a><a name="p159131449308"></a><strong id="b71781053113715"><a name="b71781053113715"></a><a name="b71781053113715"></a>cmd</strong>: structure pointer to the input command.</p> 51</td> 52<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1291519413308"><a name="p1291519413308"></a><a name="p1291519413308"></a>HDF_STATUS</p> 53</td> 54<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p3915048309"><a name="p3915048309"></a><a name="p3915048309"></a>Processes the request.</p> 55</td> 56</tr> 57<tr id="row17915124113014"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p69152416307"><a name="p69152416307"></a><a name="p69152416307"></a>setClock</p> 58</td> 59<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p12397758163416"><a name="p12397758163416"></a><a name="p12397758163416"></a><strong id="b2397155816345"><a name="b2397155816345"></a><a name="b2397155816345"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 60<p id="p119153413013"><a name="p119153413013"></a><a name="p119153413013"></a><strong id="b13651101617393"><a name="b13651101617393"></a><a name="b13651101617393"></a>clock</strong>: input clock value.</p> 61</td> 62<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p79153417302"><a name="p79153417302"></a><a name="p79153417302"></a>HDF_STATUS</p> 63</td> 64<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1291614183010"><a name="p1291614183010"></a><a name="p1291614183010"></a>Sets the clock frequency.</p> 65</td> 66</tr> 67<tr id="row19168433011"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1391614416305"><a name="p1391614416305"></a><a name="p1391614416305"></a>setPowerMode</p> 68</td> 69<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p349710303139"><a name="p349710303139"></a><a name="p349710303139"></a><strong id="b749713013132"><a name="b749713013132"></a><a name="b749713013132"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 70<p id="p99161341305"><a name="p99161341305"></a><a name="p99161341305"></a><strong id="b1355614134405"><a name="b1355614134405"></a><a name="b1355614134405"></a>mode</strong>: power consumption mode. It is an enumerated value (see MmcPowerMode).</p> 71</td> 72<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1091674183020"><a name="p1091674183020"></a><a name="p1091674183020"></a>HDF_STATUS</p> 73</td> 74<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1191617420307"><a name="p1191617420307"></a><a name="p1191617420307"></a>Sets the power consumption mode.</p> 75</td> 76</tr> 77<tr id="row291620463018"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p291612453018"><a name="p291612453018"></a><a name="p291612453018"></a>setBusWidth</p> 78</td> 79<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p52591598350"><a name="p52591598350"></a><a name="p52591598350"></a><strong id="b225999203512"><a name="b225999203512"></a><a name="b225999203512"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 80<p id="p11916245309"><a name="p11916245309"></a><a name="p11916245309"></a><strong id="b24742024134111"><a name="b24742024134111"></a><a name="b24742024134111"></a>width</strong>: bus width. It is an enumerated value (see MmcBusWidth).</p> 81</td> 82<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1491610415305"><a name="p1491610415305"></a><a name="p1491610415305"></a>HDF_STATUS</p> 83</td> 84<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p19916147304"><a name="p19916147304"></a><a name="p19916147304"></a>Sets the bus width.</p> 85</td> 86</tr> 87<tr id="row1916742301"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p3916104143014"><a name="p3916104143014"></a><a name="p3916104143014"></a>setBusTiming</p> 88</td> 89<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p109861912123517"><a name="p109861912123517"></a><a name="p109861912123517"></a><strong id="b39864125357"><a name="b39864125357"></a><a name="b39864125357"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 90<p id="p591710419302"><a name="p591710419302"></a><a name="p591710419302"></a><strong id="b1067164920426"><a name="b1067164920426"></a><a name="b1067164920426"></a>timing</strong>: bus timing. It is an enumerated value (see MmcBusTiming).</p> 91</td> 92<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p14917154123017"><a name="p14917154123017"></a><a name="p14917154123017"></a>HDF_STATUS</p> 93</td> 94<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1991814443016"><a name="p1991814443016"></a><a name="p1991814443016"></a>Sets the bus timing.</p> 95</td> 96</tr> 97<tr id="row199186423012"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p991810414305"><a name="p991810414305"></a><a name="p991810414305"></a>setSdioIrq</p> 98</td> 99<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p207324169351"><a name="p207324169351"></a><a name="p207324169351"></a><strong id="b11731716183510"><a name="b11731716183510"></a><a name="b11731716183510"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 100<p id="p16918844305"><a name="p16918844305"></a><a name="p16918844305"></a><strong id="b49304428454"><a name="b49304428454"></a><a name="b49304428454"></a>enable</strong>: specifies whether to enable interrupt.</p> 101</td> 102<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p17918204193011"><a name="p17918204193011"></a><a name="p17918204193011"></a>HDF_STATUS</p> 103</td> 104<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1191813416305"><a name="p1191813416305"></a><a name="p1191813416305"></a>Enables or disables Secure Digital Input Output (SDIO) interrupt.</p> 105</td> 106</tr> 107<tr id="row139181453012"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p491874193011"><a name="p491874193011"></a><a name="p491874193011"></a>hardwareReset</p> 108</td> 109<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p12918114163011"><a name="p12918114163011"></a><a name="p12918114163011"></a><strong id="b127774583476"><a name="b127774583476"></a><a name="b127774583476"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 110</td> 111<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p4918244309"><a name="p4918244309"></a><a name="p4918244309"></a>HDF_STATUS</p> 112</td> 113<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p11919243306"><a name="p11919243306"></a><a name="p11919243306"></a>Resets hardware.</p> 114</td> 115</tr> 116<tr id="row169195410309"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p89191746303"><a name="p89191746303"></a><a name="p89191746303"></a>systemInit</p> 117</td> 118<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p8919441302"><a name="p8919441302"></a><a name="p8919441302"></a><strong id="b296543474814"><a name="b296543474814"></a><a name="b296543474814"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 119</td> 120<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p199191941307"><a name="p199191941307"></a><a name="p199191941307"></a>HDF_STATUS</p> 121</td> 122<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p391919473014"><a name="p391919473014"></a><a name="p391919473014"></a>Performs system initialization.</p> 123</td> 124</tr> 125<tr id="row159191423012"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p189194417307"><a name="p189194417307"></a><a name="p189194417307"></a>setEnhanceSrobe</p> 126</td> 127<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p684922173510"><a name="p684922173510"></a><a name="p684922173510"></a><strong id="b1184122212354"><a name="b1184122212354"></a><a name="b1184122212354"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 128<p id="p1191910419304"><a name="p1191910419304"></a><a name="p1191910419304"></a><strong id="b17674159184914"><a name="b17674159184914"></a><a name="b17674159184914"></a>enable</strong>: specifies whether to enable the enhanced strobe feature.</p> 129</td> 130<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p69194473011"><a name="p69194473011"></a><a name="p69194473011"></a>HDF_STATUS</p> 131</td> 132<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p091904143019"><a name="p091904143019"></a><a name="p091904143019"></a>Sets the enhanced strobe feature.</p> 133</td> 134</tr> 135<tr id="row109197416305"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p791917443010"><a name="p791917443010"></a><a name="p791917443010"></a>switchVoltage</p> 136</td> 137<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p180311317351"><a name="p180311317351"></a><a name="p180311317351"></a><strong id="b2803231173514"><a name="b2803231173514"></a><a name="b2803231173514"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 138<p id="p1591912415304"><a name="p1591912415304"></a><a name="p1591912415304"></a><strong id="b5411538185218"><a name="b5411538185218"></a><a name="b5411538185218"></a>volt</strong>: voltage, which can be 3.3 V, 1.8 V, or 1.2 V. It is an enumerated value.</p> 139</td> 140<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p59196416307"><a name="p59196416307"></a><a name="p59196416307"></a>HDF_STATUS</p> 141</td> 142<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p169207416301"><a name="p169207416301"></a><a name="p169207416301"></a>Sets the voltage.</p> 143</td> 144</tr> 145<tr id="row1992015417301"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1892014463010"><a name="p1892014463010"></a><a name="p1892014463010"></a>devReadOnly</p> 146</td> 147<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p1392011411309"><a name="p1392011411309"></a><a name="p1392011411309"></a><strong id="b20848102414403"><a name="b20848102414403"></a><a name="b20848102414403"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 148</td> 149<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p89207418304"><a name="p89207418304"></a><a name="p89207418304"></a>Boolean</p> 150</td> 151<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p7920847301"><a name="p7920847301"></a><a name="p7920847301"></a>Checks whether the device is read-only.</p> 152</td> 153</tr> 154<tr id="row1092019483018"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1092034103011"><a name="p1092034103011"></a><a name="p1092034103011"></a>cardPluged</p> 155</td> 156<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p2920144123010"><a name="p2920144123010"></a><a name="p2920144123010"></a><strong id="b1685142434016"><a name="b1685142434016"></a><a name="b1685142434016"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 157</td> 158<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p2092014411305"><a name="p2092014411305"></a><a name="p2092014411305"></a>Boolean</p> 159</td> 160<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1892094153017"><a name="p1892094153017"></a><a name="p1892094153017"></a>Checks whether the device is removed.</p> 161</td> 162</tr> 163<tr id="row892018413013"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p39201146309"><a name="p39201146309"></a><a name="p39201146309"></a>devBusy</p> 164</td> 165<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p9920124193013"><a name="p9920124193013"></a><a name="p9920124193013"></a><strong id="b1885213240408"><a name="b1885213240408"></a><a name="b1885213240408"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 166</td> 167<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1992112419305"><a name="p1992112419305"></a><a name="p1992112419305"></a>Boolean</p> 168</td> 169<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p69211417302"><a name="p69211417302"></a><a name="p69211417302"></a>Checks whether the device is engaged.</p> 170</td> 171</tr> 172<tr id="row71064053613"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1511114015361"><a name="p1511114015361"></a><a name="p1511114015361"></a>tune</p> 173</td> 174<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p4972240153511"><a name="p4972240153511"></a><a name="p4972240153511"></a><strong id="b1997244017354"><a name="b1997244017354"></a><a name="b1997244017354"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 175<p id="p5116409364"><a name="p5116409364"></a><a name="p5116409364"></a><strong id="b2286168195617"><a name="b2286168195617"></a><a name="b2286168195617"></a>cmdCode</strong>: command code of the uint32_t type.</p> 176</td> 177<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p711440123610"><a name="p711440123610"></a><a name="p711440123610"></a>HDF_STATUS</p> 178</td> 179<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1411184011368"><a name="p1411184011368"></a><a name="p1411184011368"></a>Tunes</p> 180</td> 181</tr> 182<tr id="row1559214410366"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1559364493618"><a name="p1559364493618"></a><a name="p1559364493618"></a>rescanSdioDev</p> 183</td> 184<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p165931944133618"><a name="p165931944133618"></a><a name="p165931944133618"></a><strong id="b0854424164010"><a name="b0854424164010"></a><a name="b0854424164010"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> 185</td> 186<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p15593184493610"><a name="p15593184493610"></a><a name="p15593184493610"></a>HDF_STATUS</p> 187</td> 188<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p359384473615"><a name="p359384473615"></a><a name="p359384473615"></a>Scans and adds an SDIO device.</p> 189</td> 190</tr> 191</tbody> 192</table> 193 194## How to Develop<a name="section1617495117162704"></a> 195 196The MMC module adaptation involves the following steps: 197 1981. Instantiate the driver entry. 199 - Instantiate the **HdfDriverEntry** structure. 200 - Call **HDF\_INIT** to register the **HdfDriverEntry** instance with the HDF framework. 201 2022. Configure attribute files. 203 - Add the **deviceNode** information to the **device\_info.hcs** file. 204 - \(Optional\) Add the **mmc\_config.hcs** file. 205 2063. Instantiate the MMC controller object. 207 - Initialize **MmcCntlr**. 208 - Instantiate **MmcCntlrOps** in the **MmcCntlr** object. 209 210 > **NOTE** 211 212 >For details, see [Available APIs](#available-apis). 213 214 2154. Debug the driver. 216 - \(Optional\) For new drivers, verify basic functions, for example, verify the information returned after the mount operation and whether the device starts successfully. 217 218 219## Development Example<a name="section1220893490162704"></a> 220 221The following uses **himci.c** as an example to present the contents that need to be provided by the vendor to implement device functions. 222 2231. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type \(defined in **hdf\_device\_desc.h**\), and the value of **moduleName** must be the same as that in **device\_info.hcs**. In the HDF framework, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke. 224 225 Generally, HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, HDF calls **Release** to release driver resources and exit. 226 227 - MMC driver entry reference 228 229 ``` 230 struct HdfDriverEntry g_mmcDriverEntry = { 231 .moduleVersion = 1, 232 .Bind = HimciMmcBind, // See the Bind function. 233 .Init = HimciMmcInit, // See the Init function. 234 .Release = HimciMmcRelease, //See the Release function. 235 .moduleName = "hi3516_mmc_driver",// (Mandatory) The value must be the same as that of moduleName in the .hcs file. 236 }; 237 HDF_INIT(g_mmcDriverEntry); // Call HDF_INIT to register the driver entry with the HDF framework. 238 ``` 239 2402. Add the **deviceNode** information to the **device\_info.hcs** file and configure the device attributes in the **mmc\_config.hcs** file. The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **MmcCntlr** members at the core layer. 241 242 If there are multiple devices, you need to add the **deviceNode** information to the **device\_info** file and add the corresponding device attributes to the **mmc\_config** file. 243 244 - **device\_info.hcs** configuration reference 245 246 ``` 247 root { 248 device_info { 249 match_attr = "hdf_manager"; 250 platform :: host { 251 hostName = "platform_host"; 252 priority = 50; 253 device_mmc:: device { 254 device0 :: deviceNode { 255 policy = 2; 256 priority = 10; 257 permission = 0644; 258 moduleName = "hi3516_mmc_driver"; // (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. 259 serviceName = "HDF_PLATFORM_MMC_0"; // (Mandatory) Unique name of the service published by the driver 260 deviceMatchAttr = "hi3516_mmc_emmc";// (Mandatory) Used to configure the private data of the controller. The value must be the same as the controller in mmc_config.hcs. 261 } 262 device1 :: deviceNode { 263 policy = 1; 264 priority = 20; 265 permission = 0644; 266 moduleName = "hi3516_mmc_driver"; 267 serviceName = "HDF_PLATFORM_MMC_1"; 268 deviceMatchAttr = "hi3516_mmc_sd"; // Indicates an SD. 269 } 270 device2 :: deviceNode { 271 policy = 1; 272 priority = 30; 273 permission = 0644; 274 moduleName = "hi3516_mmc_driver"; 275 serviceName = "HDF_PLATFORM_MMC_2"; 276 deviceMatchAttr = "hi3516_mmc_sdio";// Indicates an SDIO. 277 } 278 } 279 } 280 } 281 } 282 ``` 283 284 - **mmc\_config.hcs** configuration reference 285 286 ``` 287 root { 288 platform { 289 mmc_config { 290 template mmc_controller {// Template configuration. In the template, you can configure the common parameters shared by service nodes. 291 match_attr = ""; 292 voltDef = 0; // 3.3V 293 freqMin = 50000; // (Mandatory) Minimum frequency 294 freqMax = 100000000; // (Mandatory) Maximum frequency 295 freqDef = 400000; // (Mandatory) Default frequency 296 maxBlkNum = 2048; // (Mandatory) Maximum block number 297 maxBlkSize = 512; // (Mandatory) Maximum number of blocks 298 ocrDef = 0x300000; // (Mandatory) Working voltage. 299 caps2 = 0; // (Mandatory) Attribute register. For details, see MmcCaps2 in mmc_caps.h. 300 regSize = 0x118; // (Mandatory) Register bit width 301 hostId = 0; // (Mandatory) Host ID 302 regBasePhy = 0x10020000;// (Mandatory) Physical base address of the register 303 irqNum = 63; // (Mandatory) Interrupt number 304 devType = 2; // (Mandatory) Device mode, which can be eMMC, SD, SDIO, or COMBO 305 caps = 0x0001e045; // (Mandatory) Attribute register. For details, see MmcCaps in mmc_caps.h. 306 } 307 controller_0x10100000 :: mmc_controller { 308 match_attr = "hi3516_mmc_emmc";// (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs. 309 hostId = 0; 310 regBasePhy = 0x10100000; 311 irqNum = 96; 312 devType = 0; // The value 0 indicates an eMMC. 313 caps = 0xd001e045; 314 caps2 = 0x60; 315 } 316 controller_0x100f0000 :: mmc_controller { 317 match_attr = "hi3516_mmc_sd"; 318 hostId = 1; 319 regBasePhy = 0x100f0000; 320 irqNum = 62; 321 devType = 1; // The value 1 indicates an SD card. 322 caps = 0xd001e005; 323 } 324 controller_0x10020000 :: mmc_controller { 325 match_attr = "hi3516_mmc_sdio"; 326 hostId = 2; 327 regBasePhy = 0x10020000; 328 irqNum = 63; 329 devType = 2; // The value 2 indicates an SDIO device. 330 caps = 0x0001e04d; 331 } 332 } 333 } 334 } 335 ``` 336 3373. Initialize the **MmcCntlr** object at the core layer, including initializing the vendor custom structure \(transferring parameters and data\), instantiating **MmcCntlrOps** \(used to call underlying functions of the driver\) in **MmcCntlr**, and implementing the **HdfDriverEntry** member functions \(**Bind**, **Init**, and **Release**\). 338 - Custom structure reference 339 340 To the driver, the custom structure carries parameters and data. The values in the **mmc\_config.hcs** file are read by the HDF, and the structure members are initialized through **DeviceResourceIface**. Some important values are also transferred to the objects at the core layer. 341 342 ``` 343 struct HimciHost { 344 struct MmcCntlr *mmc;// (Mandatory) Core layer structure 345 struct MmcCmd *cmd; // (Mandatory) Core layer structure used to transfer commands. For details about related commands, see MmcCmdCode. 346 //(Optional) Set parameters based on the vendor's requirements. 347 void *base; 348 enum HimciPowerStatus powerStatus; 349 uint8_t *alignedBuff; 350 uint32_t buffLen; 351 struct scatterlist dmaSg; 352 struct scatterlist *sg; 353 uint32_t dmaSgNum; 354 DMA_ADDR_T dmaPaddr; 355 uint32_t *dmaVaddr; 356 uint32_t irqNum; 357 bool isTuning; 358 uint32_t id; 359 struct OsalMutex mutex; 360 bool waitForEvent; 361 HIMCI_EVENT himciEvent; 362 }; 363 // MmcCntlr is the core layer controller structure. Its members are assigned with values by using the bind function. 364 struct MmcCntlr { 365 struct IDeviceIoService service; 366 struct HdfDeviceObject *hdfDevObj; 367 struct PlatformDevice device; 368 struct OsalMutex mutex; 369 struct OsalSem released; 370 uint32_t devType; 371 struct MmcDevice *curDev; 372 struct MmcCntlrOps *ops; 373 struct PlatformQueue *msgQueue; 374 uint16_t index; 375 uint16_t voltDef; 376 uint32_t vddBit; 377 uint32_t freqMin; 378 uint32_t freqMax; 379 uint32_t freqDef; 380 union MmcOcr ocrDef; 381 union MmcCaps caps; 382 union MmcCaps2 caps2; 383 uint32_t maxBlkNum; 384 uint32_t maxBlkSize; 385 uint32_t maxReqSize; 386 bool devPluged; 387 bool detecting; 388 void *priv; 389 }; 390 ``` 391 392 - Instantiate the callback function structure **MmcCntlrOps** in **MmcCntlr**. Other members are initialized by using the **Bind** function. 393 394 ``` 395 static struct MmcCntlrOps g_himciHostOps = { 396 .request = HimciDoRequest, 397 .setClock = HimciSetClock, 398 .setPowerMode = HimciSetPowerMode, 399 .setBusWidth = HimciSetBusWidth, 400 .setBusTiming = HimciSetBusTiming, 401 .setSdioIrq = HimciSetSdioIrq, 402 .hardwareReset = HimciHardwareReset, 403 .systemInit = HimciSystemInit, 404 .setEnhanceSrobe= HimciSetEnhanceSrobe, 405 .switchVoltage = HimciSwitchVoltage, 406 .devReadOnly = HimciDevReadOnly, 407 .devPluged = HimciCardPluged, 408 .devBusy = HimciDevBusy, 409 .tune = HimciTune, 410 .rescanSdioDev = HimciRescanSdioDev, 411 }; 412 ``` 413 414 - Bind function 415 416 Input parameters: 417 418 **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. 419 420 Return values: 421 422 HDF\_STATUS \(The following table lists some status. For details about other status, see **HDF\_STATUS** in the **//drivers/framework/include/utils/hdf\_base.h** file.\) 423 424 <a name="table1428218958162704"></a> 425 <table><thead align="left"><tr id="row1723943104162704"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="entry136979408162704p0"><a name="entry136979408162704p0"></a><a name="entry136979408162704p0"></a>Status (Value)</p> 426 </th> 427 <th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="entry1590766658162704p0"><a name="entry1590766658162704p0"></a><a name="entry1590766658162704p0"></a>Description</p> 428 </th> 429 </tr> 430 </thead> 431 <tbody><tr id="row408410040162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1337150412162704p0"><a name="entry1337150412162704p0"></a><a name="entry1337150412162704p0"></a>HDF_ERR_INVALID_OBJECT</p> 432 </td> 433 <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry2061632106162704p0"><a name="entry2061632106162704p0"></a><a name="entry2061632106162704p0"></a>Invalid controller object</p> 434 </td> 435 </tr> 436 <tr id="row160841211162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1173668571162704p0"><a name="entry1173668571162704p0"></a><a name="entry1173668571162704p0"></a>HDF_ERR_MALLOC_FAIL</p> 437 </td> 438 <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry74350097162704p0"><a name="entry74350097162704p0"></a><a name="entry74350097162704p0"></a>Failed to allocate memory</p> 439 </td> 440 </tr> 441 <tr id="row1596857798162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry190784255162704p0"><a name="entry190784255162704p0"></a><a name="entry190784255162704p0"></a>HDF_ERR_INVALID_PARAM</p> 442 </td> 443 <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1070501269162704p0"><a name="entry1070501269162704p0"></a><a name="entry1070501269162704p0"></a>Invalid parameter</p> 444 </td> 445 </tr> 446 <tr id="row1645995958162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry741922133162704p0"><a name="entry741922133162704p0"></a><a name="entry741922133162704p0"></a>HDF_ERR_IO</p> 447 </td> 448 <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry2094504256162704p0"><a name="entry2094504256162704p0"></a><a name="entry2094504256162704p0"></a>I/O error</p> 449 </td> 450 </tr> 451 <tr id="row733220922162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1177794681162704p0"><a name="entry1177794681162704p0"></a><a name="entry1177794681162704p0"></a>HDF_SUCCESS</p> 452 </td> 453 <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry540896959162704p0"><a name="entry540896959162704p0"></a><a name="entry540896959162704p0"></a>Initialization successful</p> 454 </td> 455 </tr> 456 <tr id="row1890064939162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry118676812162704p0"><a name="entry118676812162704p0"></a><a name="entry118676812162704p0"></a>HDF_FAILURE</p> 457 </td> 458 <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry2078272728162704p0"><a name="entry2078272728162704p0"></a><a name="entry2078272728162704p0"></a>Initialization failed</p> 459 </td> 460 </tr> 461 </tbody> 462 </table> 463 464 Function description: 465 466 Initializes the custom structure **HimciHost** object and **MmcCntlr**, and calls the **MmcCntlrAdd** function at the core layer. **MmcCntlr**, **HimciHost**, and **HdfDeviceObject** assign values with each other so that other functions can be converted successfully. 467 468 ``` 469 static int32_t HimciMmcBind(struct HdfDeviceObject *obj) 470 { 471 struct MmcCntlr *cntlr = NULL; 472 struct HimciHost *host = NULL; 473 int32_t ret; 474 cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr)); 475 host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost)); 476 477 host->mmc = cntlr; // (Mandatory) Enable conversion between HimciHost and MmcCntlr. 478 cntlr->priv = (void *)host; // (Mandatory) Enable conversion between HimciHost and MmcCntlr. 479 cntlr->ops = &g_himciHostOps; // (Mandatory) Connect to the MmcCntlrOps instance. 480 cntlr->hdfDevObj = obj; // (Mandatory) Enable conversion between HdfDeviceObject and MmcCntlr. 481 obj->service = &cntlr->service; // (Mandatory) Enable conversion between HdfDeviceObject and MmcCntlr. 482 ret = MmcCntlrParse(cntlr, obj); // (Mandatory) Initialize cntlr. If the initialization fails, execute goto _ERR. 483 ... 484 ret = HimciHostParse(host, obj); // (Mandatory) Initialize the attributes of the host. If the initialization fails, execute goto _ERR. 485 ... 486 ret = HimciHostInit(host, cntlr);// Initialization defined by the vendor. If the initialization fails, execute goto _ERR. 487 ... 488 ret = MmcCntlrAdd(cntlr); // Call the function at the core layer. If the function fails to be called, execute goto _ERR. 489 ... 490 (void)MmcCntlrAddDetectMsgToQueue(cntlr);// Add the card detection message to the queue. 491 HDF_LOGD("HimciMmcBind: success."); 492 return HDF_SUCCESS; 493 _ERR: 494 HimciDeleteHost(host); 495 HDF_LOGD("HimciMmcBind: fail, err = %d.", ret); 496 return ret; 497 } 498 ``` 499 500 - Init function 501 502 Input parameters: 503 504 **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. 505 506 Return values: 507 508 HDF\_STATUS 509 510 Function description: 511 512 Implements ProcMciInit. 513 514 ``` 515 static int32_t HimciMmcInit(struct HdfDeviceObject *obj) 516 { 517 static bool procInit = false; 518 (void)obj; 519 if (procInit == false) { 520 if (ProcMciInit() == HDF_SUCCESS) { 521 procInit = true; 522 HDF_LOGD("HimciMmcInit: proc init success."); 523 } 524 } 525 HDF_LOGD("HimciMmcInit: success."); 526 return HDF_SUCCESS; 527 } 528 ``` 529 530 - Release function 531 532 Input parameters: 533 534 **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. 535 536 Return values: 537 538 – 539 540 Function description: 541 542 Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF framework fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations. 543 544 ``` 545 static void HimciMmcRelease(struct HdfDeviceObject *obj) 546 { 547 struct MmcCntlr *cntlr = NULL; 548 ... 549 cntlr = (struct MmcCntlr *)obj->service;// Forcibly convert HdfDeviceObject to MmcCntlr by using service. For details about the value assignment, see the Bind function. 550 ... 551 HimciDeleteHost((struct HimciHost *)cntlr->priv);// Memory release function customized by the vendor. A forced conversion from MmcCntlr to HimciHost is involved in the process. 552 } 553 ``` 554 555 556 557