本文环境
- mt6797
- kernel 3.18
- android 6.0
DTS设置
&eintc {
irq_my_irq@3 {
compatible = "eint, my-irq";
interrupt-parent = <&eintc>;
interrupts = <65 IRQ_TYPE_EDGE_RISING>;
debounce = <65 0>;
};
irq_my_gpio@3 {
compatible = "eint, my-gpio";
interrupt-parent = <&eintc>;
interrupts = <179 IRQ_TYPE_EDGE_RISING>;
debounce = <179 0>;
};
};
{
//...
pinctrl-names = "default", "my_irq_as_int", "nor_irq_as_gpio";
pinctrl-0 = <&pins_default>;
pinctrl-1 = <&pins_my_irq_as_int>;
pinctrl-2 = <&pins_normal_irq_as_gpio>;
};
&pio {
pins_default: eint0default {
};
pins_my_irq_as_int: eint@0 {
pins_cmd_dat {
pins = <PINMUX_GPIO65__FUNC_EINT4>;
slew-rate = <0>;
bias-disable;
};
};
pins_normal_irq_as_gpio: normal_irq_as_gpio@0 {
pins_cmd_dat {
pins = <PINMUX_GPIO179__FUNC_GPIO179>;
slew-rate = <0>;
bias-disable;
};
};
};
driver配置
struct pinctrl *my_pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *my_irq_as_int, *nor_irq_as_gpio;
int parse_dt(struct platform_device *pdev)
{
my_pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(my_pinctrl)) {
ret = PTR_ERR(my_pinctrl);
dev_err(&pdev->dev, "failed to find pinctrl!\n");
return ret;
}
pins_default = pinctrl_lookup_state(my_pinctrl, "default");
if (IS_ERR(pins_default)) {
ret = PTR_ERR(pins_default);
dev_err(&pdev->dev, "cannot find default: %d!\n", ret);
}
my_irq_as_int= pinctrl_lookup_state(my_pinctrl, "my_irq_as_int");
if (IS_ERR(my_irq_as_int)) {
ret = PTR_ERR(my_irq_as_int);
dev_err(&pdev->dev, "cannot find my_irq_as_int\n");
return ret;
}
nor_irq_as_gpio = pinctrl_lookup_state(my_pinctrl, "nor_irq_as_gpio");
}
int my_probe(*dev)
{
pinctrl_select_state(my_pinctrl, eint_as_int);
pinctrl_select_state(my_pinctrl, nor_irq_as_gpio);
}
static struct of_device_id my_irq_match[] = {
{.compatible = "eint,my-irq", },
};
static struct of_device_id my_gpio_match[] = {
{.compatible = "eint,my-gpio", },
};
static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
return IRQ_HANDLED;
}
int my_register_irq(void)
{
struct device_node *node = NULL;
int ret = 0;
int irq;
node = of_find_matching_node(node, my_irq_match);
if (NULL == node) {
pr_err("Can not find eint node!");
return -ENODATA;
}
irq = irq_of_parse_and_map(node, 0);
pr_debug("%s irq: %d", my_irq_match->compatible, irq);
ret = request_irq(irq, my_irq_handler,
IRQF_TRIGGER_FALLING, "my-irq", NULL);
return ret;
}
#define GPIO_MY_IRQ_GPIO (GPIO179)
int my_register_irq_gpio(void)
{
struct device_node *node = NULL;
int ret = 0;
int irq;
int gpio = GPIO_MY_IRQ_GPIO;
if (gpio_is_valid(gpio)) {
ret = gpio_request(gpio, "irq_gpio");
if (ret) {
pr_err("irq gpio request failed");
}
ret = gpio_direction_input(gpio);
if (ret) {
pr_err("set_direction for irq gpio failed");
}
} else {
pr_err("gpio: %d invalid", gpio);
}
node = of_find_matching_node(node, my_gpio_match);
if (NULL == node) {
pr_err("Can not find eint node!");
return -ENODATA;
}
irq = irq_of_parse_and_map(node, 0);
pr_debug("%s irq: %d", my_gpio_match->compatible, irq);
ret = request_irq(irq, my_irq_handler,
IRQF_TRIGGER_FALLING, "my-gpio-irq", NULL);
return ret;
}