MTK平台dts里添加中断pin

MTK平台dts里添加中断pin

在MTK dts里配置中断pin,有两种方式

一、驱动内申请中断

这种方式比较通用,dts配置pin脚为gpio mode,在驱动内通过API申请中断。
例如使用GPIO7作为芯片中断

  1. dts内配置节点:
 test: test@41 {
		compatible = "test";
		reg = <0x41>; /* x41 for HW */
		pinctrl-names = "default";
		pinctrl-0 = <&irq_default>;
		irq-gpios = <&pio 7 GPIO_ACTIVE_LOW>;
	};
  1. 配置gpio7的pinctrl设置为输入,内部上拉
irq_default: irqdefault {
	d_pin_irq: pin_irq {
		pinmux = <PINMUX_GPIO7__FUNC_GPIO7>;
		input-enable;
		bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
	};
};
  1. 驱动内解析gpio并使用API申请中断
	struct gpio_desc *irq_gpiopin;
	int irq;
	/* Setup irq if gpio is provided */
	irq_gpiopin = devm_gpiod_get(card->dev, "irq", GPIOD_IN);
	/*获取中断号*/
	irq = gpiod_to_irq(irq_gpiopin);
	/*申请下降沿中断
	并注册中断回调函数irq_callback_func*/
	ret = request_irq(irq, irq_callback_func,
		  IRQF_TRIGGER_FALLING, "irq-eint", dev);

在中断回调函数内加入自己的逻辑即可。

二、dts内指定中断

这个方式适用于platform device、spi device、i2c device,中断资源会在解析设备树dtb时进行解析并申请,保存申请的中断号。

2.1 对于platform_device

一个节点能被转换为platform_device,如果它的设备树里指定了中断属性,那么可以从platform_device中获得“中断资源”,函数如下,可以使用下列函数获得IORESOURCE_IRQ资源,即中断号:

struct resource *platform_get_resource(struct platform_device *dev,
              unsigned int type, unsigned int num);

2.2 对于i2c device
dts配置

 test: test@41 {
		compatible = "test";
		reg = <0x41>; /* x41 for HW */
		pinctrl-names = "default";
		pinctrl-0 = <&irq_default>;
		interrupt-parent = <&pio>;
		interrupts = <7 IRQ_TYPE_EDGE_FALLING>; //指定gpio7 下降沿中断 
	};

i2c-core-base.c内,在i2c bus对i2c device和i2c driver进行match后,进行i2c_device_probe,此时解析i2c device node

static int i2c_device_probe(struct device *dev)
{
	struct i2c_client	*client = i2c_verify_client(dev);
	struct i2c_driver	*driver;
	int status;

	if (!client)
		return 0;

	driver = to_i2c_driver(dev->driver);

	if (!client->irq && !driver->disable_i2c_core_irq_mapping) {
		int irq = -ENOENT;

		if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
			dev_dbg(dev, "Using Host Notify IRQ\n");
			/* Keep adapter active when Host Notify is required */
			pm_runtime_get_sync(&client->adapter->dev);
			irq = i2c_smbus_host_notify_to_irq(client);
		} else if (dev->of_node) {
			irq = of_irq_get_byname(dev->of_node, "irq");
			if (irq == -EINVAL || irq == -ENODATA)
				irq = of_irq_get(dev->of_node, 0);//解析dts内interrupt相关信息并返回linux内核中断号
		} else if (ACPI_COMPANION(dev)) {
			irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0);
		}
		if (irq == -EPROBE_DEFER)
			return irq;

		if (irq < 0)
			irq = 0;

		client->irq = irq;//保存至client->irq
	}
/**
 * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
 * @dev: pointer to device tree node
 * @index: zero-based index of the IRQ
 *
 * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
 * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
 * of any other failure.
 */
int of_irq_get(struct device_node *dev, int index)
{
	int rc;
	struct of_phandle_args oirq;
	struct irq_domain *domain;

	rc = of_irq_parse_one(dev, index, &oirq);
	if (rc)
		return rc;

	domain = irq_find_host(oirq.np);
	if (!domain)
		return -EPROBE_DEFER;

	return irq_create_of_mapping(&oirq);
}
EXPORT_SYMBOL_GPL(of_irq_get);

在驱动代码里直接使用,申请中断处理函数irq_handler

if (client->irq) {
	ret = devm_request_threaded_irq(&client->dev,
				client->irq,
				   NULL,
				   irq_handler,
				   IRQF_ONESHOT | IRQF_SHARED,
				   dev_name(&client->dev), data);
	if (ret) {
		dev_err(&client->dev, "failed to request irq %d\n",
			client->irq);
		return ret;
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值