最近有一个项目需要在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