1e41f4b71Sopenharmony_ci# Development Example for Peripheral Drivers<a name="EN-US_TOPIC_0000001157063303"></a>
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview<a name="section86753818426"></a>
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThis document describes how to develop a touchscreen driver on the Hi3516D V300 development board using the HDF input driver model, helping you quickly get started with OpenHarmony peripheral driver development.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci### Hardware Resources<a name="section123071189431"></a>
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciThe touchscreen integrated circuit \(IC\) provided by the Hi3516D V300 development board is GT911, which uses the standard inter-integrated circuit \(I2C\) to communicate with the development board and connects to the main board through the 6-pin flexible flat cable. The following figure shows the distribution of the 6 pins and their connection.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci![](figures/6-pin-distribution-and-physical-connection.png)
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci### Input Driver Model<a name="section53684425430"></a>
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciThe input driver model mainly consists of the device manager, common drivers, and chip drivers.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci-   Input device manager: provides various input device drivers with the APIs for registering or unregistering input devices and manages the input device list.
18e41f4b71Sopenharmony_ci-   Input common driver: provides common drivers for initializing the board-level hardware, processing hardware interrupts, and registering input devices with the input device manager.
19e41f4b71Sopenharmony_ci-   Input chip driver: calls differentiated APIs reserved by the input platform driver to minimize the workload for input chip driver development.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ciIn addition, the input driver model implements functions for reporting input data and parsing input device configurations.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ciFor details about the input driver model, see  [Touchscreen Overview](../driver/driver-peripherals-touch-des.md).
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci## Setting Up the Environment<a name="section661075474418"></a>
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ciFollow the instructions in [Quick Start Overview](../quick-start/quickstart-overview.md).
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci>![](../public_sys-resources/icon-notice.gif) **NOTICE** 
30e41f4b71Sopenharmony_ci>This development example applies to standard, small, and mini OpenHarmony systems. The following sections use the standard system as an example. You can refer to the specific guide for your system to set up the environment.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci## Developing a Touchscreen Driver<a name="section15233162984520"></a>
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ciComplete the following tasks to adapt a touchscreen IC based on the input driver model.
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci### Configuring Device Driver Descriptions<a name="section16761205604515"></a>
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ciConfigure the touchscreen driver description required for registering the driver with the HDF, for example, whether the driver is loaded and what is the loading priority.
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ciYou can configure the device driver description in the configuration file at **./drivers/adapter/khdf/linux/hcs/device\_info/device\_info.hcs**.
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ciThe **device\_info.hcs**  file contains all necessary information for registering drivers in the input driver model with the HDF. You do not need to make any modification for the information unless otherwise required in special scenarios. The private configuration data of each driver uses the **deviceMatchAttr**  field to match the **match\_attr**  field in the **input\_config.hcs**  file.
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ciThe input-related fields in the configuration file are as follows. For details about these fields, see  [Driver Development](../driver/driver-overview-foundation.md).
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci```
47e41f4b71Sopenharmony_ciinput :: host {
48e41f4b71Sopenharmony_ci            hostName = "input_host";
49e41f4b71Sopenharmony_ci            priority = 100;
50e41f4b71Sopenharmony_ci            device_input_manager :: device {              // Specify the device driver description of the input device manager.
51e41f4b71Sopenharmony_ci                device0 :: deviceNode {
52e41f4b71Sopenharmony_ci                    policy = 2;                           // Services are released to both the kernel space and the user space.
53e41f4b71Sopenharmony_ci                    priority = 100;                       // The default priority for the input device manager is 100.
54e41f4b71Sopenharmony_ci                    preload = 0;                          // Load the driver.
55e41f4b71Sopenharmony_ci                    permission = 0660;                    // Specify the permission for the driver to create device nodes.
56e41f4b71Sopenharmony_ci                    moduleName = "HDF_INPUT_MANAGER";     // Match the moduleName in the driver entry structure.
57e41f4b71Sopenharmony_ci                    serviceName = "hdf_input_host";       // Specify the device node name to be generated by the HDF.
58e41f4b71Sopenharmony_ci                    deviceMatchAttr = "";                 // Leave this field empty because private configuration data is not required by the input device manager currently.
59e41f4b71Sopenharmony_ci                }
60e41f4b71Sopenharmony_ci            }
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci            device_hdf_touch :: device {                  // Specify the device driver description of the input common driver.
63e41f4b71Sopenharmony_ci                device0 :: deviceNode {
64e41f4b71Sopenharmony_ci                    policy = 2;                           // Services are released to both the kernel space and the user space.
65e41f4b71Sopenharmony_ci                    priority = 120;                       // The default priority for the input common driver is 120.
66e41f4b71Sopenharmony_ci                    preload = 0;                          // Load the driver.
67e41f4b71Sopenharmony_ci                    permission = 0660;                    // Specify the permission for the driver to create device nodes.
68e41f4b71Sopenharmony_ci                    moduleName = "HDF_TOUCH";             // Match the moduleName in the driver entry structure.
69e41f4b71Sopenharmony_ci                    serviceName = "hdf_input_event1";     // Specify the device node name to be generated by the HDF.
70e41f4b71Sopenharmony_ci                    deviceMatchAttr = "touch_device1";    // Keep this value the same as the match_attr value in the private configuration data.
71e41f4b71Sopenharmony_ci                }
72e41f4b71Sopenharmony_ci            }
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci            device_touch_chip :: device {                 // Specify the device description of the input chip driver.
75e41f4b71Sopenharmony_ci                device0 :: deviceNode {
76e41f4b71Sopenharmony_ci                    policy = 0;                           // Services are not released to the kernel space or the user space.
77e41f4b71Sopenharmony_ci                    priority = 130;                       // The default priority for the input chip driver is 130.
78e41f4b71Sopenharmony_ci                    preload = 0;                          // Load the driver.
79e41f4b71Sopenharmony_ci                    permission = 0660;                    // Specify the permission for the driver to create device nodes.
80e41f4b71Sopenharmony_ci                    moduleName = "HDF_TOUCH_GT911";       // Match the moduleName in the driver entry structure.
81e41f4b71Sopenharmony_ci                    serviceName = "hdf_touch_gt911_service";// Specify the device node name to be generated by the HDF.
82e41f4b71Sopenharmony_ci                    deviceMatchAttr = "zsj_gt911_5p5";    // Keep this value the same as the match_attr value in the private configuration data.
83e41f4b71Sopenharmony_ci                }
84e41f4b71Sopenharmony_ci            }
85e41f4b71Sopenharmony_ci  }
86e41f4b71Sopenharmony_ci```
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ciPay attention to the following fields in the configuration file:
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci**priority**: specifies the driver loading priority.
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci**preload**: specifies whether to load the driver.
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci**moduleName**: This value must be the same as the **moduleName**  value in the driver entry structure.
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci**serviceName**: This value is used by the HDF to create a device node name.
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ci**deviceMatchAttr**: This value must be the same as the **match\_attr**  value in the private configuration data.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ciAfter the device descriptions are configured, the HDF matches the configuration with the code registered with the driver entry structure based on the **moduleName**  field, ensuring that drivers can be loaded properly. If multiple drivers are configured, the **priority**  field determines the loading sequence of each driver.
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci### Configuring the Touchscreen<a name="section156331030144617"></a>
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ciThe private data includes the power-on and power-off sequence, and the platform hardware information includes the GPIO port that connects the touchscreen to the main board.
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ciYou can configure the touchscreen in the configuration file at **./drivers/adapter/khdf/linux/hcs/input/input\_config.hcs**.
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ciThe **input\_config.hcs**  file consists of the private configuration data of both the common driver and chip driver. Information of this file is read and parsed by the driver code. The configuration in the file includes the board-level hardware information and private configuration of the touchscreen. You can tailor the configuration during your development.
109e41f4b71Sopenharmony_ci
110e41f4b71Sopenharmony_ci```
111e41f4b71Sopenharmony_ciroot {                                                              
112e41f4b71Sopenharmony_ci    input_config {
113e41f4b71Sopenharmony_ci        touchConfig {
114e41f4b71Sopenharmony_ci            touch0 {                                                 // Configure the first touchscreen.
115e41f4b71Sopenharmony_ci                boardConfig {                                        // Specify the board-level hardware information.
116e41f4b71Sopenharmony_ci                    match_attr = "touch_device1";                    // Keep this value the same as the match_attr field in the private configuration data of the input common driver in the device description.
117e41f4b71Sopenharmony_ci                    inputAttr {
118e41f4b71Sopenharmony_ci                        /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */
119e41f4b71Sopenharmony_ci                        inputType = 0;                               // Set the input type to touch.
120e41f4b71Sopenharmony_ci                        solutionX = 480;                             // Set the resolution in the X-axis.
121e41f4b71Sopenharmony_ci                        solutionY = 960;                             // Set the resolution in the Y-axis.
122e41f4b71Sopenharmony_ci                        devName = "main_touch";                      // Set the device name.
123e41f4b71Sopenharmony_ci                    }
124e41f4b71Sopenharmony_ci                    busConfig {
125e41f4b71Sopenharmony_ci                        /* 0:i2c 1:spi */
126e41f4b71Sopenharmony_ci                        busType = 0;                                 // GT911 uses the I2C bus for communication.
127e41f4b71Sopenharmony_ci                        busNum = 6;                                  // Use the sixth bus of the chip to communicate with the development board through I2C.
128e41f4b71Sopenharmony_ci                        clkGpio = 86;                                // Set the SCL pin of the chip.
129e41f4b71Sopenharmony_ci                        dataGpio = 87;                               // Set the SDA pin of the chip.
130e41f4b71Sopenharmony_ci                        i2cClkIomux = [0x114f0048, 0x403];           // Configure the SCL pin information.
131e41f4b71Sopenharmony_ci                        i2cDataIomux = [0x114f004c, 0x403];          // Configure the SDA pin information.
132e41f4b71Sopenharmony_ci                    }
133e41f4b71Sopenharmony_ci                    pinConfig {
134e41f4b71Sopenharmony_ci                        rstGpio = 3;                                 // Set the reset pin.
135e41f4b71Sopenharmony_ci                         intGpio = 4;                                 // Set the interrupt pin.
136e41f4b71Sopenharmony_ci                        rstRegCfg = [0x112f0094, 0x400];             // Configure the reset pin information.
137e41f4b71Sopenharmony_ci                        intRegCfg = [0x112f0098, 0x400];             // Configure the interrupt pin information.
138e41f4b71Sopenharmony_ci                    }
139e41f4b71Sopenharmony_ci                    powerConfig {
140e41f4b71Sopenharmony_ci                        /* 0:unused 1:ldo 2:gpio 3:pmic */
141e41f4b71Sopenharmony_ci                        vccType = 2;                                  // Set the VCC type. Value 2 indicates the GPIO power supply.
142e41f4b71Sopenharmony_ci                        vccNum = 20;                                  // gpio20
143e41f4b71Sopenharmony_ci                        vccValue = 1800;                              // Set the voltage amplitude to 1800 mV.
144e41f4b71Sopenharmony_ci                        vciType = 1;                                  // Set the VCI type. Value 1 indicates the LDO power supply.
145e41f4b71Sopenharmony_ci                        vciNum = 12;                                  // ldo12
146e41f4b71Sopenharmony_ci                        vciValue = 3300;                              // Set the voltage amplitude to 3300 mV.
147e41f4b71Sopenharmony_ci                    }
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci                    featureConfig {
150e41f4b71Sopenharmony_ci                        capacitanceTest = 0;                          // Configure the capacitance test.
151e41f4b71Sopenharmony_ci                        gestureMode = 0;                              // Configure the gesture mode.
152e41f4b71Sopenharmony_ci                        gloverMode = 0;                               // Configure the gloves mode.
153e41f4b71Sopenharmony_ci                        coverMode = 0;                                // Configure the cover mode.
154e41f4b71Sopenharmony_ci                        chargerMode = 0;                              // Configure the charging mode.
155e41f4b71Sopenharmony_ci                        knuckleMode = 0;                              // Configure the knuckle mode.
156e41f4b71Sopenharmony_ci                    }
157e41f4b71Sopenharmony_ci                }
158e41f4b71Sopenharmony_ci                chipConfig {                                          // Configure the private data of the touchscreen chip.
159e41f4b71Sopenharmony_ci                    template touchChip {                              // Set the template.
160e41f4b71Sopenharmony_ci                        match_attr = "";
161e41f4b71Sopenharmony_ci                        chipName = "gt911";                           // Set the touchscreen IC model.
162e41f4b71Sopenharmony_ci                        vendorName = "zsj";                           // Set the vendor name.
163e41f4b71Sopenharmony_ci                        chipInfo = "AAAA11222";                       // The first four characters indicate the product name. The fifth and sixth characters indicate the IC model. The last three characters indicate the chip model.
164e41f4b71Sopenharmony_ci                        busType = 0;                                  // 0 indicates the I2C bus, and 1 indicates the SPI bus.
165e41f4b71Sopenharmony_ci                        deviceAddr = 0x5D;                            // Set the IC communication address.
166e41f4b71Sopenharmony_ci                        irqFlag = 2;                                  // Values 1 and 2 indicate that the interrupt is triggered on the rising and falling edges, respectively. Values 4 and 8 indicate that the interrupt is triggered by the high and low levels, respectively.
167e41f4b71Sopenharmony_ci                        maxSpeed = 400;                               // Set the maximum communication rate to 400 Hz.
168e41f4b71Sopenharmony_ci                        chipVersion = 0;                              // Set the touchscreen IC version.
169e41f4b71Sopenharmony_ci                        powerSequence {
170e41f4b71Sopenharmony_ci                             /* Power-on sequence is described as follows:
171e41f4b71Sopenharmony_ci                               [Type, status, direction, delay]
172e41f4b71Sopenharmony_ci                               <type> Value 0 indicates the power or pin is empty. Values 1 and 2 indicate the VCC (1.8 V) and VCI (3.3 V) power, respectively. Values 3 and 4 indicate the reset and interrupt pins, respectively.
173e41f4b71Sopenharmony_ci                               <status> Values 0 and 1 indicate the power-off or pull-down, and the power-on or pull-up, respectively. Value 2 indicates that no operation is performed.
174e41f4b71Sopenharmony_ci                               <dir> Values 0 and 1 indicate the input and output directions, respectively. Value 2 indicates that no operation is performed.
175e41f4b71Sopenharmony_ci                               <delay> Delay time, in milliseconds.
176e41f4b71Sopenharmony_ci                             */
177e41f4b71Sopenharmony_ci                            powerOnSeq = [4, 0, 1, 0,                 // Set the output direction for the interrupt pin and pull down the pin.
178e41f4b71Sopenharmony_ci                                         3, 0, 1, 10,                 // Set the output direction for the reset pin and pull down the pin, with a delay of 10 ms.
179e41f4b71Sopenharmony_ci                                         3, 1, 2, 60,                 // No operation is performed on the reset pin. Pull up the pin, with a delay of 60 ms.
180e41f4b71Sopenharmony_ci                                         4, 2, 0, 0];                 // Set the input direction for the interrupt pin.
181e41f4b71Sopenharmony_ci                            suspendSeq = [3, 0, 2, 10];               // No operation is performed on the reset pin. Pull down the pin, with a delay of 10 ms.
182e41f4b71Sopenharmony_ci                            resumeSeq = [3, 1, 2, 10];                // No operation is performed on the reset pin. Pull up the pin, with a delay of 10 ms.
183e41f4b71Sopenharmony_ci                            powerOffSeq = [3, 0, 2, 10,               // No operation is performed on the reset pin. Pull down the pin, with a delay of 10 ms.
184e41f4b71Sopenharmony_ci                                           1, 0, 2, 20];              // No operation is performed on the positive pin. Pull down the pin, with a delay of 20 ms.
185e41f4b71Sopenharmony_ci                        }
186e41f4b71Sopenharmony_ci                    }
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci                    chip0 :: touchChip {
189e41f4b71Sopenharmony_ci                        match_attr = "zsj_gt911_5p5";                 // Keep this value the same as the match_attr field in the touchscreen private configuration data in the device description.
190e41f4b71Sopenharmony_ci                        chipInfo = "ZIDN45100";                       // The chip information is composed of the product name, module number, and chip number, used to identity the current touchscreen in user space.
191e41f4b71Sopenharmony_ci                        chipVersion = 0;                              // Set the IC model version.
192e41f4b71Sopenharmony_ci                    }
193e41f4b71Sopenharmony_ci                }
194e41f4b71Sopenharmony_ci            }
195e41f4b71Sopenharmony_ci        }
196e41f4b71Sopenharmony_ci    }
197e41f4b71Sopenharmony_ci}
198e41f4b71Sopenharmony_ci```
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ciIn the example, **touchConfig**  contains the **touch0**  configuration, which describes the **boardConfig**  and **chipConfig**  configuration information. The **boardConfig**  field provides the board-level hardware information of Hi3516D V300, and the **chipConfig**  field provides the private configuration data of the touchscreen. To use another touchscreen, you can change the value of the **chipConfig**  field. You can also configure multiple touchscreens for your product. In this example, **touch0**  represents the hardware interface and chip configuration of the default touchscreen. If you need to configure a secondary touchscreen, add a **touch1**  block parallel to **touch0**.
201e41f4b71Sopenharmony_ci
202e41f4b71Sopenharmony_ci### Adapting to the Private Drivers of the Touchscreen<a name="section17127331595"></a>
203e41f4b71Sopenharmony_ci
204e41f4b71Sopenharmony_ciThe input driver model abstracts the development process of input devices. You only need to adapt to the input chip driver without making any modifications for the input device manager and common driver.
205e41f4b71Sopenharmony_ci
206e41f4b71Sopenharmony_ciThe input driver model consists of three parts of drivers. To develop a brand-new touchscreen driver, you only need to adapt your code with the input chip driver and implement differentiated APIs. The sample code in this section illustrates how you will complete the adaptation.
207e41f4b71Sopenharmony_ci
208e41f4b71Sopenharmony_ci1.  Implement differentiated APIs for the touchscreen to adapt to the input chip driver.
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_ci    You can obtain the sample code at **./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c**.
211e41f4b71Sopenharmony_ci
212e41f4b71Sopenharmony_ci    ```
213e41f4b71Sopenharmony_ci    static struct TouchChipOps g_gt911ChipOps = {                                  // IC options of the touchscreen
214e41f4b71Sopenharmony_ci        .Init = ChipInit,                                                          // Initialize the chip.
215e41f4b71Sopenharmony_ci        .Detect = ChipDetect,                                                      // Detect the chip.
216e41f4b71Sopenharmony_ci        .Resume = ChipResume,                                                      // Resume the chip.
217e41f4b71Sopenharmony_ci        .Suspend = ChipSuspend,                                                    // Suspend the chip.
218e41f4b71Sopenharmony_ci        .DataHandle = ChipDataHandle,                                              // Read the chip data.
219e41f4b71Sopenharmony_ci        .UpdateFirmware = UpdateFirmware,                                          // Update the firmware.
220e41f4b71Sopenharmony_ci    };
221e41f4b71Sopenharmony_ci    
222e41f4b71Sopenharmony_ci    /* The ICs may be different depending on the touchscreen vendors, and the corresponding register operations are also different. Therefore, the code for the input chip driver focuses only on the adaptation of differentiated APIs. The following sample code demonstrates the data parsing of GT911. */
223e41f4b71Sopenharmony_ci    
224e41f4b71Sopenharmony_ci    static int32_t ChipDataHandle(ChipDevice *device)
225e41f4b71Sopenharmony_ci    {
226e41f4b71Sopenharmony_ci        ...
227e41f4b71Sopenharmony_ci        /* Read the status register before GT911 obtains coordinates. */
228e41f4b71Sopenharmony_ci        reg[0] = (GT_BUF_STATE_ADDR >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK; 
229e41f4b71Sopenharmony_ci        reg[1] = GT_BUF_STATE_ADDR & ONE_BYTE_MASK;
230e41f4b71Sopenharmony_ci        ret = InputI2cRead(i2cClient, reg, GT_ADDR_LEN, &touchStatus, 1);
231e41f4b71Sopenharmony_ci        if (ret < 0 || touchStatus == GT_EVENT_INVALID) {
232e41f4b71Sopenharmony_ci            return HDF_FAILURE;
233e41f4b71Sopenharmony_ci        }
234e41f4b71Sopenharmony_ci        ...
235e41f4b71Sopenharmony_ci        /* Read data from the data register based on the value of the status register. */
236e41f4b71Sopenharmony_ci        reg[0] = (GT_X_LOW_BYTE_BASE >> ONE_BYTE_OFFSET) & ONE_BYTE_MASK;
237e41f4b71Sopenharmony_ci        reg[1] = GT_X_LOW_BYTE_BASE & ONE_BYTE_MASK;
238e41f4b71Sopenharmony_ci        pointNum = touchStatus & GT_FINGER_NUM_MASK;
239e41f4b71Sopenharmony_ci        if (pointNum == 0 || pointNum > MAX_SUPPORT_POINT) {
240e41f4b71Sopenharmony_ci            HDF_LOGE("%s: pointNum is invalid, %u", __func__, pointNum);
241e41f4b71Sopenharmony_ci            (void)ChipCleanBuffer(i2cClient);
242e41f4b71Sopenharmony_ci            OsalMutexUnlock(&device->driver->mutex);
243e41f4b71Sopenharmony_ci            return HDF_FAILURE;
244e41f4b71Sopenharmony_ci        }
245e41f4b71Sopenharmony_ci        frame->realPointNum = pointNum;
246e41f4b71Sopenharmony_ci        frame->definedEvent = TOUCH_DOWN;
247e41f4b71Sopenharmony_ci        (void)InputI2cRead(i2cClient, reg, GT_ADDR_LEN, buf, GT_POINT_SIZE * pointNum);
248e41f4b71Sopenharmony_ci        /* Parse the obtained data. */
249e41f4b71Sopenharmony_ci        ParsePointData(device, frame, buf, pointNum);
250e41f4b71Sopenharmony_ci        ...
251e41f4b71Sopenharmony_ci    }
252e41f4b71Sopenharmony_ci    static void ParsePointData(ChipDevice *device, FrameData *frame, uint8_t *buf, uint8_t pointNum)
253e41f4b71Sopenharmony_ci    {
254e41f4b71Sopenharmony_ci        ...
255e41f4b71Sopenharmony_ci        /* Each coordinate value consists of two bytes. Obtain the final coordinate value by combining the obtained single-byte data. */
256e41f4b71Sopenharmony_ci        for (i = 0; i < pointNum; i++) {
257e41f4b71Sopenharmony_ci                frame->fingers[i].trackId = buf[GT_POINT_SIZE * i + GT_TRACK_ID];
258e41f4b71Sopenharmony_ci                frame->fingers[i].y = (buf[GT_POINT_SIZE * i + GT_X_LOW] & ONE_BYTE_MASK) |
259e41f4b71Sopenharmony_ci                                      ((buf[GT_POINT_SIZE * i + GT_X_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET);
260e41f4b71Sopenharmony_ci                frame->fingers[i].x = (buf[GT_POINT_SIZE * i + GT_Y_LOW] & ONE_BYTE_MASK) |
261e41f4b71Sopenharmony_ci                                      ((buf[GT_POINT_SIZE * i + GT_Y_HIGH] & ONE_BYTE_MASK) << ONE_BYTE_OFFSET);
262e41f4b71Sopenharmony_ci                /* Print the parsed coordinate value. */
263e41f4b71Sopenharmony_ci                HDF_LOGD("%s: x = %d, y = %d", __func__, frame->fingers[i].x, frame->fingers[i].y);
264e41f4b71Sopenharmony_ci         }
265e41f4b71Sopenharmony_ci    }
266e41f4b71Sopenharmony_ci    ```
267e41f4b71Sopenharmony_ci
268e41f4b71Sopenharmony_ci2.  Initialize the input chip driver and register the driver with the HDF.
269e41f4b71Sopenharmony_ci
270e41f4b71Sopenharmony_ci    You can obtain the sample code at **./drivers/framework/model/input/driver/touchscreen/touch\_gt911.c**.
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci    ```
273e41f4b71Sopenharmony_ci    static int32_t HdfGoodixChipInit(struct HdfDeviceObject *device)
274e41f4b71Sopenharmony_ci    {
275e41f4b71Sopenharmony_ci        ...
276e41f4b71Sopenharmony_ci        /* Use the chipCfg structure to allocate memory, parse the configuration information, and mount the parsed data. */
277e41f4b71Sopenharmony_ci        chipCfg = ChipConfigInstance(device);
278e41f4b71Sopenharmony_ci        ...
279e41f4b71Sopenharmony_ci        /* Instantiate the touchscreen device. */
280e41f4b71Sopenharmony_ci        chipDev = ChipDeviceInstance();
281e41f4b71Sopenharmony_ci        ...
282e41f4b71Sopenharmony_ci        /* Mount touchscreen chip configuration and private operation data. */
283e41f4b71Sopenharmony_ci        chipDev->chipCfg = chipCfg;
284e41f4b71Sopenharmony_ci        chipDev->ops = &g_gt911ChipOps;
285e41f4b71Sopenharmony_ci        ...
286e41f4b71Sopenharmony_ci        /* Register the chip driver with the platform driver. */
287e41f4b71Sopenharmony_ci        RegisterChipDevice(chipDev);
288e41f4b71Sopenharmony_ci        ...
289e41f4b71Sopenharmony_ci    }
290e41f4b71Sopenharmony_ci    struct HdfDriverEntry g_touchGoodixChipEntry = {
291e41f4b71Sopenharmony_ci        .moduleVersion = 1,
292e41f4b71Sopenharmony_ci         .moduleName = "HDF_TOUCH_GT911",   // The value must match the moduleName field of the chip driver in the device_info.hcs file.
293e41f4b71Sopenharmony_ci        .Init = HdfGoodixChipInit,         // Initialize the touchscreen chip driver.
294e41f4b71Sopenharmony_ci    };
295e41f4b71Sopenharmony_ci    HDF_INIT(g_touchGoodixChipEntry);      // Register the touchscreen chip driver with the HDF.
296e41f4b71Sopenharmony_ci    ```
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ci    The private chip drivers present the major differentiations among chip vendors, such as hibernation and wakeup, data parsing, and firmware update.
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ci    Now, you have completed the adaptation for the touchscreen driver based on the HDF and input driver model.
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ci
303e41f4b71Sopenharmony_ci## Building Source Code and Burning Images<a name="section16465031164711"></a>
304e41f4b71Sopenharmony_ci
305e41f4b71Sopenharmony_ci1.  Compile the Makefile.
306e41f4b71Sopenharmony_ci
307e41f4b71Sopenharmony_ci    Open the file at **./drivers/adapter/khdf/linux/model/input/Makefile**.
308e41f4b71Sopenharmony_ci
309e41f4b71Sopenharmony_ci    Add the following content:
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ci    ```
312e41f4b71Sopenharmony_ci    obj-$(CONFIG_DRIVERS_HDF_TP_5P5_GT911) += \
313e41f4b71Sopenharmony_ci                  $(INPUT_ROOT_DIR)/touchscreen/touch_gt911.o
314e41f4b71Sopenharmony_ci    ```
315e41f4b71Sopenharmony_ci
316e41f4b71Sopenharmony_ci    **touch\_gt911.o** is the content added in this example.
317e41f4b71Sopenharmony_ci
318e41f4b71Sopenharmony_ci2.  Build source code and burn images. For details, see the related sections in [Quick Start Overview](../quick-start/quickstart-overview.md).
319e41f4b71Sopenharmony_ci
320e41f4b71Sopenharmony_ci## Debugging and Verification<a name="section62577313482"></a>
321e41f4b71Sopenharmony_ci
322e41f4b71Sopenharmony_ciThe following is part of the startup log:
323e41f4b71Sopenharmony_ci
324e41f4b71Sopenharmony_ci```
325e41f4b71Sopenharmony_ci[I/HDF_INPUT_DRV] HdfInputManagerInit: enter                            // Initialize the input device manager.
326e41f4b71Sopenharmony_ci[I/HDF_INPUT_DRV] HdfInputManagerInit: exit succ                        // The initialization is successful.
327e41f4b71Sopenharmony_ci[I/osal_cdev] add cdev hdf_input_host success
328e41f4b71Sopenharmony_ci[I/HDF_LOG_TAG] HdfTouchDriverProbe: enter                              // Initialize the input common driver.
329e41f4b71Sopenharmony_ci[I/HDF_LOG_TAG] HdfTouchDriverProbe: main_touch exit succ               // The initialization is successful.
330e41f4b71Sopenharmony_ci[I/osal_cdev] add cdev hdf_input_event1 success
331e41f4b71Sopenharmony_ci[I/HDF_INPUT_DRV] HdfGoodixChipInit: enter                              // Initialize the input chip driver.
332e41f4b71Sopenharmony_ci[I/HDF_INPUT_DRV] ChipDetect: IC FW version is 0x1060
333e41f4b71Sopenharmony_ci[I/HDF_INPUT_DRV] Product_ID: 911_1060, x_sol = 960, y_sol = 480
334e41f4b71Sopenharmony_ci[I/HDF_LOG_TAG] ChipDriverInit: chipDetect succ, ret = 0
335e41f4b71Sopenharmony_ci[I/HDF_LOG_TAG] InputDeviceInstance: inputDev->devName = main_touch
336e41f4b71Sopenharmony_ci[I/HDF_INPUT_DRV] HdfGoodixChipInit: exit succ, chipName = gt911        // The initialization is successful.
337e41f4b71Sopenharmony_ci```
338e41f4b71Sopenharmony_ci
339e41f4b71Sopenharmony_ci## Input Driver Model Workflow Analysis<a name="section1578569154917"></a>
340e41f4b71Sopenharmony_ci
341e41f4b71Sopenharmony_ciTo help you get familiarized with the working process of the input driver model, the following sections will describe the key code loaded by the input driver model.
342e41f4b71Sopenharmony_ci
343e41f4b71Sopenharmony_ci>![](../public_sys-resources/icon-notice.gif) **NOTICE:** 
344e41f4b71Sopenharmony_ci>You do not need to perform development related to the input driver model.
345e41f4b71Sopenharmony_ci
346e41f4b71Sopenharmony_ci### Parsing Private Configuration Data<a name="section1310113815495"></a>
347e41f4b71Sopenharmony_ci
348e41f4b71Sopenharmony_ciYou can obtain the sample code at  **./drivers/framework/model/input/driver/input\_config\_parser.c**.
349e41f4b71Sopenharmony_ci
350e41f4b71Sopenharmony_ciThe configuration parsing functions provided by the OSAL can parse the fields in the  **hcs**  file. For details, see the implementation of each function in  **input\_config\_parser.c**. If the provided template cannot meet business requirements, add required information to the  **hcs**  file and then develop parsing functions based on the added fields.
351e41f4b71Sopenharmony_ci
352e41f4b71Sopenharmony_ci```
353e41f4b71Sopenharmony_cistatic int32_t ParseAttr(struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode, BoardAttrCfg *attr)
354e41f4b71Sopenharmony_ci{
355e41f4b71Sopenharmony_ci    int32_t ret;
356e41f4b71Sopenharmony_ci    ret = parser->GetUint8(attrNode, "inputType", &attr->devType, 0);     // Obtain the inputType field and save it in the BoardAttrCfg structure.
357e41f4b71Sopenharmony_ci    CHECK_PARSER_RET(ret, "GetUint8");
358e41f4b71Sopenharmony_ci    ...
359e41f4b71Sopenharmony_ci    return HDF_SUCCESS;
360e41f4b71Sopenharmony_ci}
361e41f4b71Sopenharmony_ci```
362e41f4b71Sopenharmony_ci
363e41f4b71Sopenharmony_ci### Initializing the Input Device Manager and Registering the Driver with the HDF<a name="section614512119500"></a>
364e41f4b71Sopenharmony_ci
365e41f4b71Sopenharmony_ciYou can obtain the sample code at  **./drivers/framework/model/input/driver/hdf\_input\_device\_manager.c**.
366e41f4b71Sopenharmony_ci
367e41f4b71Sopenharmony_ci```
368e41f4b71Sopenharmony_cistatic int32_t HdfInputManagerInit(struct HdfDeviceObject *device)
369e41f4b71Sopenharmony_ci{ 
370e41f4b71Sopenharmony_ci    /* Allocate memory to the device manager, which will store all input devices. */
371e41f4b71Sopenharmony_ci    g_inputManager = InputManagerInstance();
372e41f4b71Sopenharmony_ci    ...
373e41f4b71Sopenharmony_ci}
374e41f4b71Sopenharmony_cistruct HdfDriverEntry g_hdfInputEntry = {
375e41f4b71Sopenharmony_ci    .moduleVersion = 1,
376e41f4b71Sopenharmony_ci    .moduleName = "HDF_INPUT_MANAGER",
377e41f4b71Sopenharmony_ci    .Bind = HdfInputManagerBind,
378e41f4b71Sopenharmony_ci    .Init = HdfInputManagerInit,
379e41f4b71Sopenharmony_ci    .Release = HdfInputManagerRelease,
380e41f4b71Sopenharmony_ci};
381e41f4b71Sopenharmony_ci
382e41f4b71Sopenharmony_ciHDF_INIT(g_hdfInputEntry);                                               // Driver input entry
383e41f4b71Sopenharmony_ci```
384e41f4b71Sopenharmony_ci
385e41f4b71Sopenharmony_ci### Initializing the Input Common Driver and Registering the Driver with the HDF<a name="section16194201755019"></a>
386e41f4b71Sopenharmony_ci
387e41f4b71Sopenharmony_ciYou can obtain the sample code at  **./drivers/framework/model/input/driver/hdf\_touch.c**.
388e41f4b71Sopenharmony_ci
389e41f4b71Sopenharmony_ci```
390e41f4b71Sopenharmony_cistatic int32_t HdfTouchDriverProbe(struct HdfDeviceObject *device)
391e41f4b71Sopenharmony_ci{
392e41f4b71Sopenharmony_ci    ...
393e41f4b71Sopenharmony_ci    /* Use the boardCfg structure to allocate memory and parse the configuration information obtained from the HCS. */
394e41f4b71Sopenharmony_ci    boardCfg = BoardConfigInstance(device);
395e41f4b71Sopenharmony_ci    ...
396e41f4b71Sopenharmony_ci    /* Allocate memory in the touchDriver structure. */
397e41f4b71Sopenharmony_ci    touchDriver = TouchDriverInstance();
398e41f4b71Sopenharmony_ci    ...
399e41f4b71Sopenharmony_ci    /* Initialize common resources based on the parsed board-level information, such as IIC initialization. */
400e41f4b71Sopenharmony_ci    ret = TouchDriverInit(touchDriver, boardCfg);
401e41f4b71Sopenharmony_ci    if (ret == HDF_SUCCESS) {
402e41f4b71Sopenharmony_ci        ...
403e41f4b71Sopenharmony_ci        /* Add the driver to the common driver management linked list, which is used to query the driver after it is bound to the device. */
404e41f4b71Sopenharmony_ci        AddTouchDriver(touchDriver);
405e41f4b71Sopenharmony_ci        ...
406e41f4b71Sopenharmony_ci    }
407e41f4b71Sopenharmony_ci    ...
408e41f4b71Sopenharmony_ci}
409e41f4b71Sopenharmony_cistruct HdfDriverEntry g_hdfTouchEntry = {
410e41f4b71Sopenharmony_ci    .moduleVersion = 1,
411e41f4b71Sopenharmony_ci    .moduleName = "HDF_TOUCH",
412e41f4b71Sopenharmony_ci    .Bind = HdfTouchDriverBind,
413e41f4b71Sopenharmony_ci    .Init = HdfTouchDriverProbe,
414e41f4b71Sopenharmony_ci    .Release = HdfTouchDriverRelease,
415e41f4b71Sopenharmony_ci};
416e41f4b71Sopenharmony_ci                               
417e41f4b71Sopenharmony_ci HDF_INIT(g_hdfTouchEntry);                                              // Driver input entry
418e41f4b71Sopenharmony_ci```
419e41f4b71Sopenharmony_ci
420e41f4b71Sopenharmony_ci### Initializing the Input Chip Driver and Registering the Driver with the HDF<a name="section1090743312505"></a>
421e41f4b71Sopenharmony_ci
422e41f4b71Sopenharmony_ciFor details, see related content in  [Adapting to the Private Drivers of the Touchscreen](#section17127331595).
423e41f4b71Sopenharmony_ci
424e41f4b71Sopenharmony_ci### Function Invocation Logic<a name="section81801147529"></a>
425e41f4b71Sopenharmony_ci
426e41f4b71Sopenharmony_ciThe init function of the input device manager initializes the device management linked list, and the init function of the common driver allocates memory for related structures. The  **RegisterChipDevice**  function passes touchscreen chip driver information to the related structures of the input common driver and initializes hardware information \(for example, interrupt registration\). The  **RegisterInputDevice**  function registers  **inputDev**  \(binding the device and the driver\) with the device manager. The  **RegisterInputDevice**  function adds  **inputDev**  to the device management linked list. The function implementation is as follows:
427e41f4b71Sopenharmony_ci
428e41f4b71Sopenharmony_ci```
429e41f4b71Sopenharmony_ci// Code location: ./drivers/framework/model/input/driver/hdf_touch.c
430e41f4b71Sopenharmony_ciint32_t RegisterChipDevice(ChipDevice *chipDev)
431e41f4b71Sopenharmony_ci{
432e41f4b71Sopenharmony_ci    ...
433e41f4b71Sopenharmony_ci    /* Bind the device to the driver and create an inputDev instance using InputDeviceInstance. */
434e41f4b71Sopenharmony_ci    DeviceBindDriver(chipDev);
435e41f4b71Sopenharmony_ci    ...
436e41f4b71Sopenharmony_ci    /* Implement the interrupt registration and interrupt handling functions. The interrupt handling function contains the channel for reporting data to the user space. */
437e41f4b71Sopenharmony_ci    ChipDriverInit(chipDev);
438e41f4b71Sopenharmony_ci    ...
439e41f4b71Sopenharmony_ci    /* Allocate memory for instantiating inputDev. */
440e41f4b71Sopenharmony_ci    inputDev = InputDeviceInstance(chipDev);
441e41f4b71Sopenharmony_ci    ...
442e41f4b71Sopenharmony_ci    /* Register inputDev with the input device manager. */
443e41f4b71Sopenharmony_ci    RegisterInputDevice(inputDev);
444e41f4b71Sopenharmony_ci    ...
445e41f4b71Sopenharmony_ci}
446e41f4b71Sopenharmony_ci
447e41f4b71Sopenharmony_ci// Code location: ./drivers/framework/model/input/driver/hdf_input_device_manager.c
448e41f4b71Sopenharmony_ciint32_t RegisterInputDevice(InputDevice *inputDev)
449e41f4b71Sopenharmony_ci{
450e41f4b71Sopenharmony_ci    ...
451e41f4b71Sopenharmony_ci    /* Allocate a device ID, which is unique for each input device. */
452e41f4b71Sopenharmony_ci    ret = AllocDeviceID(inputDev);
453e41f4b71Sopenharmony_ci    ...
454e41f4b71Sopenharmony_ci    /* This function contains special processing for hid devices but does nothing for the touchscreen driver. */
455e41f4b71Sopenharmony_ci    CreateDeviceNode(inputDev);
456e41f4b71Sopenharmony_ci    /* Apply for the buffer for the IOService capability, which is required to transmit kernel-space data to the user space. */
457e41f4b71Sopenharmony_ci    AllocPackageBuffer(inputDev);
458e41f4b71Sopenharmony_ci    /* Add the input device to the global device management linked list. */
459e41f4b71Sopenharmony_ci    AddInputDevice(inputDev);
460e41f4b71Sopenharmony_ci    ...
461e41f4b71Sopenharmony_ci}
462e41f4b71Sopenharmony_ci```
463e41f4b71Sopenharmony_ci
464