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