1# Device Driver Porting 2 3This section describes how to port device drivers. 4 5## LCD Driver Porting 6 7To port an LCD driver, write the driver, create an instance of the corresponding model in the driver, and complete the registration. 8 9The LCD drivers are stored in **//drivers/hdf_core/framework/model/display/driver/panel**. 10 111. Create a panel driver. 12 13 Create an HDF driver and call the **RegisterPanel** method to register a model instance during driver initialization. 14 15 16 ``` 17 int32_t LCDxxEntryInit(struct HdfDeviceObject *object) 18 { 19 struct PanelData *panel = CreateYourPanel(); 20 // Register a model instance. 21 if (RegisterPanel(panel) != HDF_SUCCESS) { 22 HDF_LOGE("%s: RegisterPanel failed", __func__); 23 return HDF_FAILURE; 24 } 25 return HDF_SUCCESS; 26 } 27 28 struct HdfDriverEntry g_xxxxDevEntry = { 29 .moduleVersion = 1, 30 .moduleName = "LCD_XXXX", 31 .Init = LCDxxEntryInit, 32 }; 33 34 HDF_INIT(g_xxxxDevEntry); 35 ``` 36 372. Configure and load the panel driver. 38 39 Modify the source code file **//vendor/vendor_name/product_name/config/device_info/device_info.hcs**. Add configurations for the device named **device\_lcd** for the display host. 40 41 >  **CAUTION** 42 > 43 > Make sure the value of **moduleName** is the same as that of **moduleName** in the panel driver. 44 45 46 ``` 47 root { 48 ... 49 display :: host { 50 device_lcd :: device { 51 deviceN :: deviceNode { 52 policy = 0; 53 priority = 100; 54 preload = 2; 55 moduleName = "LCD_XXXX"; 56 } 57 } 58 } 59 } 60 ``` 61 62 63## Touchscreen Driver Porting 64 65This section describes how to port a touchscreen driver. The touchscreen drivers are stored in the source code directory **//drivers/hdf_core/framework/model/input/driver/touchscreen**. To port a touchscreen driver, register a **ChipDevice** model instance with the system. 66 67For details about how to develop a touchscreen driver, see [Touchscreen Development Guidelines](../driver/driver-peripherals-touch-des.md). 68 691. Create a touchscreen driver. 70 71 Create the **touch_ic_name.c** file in the **touchscreen** directory. Write the following content: 72 73 74 ``` 75 #include "hdf_touch.h" 76 77 static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device) 78 { 79 ChipDevice *tpImpl = CreateXXXXTpImpl(); 80 if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) { // Register the ChipDevice model instance. 81 ReleaseXXXXTpImpl(tpImpl); 82 return HDF_FAILURE; 83 } 84 return HDF_SUCCESS; 85 } 86 87 struct HdfDriverEntry g_touchXXXXChipEntry = { 88 .moduleVersion = 1, 89 .moduleName = "HDF_TOUCH_XXXX", // Make sure the value is the same as that in the subsequent configuration. 90 .Init = HdfXXXXChipInit, 91 }; 92 93 HDF_INIT(g_touchXXXXChipEntry); 94 ``` 95 96 The following methods need to be implemented in **ChipDevice**. 97 98 | Method | Description | 99 | -------- | -------- | 100 | int32_t (\*Init)(ChipDevice \*device) | Initializes the device. | 101 | int32_t (\*Detect)(ChipDevice \*device) | Detects the device. | 102 | int32_t (\*Suspend)(ChipDevice \*device) | Places the device in sleep mode. | 103 | int32_t (\*Resume)(ChipDevice \*device) | Wakes up the device. | 104 | int32_t (\*DataHandle)(ChipDevice \*device) | Reads data from the device and writes touch point data to device > driver > frameData. | 105 | int32_t (\*UpdateFirmware)(ChipDevice \*device) | Updates the firmware. | 106 1072. Configure the product and load the driver. 108 109 All device information of the product is defined in the source code file **//vendor/vendor_name/product_name/config/device_info/device_info.hcs**. Modify the file and add configurations to the **device** named **device\_touch\_chip** in the **host** of the **input** command. 110 111 >  **NOTE** 112 > 113 > Make sure the value of **moduleName** is the same as that of **moduleName** in the touchscreen driver. 114 115 116 ``` 117 deviceN :: deviceNode { 118 policy = 0; 119 priority = 130; 120 preload = 0; 121 permission = 0660; 122 moduleName = "HDF_TOUCH_XXXX"; 123 deviceMatchAttr = "touch_XXXX_configs"; 124 } 125 ``` 126 127 128## WLAN Driver Porting 129 130The WLAN driver is divided into two parts. One of the parts manages WLAN devices, and the other part manages WLAN traffic. 131 132**Figure 1** OpenHarmony WLAN driver architecture<a name="fig155920160203"></a> 133 134  135 136As shown in Figure 1, the part on the left manages WLAN devices, and the part on the right manages WLAN traffic. The HDF WLAN framework abstracts these two parts. The porting process of the driver can be considered as the implementation of the APIs required by the two parts. These APIs are described in the table below. 137 138| API | Header File | Description | 139| -------- | -------- | -------- | 140| HdfChipDriverFactory | drivers\hdf_core\framework\include\wifi\hdf_wlan_chipdriver_manager.h | Factory of the ChipDriver, which is used to support multiple WLAN interfaces of a chip. | 141| HdfChipDriver | drivers\hdf_core\framework\include\wifi\wifi_module.h | Manages a specific WLAN interface. | 142| NetDeviceInterFace | drivers\hdf_core\framework\include\wifi\net_device.h | Communicates with the protocol stack, such as sending data and setting the status of network interfaces. | 143 144>  **NOTE** 145> 146> For details about the API development, see [WLAN Development Guidelines](../driver/driver-peripherals-external-des.md). 147 148The porting procedure is as follows: 149 1501. Create a WLAN chip driver. 151 152 Create the **hdf_wlan_chip_name.c** file in **/device/vendor_name/peripheral/wifi/chip_name/**. The sample code is as follows: 153 154 ``` 155 static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) { 156 static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); // Implement the method. 157 struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr(); 158 if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) { // Register the driver factory. 159 HDF_LOGE("%s fail: driverMgr is NULL!", __func__); 160 return HDF_FAILURE; 161 } 162 return HDF_SUCCESS; 163 } 164 165 struct HdfDriverEntry g_hdfXXXChipEntry = { 166 .moduleVersion = 1, 167 .Init = HdfWlanXXXChipDriverInit, 168 .Release = HdfWlanXXXChipRelease, 169 .moduleName = "HDF_WIFI_CHIP_XXX" // Make sure the name is the same as the configured one. 170 }; 171 172 HDF_INIT(g_hdfXXXChipEntry); 173 ``` 174 175 In the **CreateChipDriverFactory** method, create an object of the **HdfChipDriverFactory** type. This object provides the methods listed below. 176 177 | Method | Description | 178 | -------- | -------- | 179 | const char \*driverName | Indicates the driver name. | 180 | int32_t (\*InitChip)(struct HdfWlanDevice \*device) | Initializes the chip. | 181 | int32_t (\*DeinitChip)(struct HdfWlanDevice \*device) | Deinitializes the chip. | 182 | void (\*ReleaseFactory)(struct HdfChipDriverFactory \*factory) | Releases the **HdfChipDriverFactory** object. | 183 | struct HdfChipDriver \*(\*Build)(struct HdfWlanDevice \*device, uint8_t ifIndex) | Creates an **HdfChipDriver**. In the input parameters, **device** indicates the device information, and **ifIndex** indicates the sequence number of this interface in the chip. | 184 | void (\*Release)(struct HdfChipDriver \*chipDriver) | Releases the chip driver. | 185 | uint8_t (\*GetMaxIFCount)(struct HdfChipDriverFactory \*factory) | Obtains the maximum number of interfaces supported by the current chip. | 186 187 The **Build** method creates an **HdfChipDriver** object that manages the specified network interface. This object needs to provide the following methods: 188 189 | Method | Description | 190 | -------- | -------- | 191 | int32_t (\*init)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | Initializes the current network interface. The **NetDeviceInterFace** needs to be provided for the **netDev**. | 192 | int32_t (\*deinit)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | Deinitializes the current network interface. | 193 | struct HdfMac80211BaseOps \*ops | Provides the WLAN basic capability interface set. | 194 | struct HdfMac80211STAOps \*staOps | Provides the interface set required for supporting the STA mode. | 195 | struct HdfMac80211APOps \*apOps | Provides the interface set required for supporting the AP mode. | 196 1972. Create a configuration file to describe the chips supported by the driver. 198 199 Create a chip configuration file in the product configuration directory and save it to the source code path **//vendor/vendor\_name/product\_name/config/wifi/wlan\_chip\_chip\_name.hcs**. 200 201 202 203 204 ``` 205 root { 206 wlan_config { 207 chip_name :& chipList { 208 chip_name :: chipInst { 209 match_attr = "hdf_wlan_chips_chip_name"; /* Indicates the configuration matching attribute, which is used to provide the configuration root of the driver. */ 210 driverName = "driverName"; /* Indicates the driver name, which must be the same as that of driverName in HdfChipDriverFactory.*/ 211 sdio { 212 vendorId = 0xXXXX; /* your vendor id */ 213 deviceId = [0xXXXX]; /*your supported devices */ 214 } 215 } 216 } 217 } 218 } 219 ``` 220 221 >  **NOTE** 222 > 223 > Replace the values of **vendor\_name**, **product\_name**, and **chip\_name** in the path and file with the actual names. 224 > 225 > Set **vendorId** and **deviceId** to the actual vendor ID and chip ID, respectively. 226 2273. Edit the configuration file and load the driver. 228 229 All device information of the product is defined in the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Modify the file and add configurations to the **device** named **device\_wlan\_chips** in the **host** of the **network** command. The sample code is as follows: 230 231 232 ``` 233 deviceN :: deviceNode { 234 policy = 0; 235 preload = 2; 236 moduleName = "HDF_WLAN_CHIPS"; 237 deviceMatchAttr = "hdf_wlan_chips_chip_name"; 238 serviceName = "driverName"; 239 } 240 ``` 241 242 >  **NOTE** 243 > 244 > Make sure the value of **moduleName** is the same as that of **moduleName** in the WLAN driver. 245 2464. Modify the **Kconfig** file to make the ported WLAN driver appear in the kernel configuration. 247 248 Add configurations to **device/vendor\_name/drivers/Kconfig**. The sample code is as follows: 249 250 251 ``` 252 config DRIVERS_HDF_WIFI_chip_name 253 bool "Enable chip_name Host driver" 254 default n 255 depends on DRIVERS_HDF_WLAN help 256 Answer Y to enable chip_name Host driver. 257 ``` 258 259 >  **NOTE** 260 > 261 > Replace **chip\_name** with the actual chip name. 262 2635. Modify the build script to enable the driver to participate in the kernel build. 264 265 Add the following content to the end of the source code file **//device/vendor\_name/drivers/lite.mk**: 266 267 268 ``` 269 ifeq ($(LOSCFG_DRIVERS_HDF_WIFI_chip_name), y) 270 # After the build is complete, an object named hdf_wlan_chipdriver_chip_name needs to be linked. You are advised to use this name to prevent conflicts. 271 LITEOS_BASELIB += -lhdf_wlan_chipdriver_chip_name 272 # Add the build directory gpio. 273 LIB_SUBDIRS += ../peripheral/wifi/chip_name 274 endif 275 ``` 276 277 >  **NOTE** 278 > 279 > Replace **chip_name** with the actual chip name. 280 281 282