In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces "what is the programming method of capacitive touch screen under Linux". In daily operation, I believe that many people have doubts about the programming method of capacitive touch screen under Linux. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "what is the programming method of capacitive touch screen under Linux". Next, please follow the editor to study!
54.2 hardware schematic
In this experiment, we use the 7-inch screen of Xunwei as an example, using the FT5426 touch chip.
It is known from the schematic that the 7-inch screen uses I2C2, the touch screen reset pin is SNVS_TAMPER9, and the interrupt pin is GPIO_9.
54.3 Experimental programming
54.3.1 modify the device tree file
1. Add the pinctrl information of FT5426
The FT5426 touch chip uses four IO, one reset IO, one interrupt IO, I2C2 SCL and SDA, so we need to add IO related information to the device tree first. Reset IO and interrupt IO are ordinary GPIO, so the two IO can be described under the same node. The SCL and SDA of I2C2 belong to I2C2, so they should be described under the same node. First, there is a node named "pinctrl_tsc" by default in the reset IO and interrupt IO,topeet_emmc_4_3.dts file. If it is deleted, create it by yourself. Add the reset IO and interrupt IO information of the touchscreen under this node. The modified "pinctrl_tsc" node is as follows:
1 pinctrl_tsc: tscgrp {
2 fsl,pins =
< 3 MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x10B0 /* TSC_RST */ 4 MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0xF080 /* TSC_INT */ 5 >6}
Continue to add the IO information of SCL and SDA of I2C2. The IO information of I2C2 has been added by default in topeet_emmc_4_3.dts, which is officially added by NXP, so there is no need for us to modify it. Locate the "pinctrl_i2c1" node, which is the IO information used to describe the I2C2. The node content is as follows:
1 pinctrl_i2c2: i2c2grp {
2 fsl,pins =
< 3 MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 4 MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0 5 >6}
Finally, check to see if these four pins are used by other peripherals. If there is, it needs to be blocked.
2. Add a FT5426 node
The touch IC of FT5426 is mounted under the I2C2, so you need to add a child node under the I2C2 node, which is used to describe the FT5426. The content of the I2C2 node after the addition is as follows:
1 & i2c2 {
2 clock_frequency =
3 pinctrl-names = "default"
4 pinctrl-0 =
5 status = "okay"
six
7 / * /
8 / * omit other device nodes * /
9 / * /
ten
eleven
12 ft5426: ft5426@38 {
13 compatible = "edt,edt-ft5426"
14 reg =
15 pinctrl-names = "default"
16 pinctrl-0 =
17 interrupt-parent =
18 interrupts =
19 reset-gpios =
20 interrupt-gpios =
21}
22}
Line 12, the FT5426 chip node used by the touch screen, under the mount I2C2 node, the device address of the FT5426 is 0X38.
In line 14, the reg attribute describes the device address of the FT5426 as 0x38.
In line 16, the pinctrl-0 attribute describes that the node used by FT5426's reset IO and interrupt IO is pinctrl_tsc.
In line 17, the interrupt-parent attribute describes that the GPIO group corresponding to the interrupt IO is GPIO1.
In line 18, the interrupts attribute describes that the interrupt IO corresponds to the IOI09 of the GPIO1 group.
In line 19, the reset-gpios attribute describes that the GPIO corresponding to the reset IO is GPIO5_IO09.
In line 20, the interrupt-gpios attribute describes that the GPIO corresponding to the interrupt IO is GPIO1_IO09.
54.3.2 write multi-point capacitive touch driver
This lab routine path: i.MX6UL Terminator CD material / 06_Linux driver routine / 20_multitouch
Create a ft5426.c driver file as follows:
1 # include
2 # include
3 # include
4 # include
5 # include
6 # include
7 # include
8 # include
9 # include
10 # include
11 # include
12 # include
13 # include
14 # include
15 # include
sixteen
17 # define MAX_SUPPORT_POINTS 5 / * 5 touch * /
18 # define TOUCH_EVENT_DOWN 0x00 / * Press * /
19 # define TOUCH_EVENT_UP 0x01 / * lift * /
20 # define TOUCH_EVENT_ON 0x02 / * contact * /
21 # define TOUCH_EVENT_RESERVED 0x03 / * reserved * /
twenty-two
23 / * FT5X06 register related macro definition * /
24 # define FT5X06_TD_STATUS_REG 0X02 / * status register address * /
25 # define FT5x06_DEVICE_MODE_REG 0X00 / * mode register * /
26 # define FT5426_IDG_MODE_R 0XA4 / * interrupt mode * /
27 # define FT5X06_READLEN 29 / * number of registers to read * /
twenty-eight
29 struct ft5x06_dev {
30 struct device_node * nd; / * device node * /
31 int irq_pin,reset_pin; / * interrupt and reset IO * /
32 int irqnum; / * interrupt number * /
33 void * private_data; / * Private data * /
34 struct input_dev * input; / * input structure * /
35 struct i2c_client * client; / * I2C client * /
36}
thirty-seven
38 static struct ft5x06_dev ft5x06
thirty-nine
40 / *
41 * @ description: reset FT5X06
42 * @ param-client: i2C to be operated
43 * @ param-multidev: custom multitouch device
44 * @ return: 0, success; other negative values, failure
45 * /
46 static int ft5x06_ts_reset (struct i2c_client * client, struct ft5x06_dev * dev)
47 {
48 int ret = 0
forty-nine
50 if (gpio_is_valid (dev- > reset_pin)) {/ * check whether IO is valid * /
51 / * apply for reset IO and output low level by default * /
52 ret = devm_gpio_request_one (& client- > dev
53 dev- > reset_pin, GPIOF_OUT_INIT_LOW
54 "edt-ft5x06 reset")
55 if (ret) {
56 return ret
57}
fifty-eight
59 msleep (5)
60 gpio_set_value (dev- > reset_pin, 1); / * output high level, stop reset * /
61 msleep
62}
sixty-three
64 return 0
65}
sixty-six
67 / *
68 * @ description: read multiple register data from FT5X06
69 * @ param-dev: ft5x06 device
70 * @ param-reg: the first address of the register to read
71 * @ param-val: read data
72 * @ param-len: length of data to read
73 * @ return: operation result
74 * /
75 static int ft5x06_read_regs (struct ft5x06_dev * dev, U8 reg, void * val, int len)
76 {
77 int ret
78 struct i2c_msg msg [2]
79 struct i2c_client * client = (struct i2c_client *) dev- > client
eighty
81 / * msg [0] is the first address to be sent for reading * /
82 msg [0] .addr = client- > addr; / * ft5x06 address * /
83 msg [0] .flags = 0; / * marked to send data * /
84 msg [0] .buf = ®/ * read first address * /
85 msg [0] .len = 1; / * reg length * /
eighty-six
87 / * msg [1] read data * /
88 msg [1] .addr = client- > addr; / * ft5x06 address * /
89 msg [1] .flags = I2C read data RD; / * marked to read data * /
90 msg [1] .buf = val; / * read data buffer * /
91 msg [1] .len = len; / * length of data to be read * /
ninety-two
93 ret = i2c_transfer (client- > adapter, msg, 2)
94 if (ret = = 2) {
95 ret = 0
96} else {
97 ret =-EREMOTEIO
98}
99 return ret
100}
one hundred and one
102 / *
103 * @ description: write data to multiple registers of ft5x06
104 * @ param-dev: ft5x06 device
105 * @ param-reg: the first address of the register to be written
106 * @ param-val: the data buffer to write to
107 * @ param-len: the length of data to write
108 * @ return: operation result
109 * /
110 static S32 ft5x06_write_regs (struct ft5x06_dev * dev, U8 reg, U8 * buf, U8 len)
111 {
112 u8 b [256]
113 struct i2c_msg msg
114 struct i2c_client * client = (struct i2c_client *) dev- > client
one hundred and fifteen
116b [0] = reg; / * first register address * /
Memcpy (& b [1], buf,len); / * copy the data to be written into array b * /
one hundred and eighteen
Msg.addr = client- > addr; / * ft5x06 address * /
120 msg.flags = 0; / * marked as write data * /
one hundred and twenty one
122 msg.buf = b; / * data buffer to be written * /
123 msg.len = len + 1; / * length of data to be written * /
one hundred and twenty four
125 return i2c_transfer (client- > adapter, & msg, 1)
126}
one hundred and twenty seven
128 / *
129@ description: writes the specified value to the ft5x06 specified register and writes a register
130 * @ param-dev: ft5x06 device
131 * @ param-reg: the register to be written
132 * @ param-data: the value to be written
133 * @ return: none
134 * /
135 static void ft5x06_write_reg (struct ft5x06_dev * dev, U8 reg, U8 data)
136 {
137u8 buf = 0
138buf = data
139 ft5x06_write_regs (dev, reg, & buf, 1)
140}
one hundred and forty one
142 / *
143@ description: FT5X06 interrupt service function
144 * @ param-irq: interrupt number
145 * @ param-dev_id: device structure.
146@ return: interrupt the execution result
147 * /
148static irqreturn_t ft5x06_handler (int irq, void * dev_id)
149 {
150 struct ft5x06_dev * multidata = dev_id
one hundred and fifty one
152 u8 rdbuf [29]
153 int i, type, x, y, id
154 int offset, tplen
155 int ret
156 bool down
one hundred and fifty seven
158 offset = 1; / * offset 1, that is, 0X02+1=0x03, which is the touch value from 0X03 * /
159 tplen = 6; / * A touchpoint has 6 registers to hold the touch value * /
one hundred and sixty
Memset (rdbuf, 0, sizeof (rdbuf)); / * clear * /
one hundred and sixty two
Reading FT5X06 touchpoint coordinates starts with the 0X02 register and reads 29 registers in a row * /
164ret = ft5x06_read_regs (multidata, FT5X06_TD_STATUS_REG
Rdbuf, FT5X06_READLEN)
165 if (ret) {
166 goto fail
167}
one hundred and sixty eight
169 / * report the coordinates of each touch point * /
170 for (I = 0; I
< MAX_SUPPORT_POINTS; i++) { 171 u8 *buf = &rdbuf[i * tplen + offset]; 172 173 /* 以第一个触摸点为例,寄存器 TOUCH1_XH(地址 0X03),各位描述如下: 174 * bit7:6 Event flag 0:按下 1:释放 2:接触 3:没有事件 175 * bit5:4 保留 176 * bit3:0 X 轴触摸点的 11~8 位。 177 */ 178 type = buf[0] >> 6; / * get the touch type * /
179 if (type = = TOUCH_EVENT_RESERVED)
180 continue
one hundred and eighty one
182 / * the touchscreen and FT5X06 we use are the reverse * /
183x = (buf [2] 4) & 0x0f
191 down = type! = TOUCH_EVENT_UP
one hundred and ninety two
193 input_mt_slot (multidata- > input, id)
194 input_mt_report_slot_state (multidata- > input, MT_TOOL_FINGER, down)
one hundred and ninety five
196 if (! down)
197 continue
one hundred and ninety eight
199 input_report_abs (multidata- > input, ABS_MT_POSITION_X, x)
200 input_report_abs (multidata- > input, ABS_MT_POSITION_Y, y)
201}
two hundred and two
203 input_mt_report_pointer_emulation (multidata- > input, true)
204 input_sync (multidata- > input)
two hundred and five
206 fail:
207 return IRQ_HANDLED
two hundred and eight
209}
two hundred and ten
211 / *
212 * @ description: FT5x06 interrupts initialization
213 * @ param-client: i2C to be operated
* @ param-multidev: custom multitouch device
215 * @ return: 0, success; other negative values, failure
216 * /
217 static int ft5x06_ts_irq (struct i2c_client * client, struct ft5x06_dev * dev)
218 {
219 int ret = 0
two hundred and twenty
221 / * 1, apply for interruption of GPIO * /
222 if (gpio_is_valid (dev- > irq_pin)) {
223 ret = devm_gpio_request_one (& client- > dev, dev- > irq_pin
224 GPIOF_IN, "edt-ft5x06 irq")
225 if (ret) {
& client- > dev dev_err
227 "Failed to request GPIO% d, error% d\ n"
228 dev- > irq_pin, ret)
229 return ret
230}
231}
two hundred and thirty two
Apply for interruption. Client- > irq means IO interruption, * /
234 ret = devm_request_threaded_irq (& client- > dev, client- > irq, NULL
235 ft5x06_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT
236 client- > name, & ft5x06)
237 if (ret) {
238 dev_err (& client- > dev, "Unable to request touchscreen IRQ.\ n")
239 return ret
240}
two hundred and forty one
242 return 0
243}
two hundred and forty four
245 / *
246 * @ description: the probe function of the i2C driver, when the driver is associated with
247 * this function will be executed after the device matches
248 * @ param-client: i2C device
249 * @ param-id: i2C device ID
250 * @ return: 0, success; other negative values, failure
251 * /
252 static int ft5x06_ts_probe (struct i2c_client * client, const struct i2c_device_id * id)
253 {
254 int ret = 0
two hundred and fifty five
256 ft5x06.client = client
two hundred and fifty seven
258 / * 1, get interrupt and reset pins in the device tree * /
259 ft5x06.irq_pin = of_get_named_gpio (client- > dev.of_node, "interrupt-gpios", 0)
260 ft5x06.reset_pin = of_get_named_gpio (client- > dev.of_node, "reset-gpios", 0)
two hundred and sixty one
262 / * 2, reset FT5x06 * /
263 ret = ft5x06_ts_reset (client, & ft5x06)
264 if (ret
< 0) { 265 goto fail; 266 } 267 268 /* 3,初始化中断 */ 269 ret = ft5x06_ts_irq(client, &ft5x06); 270 if(ret < 0) { 271 goto fail; 272 } 273 274 /* 4,初始化 FT5X06 */ 275 ft5x06_write_reg(&ft5x06, FT5x06_DEVICE_MODE_REG, 0); /* 进入正常模式*/ 276 ft5x06_write_reg(&ft5x06, FT5426_IDG_MODE_REG, 1); /* FT5426 中断模式 */ 277 278 /* 5,input 设备注册 */ 279 ft5x06.input = devm_input_allocate_device(&client->Dev)
280 if (! ft5x06.input) {
281 ret =-ENOMEM
282 goto fail
283}
Ft5x06.input- > name = client- > name
Ft5x06.input- > id.bustype = BUS_I2C
Ft5x06.input- > dev.parent = & client- > dev
two hundred and eighty seven
288 _ _ set_bit (EV_KEY, ft5x06.input- > evbit)
289 _ _ set_bit (EV_ABS, ft5x06.input- > evbit)
290 _ set_bit (BTN_TOUCH, ft5x06.input- > keybit)
two hundred and ninety one
292 input_set_abs_params (ft5x06.input, ABS_X, 0, 1024, 0, 0)
293 input_set_abs_params (ft5x06.input, ABS_Y, 0600, 0,0)
294 input_set_abs_params (ft5x06.input, ABS_MT_POSITION_X,0, 1024, 0,0)
295 input_set_abs_params (ft5x06.input, ABS_MT_POSITION_Y,0, 600,0,0)
296 ret = input_mt_init_slots (ft5x06.input, MAX_SUPPORT_POINTS, 0)
297 if (ret) {
298 goto fail
299}
three hundred
301 ret = input_register_device (ft5x06.input)
302 if (ret)
303 goto fail
three hundred and four
305 return 0
three hundred and six
307 fail:
308 return ret
309}
three hundred and ten
311 / *
312 * @ description: the remove function driven by i2C, which is executed when the i2c driver is removed
313 * @ param-client: i2C device
314 * @ return: 0, success; other negative values, failure
315 * /
316 static int ft5x06_ts_remove (struct i2c_client * client)
317 {
318 / * release input_dev * /
319 input_unregister_device (ft5x06.input)
320 return 0
321}
three hundred and twenty two
three hundred and twenty three
324 / *
325 * traditional driver matching table
326 * /
327 static const struct i2c_device_id ft5x06_ts_id [] = {
328 {"edt-ft5206", 0,}
329 {"edt-ft5426", 0,}
330 {/ * sentinel * /}
331}
three hundred and thirty two
333 / *
334 * device tree matching table
335 * /
336 static const struct of_device_id ft5x06_of_match [] = {
337 {.clients = "edt,edt-ft5206",}
338 {.clients = "edt,edt-ft5426",}
339 {/ * sentinel * /}
340}
three hundred and forty one
342 / * i2c driver structure * /
343 static struct i2c_driver ft5x06_ts_driver = {
344. Driver = {
Owner = THIS_MODULE
346. Name = "edt_ft5x06"
347. Of _ match_table = of_match_ptr (ft5x06_of_match)
348}
ID _ table = ft5x06_ts_id
350.probe = ft5x06_ts_probe
351. Remove = ft5x06_ts_remove
352}
three hundred and fifty three
354 / *
355 * @ description: driver entry function
356 * @ param: none
357 * @ return: none
358 * /
359 static int _ init ft5x06_init (void)
360 {
361 int ret = 0
three hundred and sixty two
363 ret = i2c_add_driver (& ft5x06_ts_driver)
three hundred and sixty four
365 return ret
366}
three hundred and sixty seven
368 / *
369 * @ description: drive exit function
370 * @ param: none
371 * @ return: none
372 * /
373 static void _ exit ft5x06_exit (void)
374 {
375 i2c_del_driver (& ft5x06_ts_driver)
376}
three hundred and seventy seven
378 module_init (ft5x06_init)
379 module_exit (ft5x06_exit)
380 MODULE_LICENSE ("GPL")
381 MODULE_AUTHOR ("topeet")
Line 29-36 defines a device structure that stores attribute information related to multi-point capacitive touch devices.
In line 38, define a global variable named ft5x06, whose type is the ft5x06_dev structure defined above.
Line 46-63, the ft5x06_ts_reset function, is used to initialize the FT5426 touch chip, which is actually setting the reset IO of the FT5426 to high level to prevent the chip from resetting. Note that the devm_gpio_request_one function is used on line 52 to request a reset of the IO, and the role of the "devm_" prefix has been explained in detail earlier. The resources requested by the API function with the prefix "devm_" do not need to be manually released by us, and will be processed by the kernel, so we do not need to release the IO manually when we uninstall the driver after using the devm_gpio_request_one function to apply for IO.
Line 73-98, the ft5x06_read_regs function, is used to continuously read FT5426 internal register data, which is the I2C read function.
Line 98-124, the ft5x06_write_regs function, is used to write continuous data to the FT5426 register, that is, the I2C write function.
Line 133-138, the ft5x06_write_reg function, a simple wrapper of the ft5x06_write_regs function, writes a piece of data to the FT5426 specified register for configuring FT5426.
Line 146-207, ft5x06_handler function, touch screen interrupt service function, the reporting of touch point coordinates is completed in this function. Line 162 reads all the touchpoint information register data of FT5426 through the ft5x06_read_regs function, starting with the address of 0X02, a total of 29 registers. The for loop on line 168-199 is to report the touchpoint coordinate data one by one, using Type B.
Timing, we have talked about this many times before. Finally, the SYN_REPORT event is reported through the input_sync function on line 202. If you understand the Type B timing explained earlier, then this function is easy to understand.
Line 215-241, the ft5x06_ts_irq function, initializes the interrupt IO for FT5426, and line 221 uses the devm_gpio_request_one function to request an interrupt IO. The 232nd exercise uses the function devm_request_threaded_irq to request an interrupt, and the interrupt handling function is ft5x06_handler.
Line 250-307, this function is executed when the I2C device matches the driver, and some initialization work is usually done in this function. Let's focus on line 277-299 about initializing input_dev devices, line 277-284 requesting and simply initializing input_dev. Lines 286 and 288 set the events to be reported by input_dev as EV_KEY and EV_ABS, and the button code to be reported as BTN_TOUCH. EV_KEY is a keystroke event that reports whether the touchscreen has been pressed, which is equivalent to treating the touchscreen as a button. EV_ABS is the touchpoint coordinate data, and BTN_TOUCH means that the press and lift of the touchscreen are used as BTN_TOUCH buttons. Line 2900293 calls the input_set_abs_params function to set EV_ABS events that need to be reported to ABS_X, ABS_Y, ABS_MT_POSITION_X and ABS_MT_POSITION_Y. Single touch needs to report ABS_X and ABS_Y, and for multi-touch needs to report ABS_MT_POSITION_X and
ABS_MT_POSITION_Y . Line 294 calls the input_mt_init_slots function to initialize slots, which is the maximum number of touch points. FT5426 is a 5-point capacitive touch chip, so there are five slot. Finally, the input_register_device function is called on line 299 to register the input_dev with the system.
Line 314-319, the ft5x06_ts_remove function executes when the driver is unloaded, because many of the previous resources are requested with the "devm_" prefix function, so there is no need to release them manually. This function only needs to call input_unregister_device to release the input_dev that was previously added to the kernel.
At the end of line 320, the rest is the I2C driver framework.
At this point, the study on "what is the programming method of capacitive touch screen under Linux" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.