mtk 平台 TP 驱动框架对触摸 IC 的复位和中断进行了封装,并提供了统一的操作方式。下面以 MT8788 为例介绍有关的知识点。
1、内核 dts 文件中 TP 复位和中断的配置:
(1)平台 dts 文件中 touch 节点用于和 TP 框架的绑定
kernel-4.14/arch/arm64/boot/dts/mediatek/mt6771.dts:
touch: touch {
compatible = "mediatek,touch";
};
(2)项目 dts 文件中复位和中断的配置
kernel-4.14/arch/arm64/boot/dts/mediatek/tb8788p1_64_bsp.dts:
&touch {
... // 省略部分代码
pinctrl-names = "default", "state_eint_as_int", "state_eint_output0",
"state_eint_output1", "state_rst_output0", "state_rst_output1";
pinctrl-0 = <&ctp_pins_default>;
pinctrl-1 = <&ctp_pins_eint_as_int>;
pinctrl-2 = <&ctp_pins_eint_output0>;
pinctrl-3 = <&ctp_pins_eint_output1>;
pinctrl-4 = <&ctp_pins_rst_output0>;
pinctrl-5 = <&ctp_pins_rst_output1>;
status = "okay";
};
&pio {
... // 省略部分代码
ctp_pins_default: eint0default {
};
ctp_pins_eint_as_int: eint@0 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO11__FUNC_GPIO11>;
slew-rate = <0>;
bias-disable;
};
};
ctp_pins_eint_output0: eintoutput0 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO11__FUNC_GPIO11>;
slew-rate = <1>;
output-low;
};
};
ctp_pins_eint_output1: eintoutput1 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO11__FUNC_GPIO11>;
slew-rate = <1>;
output-high;
};
};
ctp_pins_rst_output0: rstoutput0 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO12__FUNC_GPIO12>;
slew-rate = <1>;
output-low;
};
};
ctp_pins_rst_output1: rstoutput1 {
pins_cmd_dat {
pinmux = <PINMUX_GPIO12__FUNC_GPIO12>;
slew-rate = <1>;
output-high;
};
};
... // 省略部分代码
};
2、TP 驱动框架对复位和中断的封装
(1)定义 of_device_id 数组 touch_of_match,用于和设备的绑定
kernel-4.14/drivers/input/touchscreen/mediatek/mtk_tpd.c:
const struct of_device_id touch_of_match[] = {
{ .compatible = "mediatek,touch", },
};
(2) 获取复位和中断的 pinctrl 和 pinctrl_state
kernel-4.14/drivers/input/touchscreen/mediatek/mtk_tpd.c:
struct pinctrl *pinctrl1;
struct pinctrl_state *pins_default;
struct pinctrl_state *eint_as_int, *eint_output0, *eint_output1, *rst_output0, *rst_output1;
int tpd_get_gpio_info(struct platform_device *pdev)
{
int ret;
pinctrl1 = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(pinctrl1)) {
ret = PTR_ERR(pinctrl1);
dev_info(&pdev->dev, "fwq Cannot find pinctrl1!\n");
return ret;
}
pins_default = pinctrl_lookup_state(pinctrl1, "default");
if (IS_ERR(pins_default)) {
ret = PTR_ERR(pins_default);
TPD_DMESG("Cannot find pinctrl default %d!\n", ret);
}
eint_as_int = pinctrl_lookup_state(pinctrl1, "state_eint_as_int");
if (IS_ERR(eint_as_int)) {
ret = PTR_ERR(eint_as_int);
TPD_DMESG("Cannot find pinctrl state_eint_as_int!\n");
return ret;
}
eint_output0 = pinctrl_lookup_state(pinctrl1, "state_eint_output0");
if (IS_ERR(eint_output0)) {
ret = PTR_ERR(eint_output0);
TPD_DMESG("Cannot find pinctrl state_eint_output0!\n");
return ret;
}
eint_output1 = pinctrl_lookup_state(pinctrl1, "state_eint_output1");
if (IS_ERR(eint_output1)) {
ret = PTR_ERR(eint_output1);
TPD_DMESG("Cannot find pinctrl state_eint_output1!\n");
return ret;
}
... // 省略部分代码
}
(3)定义两个接口函数,参数 pin 为 0 时对复位进行操作,为 1 时对中断进行操作
kernel-4.14/drivers/input/touchscreen/mediatek/mtk_tpd.c:
void tpd_gpio_as_int(int pin)
{
mutex_lock(&tpd_set_gpio_mutex);
if (pin == 1)
pinctrl_select_state(pinctrl1, eint_as_int);
mutex_unlock(&tpd_set_gpio_mutex);
}
void tpd_gpio_output(int pin, int level)
{
mutex_lock(&tpd_set_gpio_mutex);
if (pin == 1) {
if (level)
pinctrl_select_state(pinctrl1, eint_output1);
else
pinctrl_select_state(pinctrl1, eint_output0);
} else {
if (level)
pinctrl_select_state(pinctrl1, rst_output1);
else
pinctrl_select_state(pinctrl1, rst_output0);
}
mutex_unlock(&tpd_set_gpio_mutex);
}
3、使用 TP 框架编写 TP 驱动,以 focaltech IC 为例
(1)根据 TP 框架的要求,驱动对 reset_gpio 和 irq_gpio 进行赋值
static void fts_platform_data_init(struct fts_ts_data *ts_data)
{
... // 省略部分代码
pdata->reset_gpio = 0;
pdata->irq_gpio = 1;
... // 省略部分代码
}
(2)中断注册函数调用 tpd_gpio_as_int 函数
static int fts_irq_registration(struct fts_ts_data *ts_data)
{
int ret = 0;
struct device_node *node = NULL;
// 通过 TP 框架的 touch_of_match 来查找指定的节点
node = of_find_matching_node(node, touch_of_match);
if (NULL == node) {
return -ENODATA;
}
ts_data->thread_tpd = kthread_run(touch_event_handler, 0, TPD_DEVICE);
if (IS_ERR_OR_NULL(ts_data->thread_tpd)) {
ret = PTR_ERR(ts_data->thread_tpd);
ts_data->thread_tpd = NULL;
return ret;
}
// 将中断 pin 设置为中断状态
tpd_gpio_as_int(ts_data->pdata->irq_gpio);
ts_data->irq = irq_of_parse_and_map(node, 0);
ts_data->pdata->irq_gpio_flags = IRQF_TRIGGER_FALLING;
ret = request_irq(ts_data->irq, fts_irq_handler,
ts_data->pdata->irq_gpio_flags, FTS_DRIVER_NAME, ts_data);
fts_irq_enable();
return ret;
}
(3)复位函数调用 tpd_gpio_output 函数
int fts_reset_proc(void)
{
// 复位 pin 输出低电平
tpd_gpio_output(fts_data->pdata->reset_gpio, 0);
msleep(1);
// 复位 pin 输出高电平
tpd_gpio_output(fts_data->pdata->reset_gpio, 1);
msleep(200);
return 0;
}
以上介绍了 mtk 平台 TP 驱动框架对触摸 IC 复位和中断的封装,并以 focaltech IC 为例介绍了其在 TP 驱动中的使用。