• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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![](figures/independent-service-mode.png "independent-service-mode")
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        >![](../public_sys-resources/icon-note.gif) **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
538539
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