最近有一个项目需要在HI3516DV300平台调通GT911触摸屏,调试前同事已经给了一份能正常跑起来的驱动,虽说能读到相关坐标信息,但是由于没有接入标准的linux输入设备接口,所以在应用时有困难。本来打算移植到标准接口,偶然发现kernel中竟然有该触摸屏的驱动代码,文件名为drivers/input/touchscreen/goodix.c,那就直接用这个啦!
先配置
x -> Device Drivers x x -> Input device support x x -> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y]) x x -> Touchscreens (INPUT_TOUCHSCREEN [=y])
然后设置设备树,我接的I2C7,修改 arch/arm/boot/dts/hi3516dv300-demb.dts文件
&i2c_bus7 { status = "okay"; clock-frequency = <100000>; gt911@14 { compatible = "goodix,gt911"; reg = <0x14>; interrupt-parent = <&gpio_chip3>; interrupts = <1 4>; touchscreen-inverted-x; touchscreen-inverted-y; irq-gpios = <&gpio_chip3 1 0>; reset-gpios = <&gpio_chip0 3 0>; }; }; touchscreen-inverted-x和 touchscreen-inverted-y是因为后面发现读的坐标是反的,所以加了这两句,具体规则参考
Documentation/devicetree/bindings/input/touchscreen/goodix.txt文件
编译后加载发现错误
Goodix-TS 7-0014: Direct firmware load for goodix_911_cfg.bin failed with error -2
这个错误大概是需要加载一个固件,但是我也没有,对比同事给驱动发现,固件有可能就是那个配置数组。所以修改drivers/input/touchscreen/goodix.c文件,在goodix_ts_probe函数中有一段
error = request_firmware_nowait(THIS_MODULE, true, ts->cfg_name, &client->dev, GFP_KERNEL, ts, goodix_config_cb); if (error) { dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", error); return error; }这个应该就是加载固件的函数,读到固件后调用goodix_config_cb函数写入配置
static void goodix_config_cb(const struct firmware *cfg, void *ctx) { struct goodix_ts_data *ts = ctx; int error; if (cfg) { /* send device configuration to the firmware */ error = goodix_send_cfg(ts, cfg); if (error) goto err_release_cfg; } goodix_configure_dev(ts); err_release_cfg: release_firmware(cfg); complete_all(&ts->firmware_loading_complete); }然后进入goodix_send_cfg函数
static int goodix_send_cfg(struct goodix_ts_data *ts, const struct firmware *cfg) { int error; error = goodix_check_cfg(ts, cfg); if (error) return error; error = goodix_i2c_write(ts->client, GOODIX_REG_CONFIG_DATA, cfg->data, cfg->size); if (error) { dev_err(&ts->client->dev, "Failed to write config data: %d", error); return error; } dev_dbg(&ts->client->dev, "Config sent successfully."); /* Let the firmware reconfigure itself, so sleep for 10ms */ usleep_range(10000, 11000); return 0; }很明显最后调用goodix_i2c_write函数将数据写入,那我们将这个加载固件函数注释掉,直接用goodix_i2c_write将数组数据写入。
对于Goodix-TS 7-0014: request IRQ failed: -22 错误,应该是设备树中断配置不对,但是我尝试修改后还是会有错误。这时又参考了那份旧驱动,发现旧驱动没有用中断,直接用的轮询的方式读取坐标。那就直接将中断改为轮询吧!
关于中断配置在goodix_configure_dev函数中调用,中断响应函数为goodix_ts_irq_handler,我们注释掉goodix_configure_dev
中关于中断的部分,然后创建一个线程调用goodix_ts_irq_handler函数就可以了。
修改后重新编译测试成功!
修改后的goodix.c文件下载地址https://download.csdn.net/download/weixin_41231656/12576530