1e41f4b71Sopenharmony_ci# SDIO
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## Overview
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciA Secure Digital Input Output (SDIO) card is an extension of the SD specification to cover I/O functions. SD and SDIO cards are called multimedia cards (MMCs). In the Hardware Driver Foundation (HDF), the SDIO module uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci  **Figure 1** Independent service mode
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci  ![image](figures/independent-service-mode.png)
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci## Available APIs
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci**SdioDeviceOps**:
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci```
19e41f4b71Sopenharmony_ci// Function template
20e41f4b71Sopenharmony_cistruct SdioDeviceOps {
21e41f4b71Sopenharmony_ci  int32_t (*incrAddrReadBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);
22e41f4b71Sopenharmony_ci  int32_t (*incrAddrWriteBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);
23e41f4b71Sopenharmony_ci  int32_t (*fixedAddrReadBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen);
24e41f4b71Sopenharmony_ci  int32_t (*fixedAddrWriteBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen);
25e41f4b71Sopenharmony_ci  int32_t (*func0ReadBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);
26e41f4b71Sopenharmony_ci  int32_t (*func0WriteBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);
27e41f4b71Sopenharmony_ci  int32_t (*setBlockSize)(struct SdioDevice *dev, uint32_t blockSize);
28e41f4b71Sopenharmony_ci  int32_t (*getCommonInfo)(struct SdioDevice *dev, SdioCommonInfo *info, uint32_t infoType);
29e41f4b71Sopenharmony_ci  int32_t (*setCommonInfo)(struct SdioDevice *dev, SdioCommonInfo *info, uint32_t infoType);
30e41f4b71Sopenharmony_ci  int32_t (*flushData)(struct SdioDevice *dev);
31e41f4b71Sopenharmony_ci  int32_t (*enableFunc)(struct SdioDevice *dev);
32e41f4b71Sopenharmony_ci  int32_t (*disableFunc)(struct SdioDevice *dev);
33e41f4b71Sopenharmony_ci  int32_t (*claimIrq)(struct SdioDevice *dev, SdioIrqHandler *irqHandler);
34e41f4b71Sopenharmony_ci  int32_t (*releaseIrq)(struct SdioDevice *dev);
35e41f4b71Sopenharmony_ci  int32_t (*findFunc)(struct SdioDevice *dev, struct SdioFunctionConfig *configData);
36e41f4b71Sopenharmony_ci  int32_t (*claimHost)(struct SdioDevice *dev);
37e41f4b71Sopenharmony_ci  int32_t (*releaseHost)(struct SdioDevice *dev);
38e41f4b71Sopenharmony_ci};
39e41f4b71Sopenharmony_ci```
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ci  **Table 1** Description of the callback functions in SdioDeviceOps
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci| Function| Input Parameter| Output Parameter| Return Value| Description|
44e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- | -------- |
45e41f4b71Sopenharmony_ci| incrAddrReadBytes | **dev**: structure pointer to the SDIO device controller.<br>**addr**: SDIO address, which is of the uint32_t type.<br>**size**: size of the data to read, which is of the uint32_t type.| **data**: pointer to the output value, which is of the uint8_t type.| HDF_STATUS| Incrementally reads data of a given length from the specified SDIO address.|
46e41f4b71Sopenharmony_ci| incrAddrWriteBytes | **dev**: structure pointer to the SDIO device controller.<br>**data**: pointer to the input value, which is of the uint8_t type.<br>**addr**: SDIO address, which is of the uint32_t type.<br>**size**: size of the data to write, which is of the uint32_t type.| –| HDF_STATUS| Incrementally writes data of a given length to the specified SDIO address.|
47e41f4b71Sopenharmony_ci| fixedAddrReadBytes | **dev**: structure pointer to the SDIO device controller.<br>**addr**: SDIO address, which is of the uint32_t type.<br>**size**: size of the data to read, which is of the uint32_t type.<br>**scatterLen**: data length, which is of the uint32_t type.| **data**: pointer to the output value, which is of the uint8_t type.| HDF_STATUS| Reads data of a given length from a fixed SDIO address.|
48e41f4b71Sopenharmony_ci| fixedAddrWriteBytes | **dev**: structure pointer to the SDIO device controller.<br>**data**: pointer to the input value, which is of the uint8_t type.<br>**addr**: SDIO address, which is of the uint32_t type.<br>**size**: size of the data to write, which is of the uint32_t type.<br>**scatterLen**: data length, which is of the uint32_t type.| –| HDF_STATUS| Writes data of a given length to the fixed SDIO address.|
49e41f4b71Sopenharmony_ci| func0ReadBytes | **dev**: structure pointer to the SDIO device controller.<br>**addr**: SDIO address, which is of the uint32_t type.<br>**size**: size of the data to read, which is of the uint32_t type.| **data**: pointer to the output value, which is of the uint8_t type.| HDF_STATUS| Reads data of a given length from the address space of SDIO function 0.|
50e41f4b71Sopenharmony_ci| func0WriteBytes | **dev**: structure pointer to the SDIO device controller.<br>**data**: pointer to the input value, which is of the uint8_t type.<br>**addr**: SDIO address, which is of the uint32_t type.<br>**size**: size of the data to write, which is of the uint32_t type.| –| HDF_STATUS| Writes data of a given length to the address space of SDIO function 0.|
51e41f4b71Sopenharmony_ci| setBlockSize | **dev**: structure pointer to the SDIO device controller.<br>**blockSize**: block size, which is of the uint32_t type.| –| HDF_STATUS| Sets the block size.|
52e41f4b71Sopenharmony_ci| getCommonInfo | **dev**: structure pointer to the SDIO device controller.  <br>**infoType**: info type, which is of the uint32_t type.| **info**: structure pointer to the output **SdioFuncInfo**.| HDF_STATUS| Obtains **CommonInfo**. For details, see the **NOTE** below this table.|
53e41f4b71Sopenharmony_ci| setCommonInfo | **dev**: structure pointer to the SDIO device controller.<br>**info**: union pointer to the input **SdioFuncInfo**.<br>**infoType**: info type, which is of the uint32_t type.| –| HDF_STATUS| Sets **CommonInfo**. For details, see the **NOTE** below this table.|
54e41f4b71Sopenharmony_ci| flushData | **dev**: structure pointer to the SDIO device controller.| –| HDF_STATUS| Called to flush data when the SDIO device needs to be re-initialized or an error occurs.|
55e41f4b71Sopenharmony_ci| enableFunc | **dev**: structure pointer to the SDIO device controller.| –| HDF_STATUS| Enables an SDIO device.|
56e41f4b71Sopenharmony_ci| disableFunc | **dev**: structure pointer to the SDIO device controller.| –| HDF_STATUS| Disables an SDIO device.|
57e41f4b71Sopenharmony_ci| claimIrq | **dev**: structure pointer to the SDIO device controller.<br>**irqHandler**: void function pointer to the interrupt request (IRQ) handler.| –| HDF_STATUS| Claims an SDIO IRQ.|
58e41f4b71Sopenharmony_ci| releaseIrq | **dev**: structure pointer to the SDIO device controller.| –| HDF_STATUS| Releases an SDIO IRQ.|
59e41f4b71Sopenharmony_ci| findFunc | **dev**: structure pointer to the SDIO device controller.<br>**configData**: structure pointer to the key SDIO function information.| –| HDF_STATUS| Obtains the matching funcNum.|
60e41f4b71Sopenharmony_ci| claimHost | **dev**: structure pointer to the SDIO device controller.| –| HDF_STATUS| Claims a host exclusively.|
61e41f4b71Sopenharmony_ci| releaseHost | **dev**: structure pointer to the SDIO device controller.| –| HDF_STATUS| Releases the exclusively claimed host.|
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ci> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
65e41f4b71Sopenharmony_ci> CommonInfo includes the following information:<br>- **maxBlockNum**: specifies the maximum number of blocks in a request. <br>- **maxBlockSize**: specifies the maximum number of bytes in a block. <br>- **maxRequestSize**: specifies the maximum number of bytes in a request. <br>- **enTimeout**: specifies the maximum timeout period, in milliseconds. <br>- **funcNum**: specifies the function number, which ranges from 1 to 7. <br>- **irqCap**: specifies the IRQ capabilities. <br>- **(void \*)data**
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci## How to Develop
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ciThe SDIO module adaptation involves the following steps:
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci1. Instantiate the driver entry.
73e41f4b71Sopenharmony_ci   - Instantiate the **HdfDriverEntry** structure.
74e41f4b71Sopenharmony_ci   - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci2. Configure attribute files.
77e41f4b71Sopenharmony_ci   - Add the **deviceNode** information to the **device_info.hcs** file.
78e41f4b71Sopenharmony_ci   - (Optional) Add the **sdio_config.hcs** file.
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci3. Instantiate the SDIO controller object.
81e41f4b71Sopenharmony_ci   - Initialize **SdioDevice**.
82e41f4b71Sopenharmony_ci   - Instantiate **SdioDeviceOps** in the **SdioDevice** object.
83e41f4b71Sopenharmony_ci      > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
84e41f4b71Sopenharmony_ci      > For details about the functions in **SdioDeviceOps**, see [Available APIs](#available-apis).
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ci4. Debug the driver.
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci   (Optional) For new drivers, verify the basic functions, such as the SDIO control status and response to interrupts.
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci
91e41f4b71Sopenharmony_ci## Development Example
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_ciThe following uses **sdio_adapter.c** as an example to present the information required for implementing device functions.
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci1. Instantiate the driver entry.
96e41f4b71Sopenharmony_ci
97e41f4b71Sopenharmony_ci   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**.
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci   In the HDF, 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.
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci   Generally, the HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci   SDIO driver entry example:
104e41f4b71Sopenharmony_ci   
105e41f4b71Sopenharmony_ci   ```
106e41f4b71Sopenharmony_ci   struct HdfDriverEntry g_sdioDriverEntry = {
107e41f4b71Sopenharmony_ci       .moduleVersion = 1,
108e41f4b71Sopenharmony_ci       .Bind = Hi35xxLinuxSdioBind,       // See the Bind function.
109e41f4b71Sopenharmony_ci       .Init = Hi35xxLinuxSdioInit,       // See the Init function.
110e41f4b71Sopenharmony_ci       .Release = Hi35xxLinuxSdioRelease, // See the Release function.
111e41f4b71Sopenharmony_ci       .moduleName = "HDF_PLATFORM_SDIO",// (Mandatory) The value must be the same as that of moduleName in the .hcs file.
112e41f4b71Sopenharmony_ci   };
113e41f4b71Sopenharmony_ci   // Call HDF_INIT to register the driver entry with the HDF.
114e41f4b71Sopenharmony_ci   HDF_INIT(g_sdioDriverEntry);
115e41f4b71Sopenharmony_ci   ```
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **sdio_config.hcs** file.
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci   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 **SdioDevice** members at the core layer.
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci   In this example, there is only one SDIO controller. If there are multiple SDIO controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **sdio_config** file for each controller.
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci   - **device_info.hcs** configuration example:
124e41f4b71Sopenharmony_ci   
125e41f4b71Sopenharmony_ci     
126e41f4b71Sopenharmony_ci     ```
127e41f4b71Sopenharmony_ci      root {
128e41f4b71Sopenharmony_ci       device_info {
129e41f4b71Sopenharmony_ci         match_attr = "hdf_manager";
130e41f4b71Sopenharmony_ci         platform :: host {
131e41f4b71Sopenharmony_ci           hostName = "platform_host";
132e41f4b71Sopenharmony_ci           priority = 50;
133e41f4b71Sopenharmony_ci           device_sdio :: device {
134e41f4b71Sopenharmony_ci             device0 :: deviceNode {
135e41f4b71Sopenharmony_ci               policy = 1;
136e41f4b71Sopenharmony_ci               priority = 70;
137e41f4b71Sopenharmony_ci               permission = 0644;
138e41f4b71Sopenharmony_ci               moduleName = "HDF_PLATFORM_SDIO";          // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
139e41f4b71Sopenharmony_ci               serviceName = "HDF_PLATFORM_MMC_2";        // (Mandatory) Unique name of the service published by the driver.
140e41f4b71Sopenharmony_ci               deviceMatchAttr = "hisilicon_hi35xx_sdio_0";// (Mandatory) Private data of the controller. The value must be the same as the controller information in sdio_config.hcs.
141e41f4b71Sopenharmony_ci             }
142e41f4b71Sopenharmony_ci           }
143e41f4b71Sopenharmony_ci         }
144e41f4b71Sopenharmony_ci       }
145e41f4b71Sopenharmony_ci     }
146e41f4b71Sopenharmony_ci     ```
147e41f4b71Sopenharmony_ci   
148e41f4b71Sopenharmony_ci   - **sdio_config.hcs** configuration example:
149e41f4b71Sopenharmony_ci   
150e41f4b71Sopenharmony_ci     
151e41f4b71Sopenharmony_ci     ```
152e41f4b71Sopenharmony_ci     root {
153e41f4b71Sopenharmony_ci       platform {
154e41f4b71Sopenharmony_ci         sdio_config {
155e41f4b71Sopenharmony_ci           template sdio_controller {
156e41f4b71Sopenharmony_ci             match_attr = "";
157e41f4b71Sopenharmony_ci             hostId = 2;                            // (Mandatory) The value must be 2. For details, see mmc_config.hcs.
158e41f4b71Sopenharmony_ci             devType = 2;                           // (Mandatory) The value must be 2. For details, see mmc_config.hcs.
159e41f4b71Sopenharmony_ci           }
160e41f4b71Sopenharmony_ci           controller_0x2dd1 :: sdio_controller {
161e41f4b71Sopenharmony_ci             match_attr = "hisilicon_hi35xx_sdio_0";// (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
162e41f4b71Sopenharmony_ci         }
163e41f4b71Sopenharmony_ci       }
164e41f4b71Sopenharmony_ci     }
165e41f4b71Sopenharmony_ci     ```
166e41f4b71Sopenharmony_ci
167e41f4b71Sopenharmony_ci3. Initialize the **SdioDevice** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **SdioDeviceOps** in **SdioDevice** (so that the underlying driver functions can be called).
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ci   - Defining a custom structure
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci     To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **sdio_config.hcs** file to initialize the members in the custom structure and passes important parameters to the object at the core layer.
172e41f4b71Sopenharmony_ci
173e41f4b71Sopenharmony_ci     
174e41f4b71Sopenharmony_ci      ```
175e41f4b71Sopenharmony_ci      typedef struct {
176e41f4b71Sopenharmony_ci          uint32_t maxBlockNum;    // Maximum number of blocks in a request.
177e41f4b71Sopenharmony_ci          uint32_t maxBlockSize;   // Maximum number of bytes in a block. The value range is 1 to 2048.
178e41f4b71Sopenharmony_ci          uint32_t maxRequestSize; // Maximum number of bytes in a request. The value range is 1 to 2048.
179e41f4b71Sopenharmony_ci          uint32_t enTimeout;      // Maximum timeout period in milliseconds. The value cannot exceed one second.
180e41f4b71Sopenharmony_ci          uint32_t funcNum;        // Function number, which ranges from 1 to 7.
181e41f4b71Sopenharmony_ci          uint32_t irqCap;         // IRQ capabilities.
182e41f4b71Sopenharmony_ci          void *data;              // Private data.
183e41f4b71Sopenharmony_ci      } SdioFuncInfo;
184e41f4b71Sopenharmony_ci      
185e41f4b71Sopenharmony_ci      // SdioDevice is the core layer controller structure. The Bind function assigns values to the members of SdioDevice.
186e41f4b71Sopenharmony_ci      struct SdioDevice {
187e41f4b71Sopenharmony_ci          struct SdDevice sd;
188e41f4b71Sopenharmony_ci          struct SdioDeviceOps *sdioOps;
189e41f4b71Sopenharmony_ci          struct SdioRegister sdioReg;
190e41f4b71Sopenharmony_ci          uint32_t functions;
191e41f4b71Sopenharmony_ci          struct SdioFunction *sdioFunc[SDIO_MAX_FUNCTION_NUMBER];
192e41f4b71Sopenharmony_ci          struct SdioFunction *curFunction;
193e41f4b71Sopenharmony_ci          struct OsalThread thread;  /* irq thread */
194e41f4b71Sopenharmony_ci          struct OsalSem sem;
195e41f4b71Sopenharmony_ci          bool irqPending;
196e41f4b71Sopenharmony_ci          bool threadRunning;
197e41f4b71Sopenharmony_ci      };
198e41f4b71Sopenharmony_ci      ```
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci   - Instantiating **SdioDeviceOps** in **SdioDevice** (other members are initialized by **Init**)
201e41f4b71Sopenharmony_ci
202e41f4b71Sopenharmony_ci     
203e41f4b71Sopenharmony_ci      ```
204e41f4b71Sopenharmony_ci      static struct SdioDeviceOps g_sdioDeviceOps = {
205e41f4b71Sopenharmony_ci          .incrAddrReadBytes   = Hi35xxLinuxSdioIncrAddrReadBytes,
206e41f4b71Sopenharmony_ci          .incrAddrWriteBytes  = Hi35xxLinuxSdioIncrAddrWriteBytes,
207e41f4b71Sopenharmony_ci          .fixedAddrReadBytes  = Hi35xxLinuxSdioFixedAddrReadBytes,
208e41f4b71Sopenharmony_ci          .fixedAddrWriteBytes = Hi35xxLinuxSdioFixedAddrWriteBytes,
209e41f4b71Sopenharmony_ci          .func0ReadBytes  = Hi35xxLinuxSdioFunc0ReadBytes,
210e41f4b71Sopenharmony_ci          .func0WriteBytes = Hi35xxLinuxSdioFunc0WriteBytes,
211e41f4b71Sopenharmony_ci          .setBlockSize    = Hi35xxLinuxSdioSetBlockSize,
212e41f4b71Sopenharmony_ci          .getCommonInfo   = Hi35xxLinuxSdioGetCommonInfo,
213e41f4b71Sopenharmony_ci          .setCommonInfo   = Hi35xxLinuxSdioSetCommonInfo,
214e41f4b71Sopenharmony_ci          .flushData       = Hi35xxLinuxSdioFlushData,
215e41f4b71Sopenharmony_ci          .enableFunc      = Hi35xxLinuxSdioEnableFunc,
216e41f4b71Sopenharmony_ci          .disableFunc = Hi35xxLinuxSdioDisableFunc,
217e41f4b71Sopenharmony_ci          .claimIrq    = Hi35xxLinuxSdioClaimIrq,
218e41f4b71Sopenharmony_ci          .releaseIrq  = Hi35xxLinuxSdioReleaseIrq,
219e41f4b71Sopenharmony_ci          .findFunc    = Hi35xxLinuxSdioFindFunc,
220e41f4b71Sopenharmony_ci          .claimHost   = Hi35xxLinuxSdioClaimHost,
221e41f4b71Sopenharmony_ci          .releaseHost = Hi35xxLinuxSdioReleaseHost,
222e41f4b71Sopenharmony_ci      };
223e41f4b71Sopenharmony_ci      ```
224e41f4b71Sopenharmony_ci      
225e41f4b71Sopenharmony_ci- **Bind** function
226e41f4b71Sopenharmony_ci  
227e41f4b71Sopenharmony_ci   **Input parameter**:
228e41f4b71Sopenharmony_ci   
229e41f4b71Sopenharmony_ci   **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
230e41f4b71Sopenharmony_ci   
231e41f4b71Sopenharmony_ci   **Return value**:
232e41f4b71Sopenharmony_ci   
233e41f4b71Sopenharmony_ci   **HDF_STATUS**
234e41f4b71Sopenharmony_ci   
235e41f4b71Sopenharmony_ci   The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
236e41f4b71Sopenharmony_ci   
237e41f4b71Sopenharmony_ci   **Table 2** Description of HDF_STATUS
238e41f4b71Sopenharmony_ci   
239e41f4b71Sopenharmony_ci   | Status                 | Description                |
240e41f4b71Sopenharmony_ci   | ---------------------- | -------------------------- |
241e41f4b71Sopenharmony_ci   | HDF_ERR_INVALID_OBJECT | Invalid controller object. |
242e41f4b71Sopenharmony_ci   | HDF_ERR_MALLOC_FAIL    | Failed to allocate memory. |
243e41f4b71Sopenharmony_ci   | HDF_ERR_INVALID_PARAM  | Invalid parameter.         |
244e41f4b71Sopenharmony_ci   | HDF_ERR_IO             | I/O error.                 |
245e41f4b71Sopenharmony_ci   | HDF_SUCCESS            | Initialization successful. |
246e41f4b71Sopenharmony_ci   | HDF_FAILURE            | Initialization failed.     |
247e41f4b71Sopenharmony_ci   
248e41f4b71Sopenharmony_ci   **Function description**:
249e41f4b71Sopenharmony_ci   
250e41f4b71Sopenharmony_ci   Initializes the custom structure object and **SdioCntlr**, calls the **SdioCntlrAdd** function at the core layer, and performs other initialization operations customized by the vendor.
251e41f4b71Sopenharmony_ci   
252e41f4b71Sopenharmony_ci   ```
253e41f4b71Sopenharmony_ci   static int32_t Hi35xxLinuxSdioBind(struct HdfDeviceObject *obj)
254e41f4b71Sopenharmony_ci      {
255e41f4b71Sopenharmony_ci          struct MmcCntlr *cntlr = NULL;
256e41f4b71Sopenharmony_ci          int32_t ret;
257e41f4b71Sopenharmony_ci          ...
258e41f4b71Sopenharmony_ci           cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));// Allocate memory.
259e41f4b71Sopenharmony_ci          ...
260e41f4b71Sopenharmony_ci          cntlr->ops = &g_sdioCntlrOps;                                     // (Mandatory) struct MmcCntlrOps g_sdioCntlrOps={
261e41f4b71Sopenharmony_ci                                                                            // .rescanSdioDev = Hi35xxLinuxSdioRescan,};
262e41f4b71Sopenharmony_ci          cntlr->hdfDevObj = obj;                                           // (Mandatory) Prerequisites for conversion between HdfDeviceObject and MmcCntlr.
263e41f4b71Sopenharmony_ci          obj->service = &cntlr->service;                                   // (Mandatory) Prerequisites for conversion between HdfDeviceObject and MmcCntlr.   
264e41f4b71Sopenharmony_ci          ret = Hi35xxLinuxSdioCntlrParse(cntlr, obj);                      // (Mandatory) Initialize index and devType of cntlr. If the initialization fails, execute goto _ERR.
265e41f4b71Sopenharmony_ci          ...
266e41f4b71Sopenharmony_ci          ret = MmcCntlrAdd(cntlr);                                         // (Mandatory) Call the function in mmc_core.c. If the operation fails, execute goto _ERR.
267e41f4b71Sopenharmony_ci          ...
268e41f4b71Sopenharmony_ci          ret = MmcCntlrAllocDev(cntlr, (enum MmcDevType)cntlr->devType);   // (Mandatory) Call the function in mmc_core.c. If the operation fails, execute goto _ERR.
269e41f4b71Sopenharmony_ci          ...
270e41f4b71Sopenharmony_ci          
271e41f4b71Sopenharmony_ci          MmcDeviceAddOps(cntlr->curDev, &g_sdioDeviceOps);                // (Mandatory) Call the function in mmc_core.c to hook the related functions.
272e41f4b71Sopenharmony_ci          HDF_LOGD("Hi35xxLinuxSdioBind: Success!");
273e41f4b71Sopenharmony_ci          return HDF_SUCCESS;
274e41f4b71Sopenharmony_ci      
275e41f4b71Sopenharmony_ci      _ERR:
276e41f4b71Sopenharmony_ci          Hi35xxLinuxSdioDeleteCntlr(cntlr);
277e41f4b71Sopenharmony_ci          HDF_LOGE("Hi35xxLinuxSdioBind: Fail!");
278e41f4b71Sopenharmony_ci       return HDF_FAILURE;
279e41f4b71Sopenharmony_ci      }
280e41f4b71Sopenharmony_ci   ```
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ci- **Init** function
283e41f4b71Sopenharmony_ci  
284e41f4b71Sopenharmony_ci   **Input parameter**:
285e41f4b71Sopenharmony_ci   
286e41f4b71Sopenharmony_ci   **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
287e41f4b71Sopenharmony_ci   
288e41f4b71Sopenharmony_ci   **Return value**:
289e41f4b71Sopenharmony_ci   
290e41f4b71Sopenharmony_ci   **HDF_STATUS**
291e41f4b71Sopenharmony_ci   
292e41f4b71Sopenharmony_ci   **Function description**:
293e41f4b71Sopenharmony_ci   
294e41f4b71Sopenharmony_ci   You can add operations as required.
295e41f4b71Sopenharmony_ci   
296e41f4b71Sopenharmony_ci   ```
297e41f4b71Sopenharmony_ci   static int32_t Hi35xxLinuxSdioInit(struct HdfDeviceObject *obj)
298e41f4b71Sopenharmony_ci      {
299e41f4b71Sopenharmony_ci          (void)obj;// No operation. You can add operations as required.
300e41f4b71Sopenharmony_ci          HDF_LOGD("Hi35xxLinuxSdioInit: Success!");
301e41f4b71Sopenharmony_ci          return HDF_SUCCESS;
302e41f4b71Sopenharmony_ci   }
303e41f4b71Sopenharmony_ci   ```
304e41f4b71Sopenharmony_ci
305e41f4b71Sopenharmony_ci- **Release** function
306e41f4b71Sopenharmony_ci
307e41f4b71Sopenharmony_ci   **Input parameter**:
308e41f4b71Sopenharmony_ci
309e41f4b71Sopenharmony_ci   **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ci   **Return value**:
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci   No value is returned.
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci   **Function description**:
316e41f4b71Sopenharmony_ci
317e41f4b71Sopenharmony_ci   Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
318e41f4b71Sopenharmony_ci
319e41f4b71Sopenharmony_ci   > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
320e41f4b71Sopenharmony_ci   > All forced conversion operations for obtaining the corresponding object can be successful only when the **Bind** function has the corresponding value assignment operations.
321e41f4b71Sopenharmony_ci
322e41f4b71Sopenharmony_ci   ```
323e41f4b71Sopenharmony_ci   static void Hi35xxLinuxSdioRelease(struct HdfDeviceObject *obj)
324e41f4b71Sopenharmony_ci   {
325e41f4b71Sopenharmony_ci       if (obj == NULL) {
326e41f4b71Sopenharmony_ci           return;
327e41f4b71Sopenharmony_ci       }
328e41f4b71Sopenharmony_ci       Hi35xxLinuxSdioDeleteCntlr((struct MmcCntlr *)obj->service);// (Mandatory) Custom function for releasing memory. A forced conversion from HdfDeviceObject to MmcCntlr is involved.
329e41f4b71Sopenharmony_ci   }
330e41f4b71Sopenharmony_ci   ```
331