gpio复用 海思_海思GPIO

本文档详细介绍了海思GPIO复用的相关接口和初始化过程,包括GPIO方向设置、值的读写、中断配置等,适用于海思平台的GPIO驱动开发。
摘要由CSDN通过智能技术生成

#include

#include

#include

#define GPIO_DIR 0x400

#define GPIO_IS 0x404

#define GPIO_IBE 0x408

#define GPIO_IEV 0x40C

#define GPIO_IE 0x410

#define GPIO_RIS 0x414

#define GPIO_MIS 0x418

#define GPIO_IC 0x41C

/************************************************************************/

/* gpio interface */

/************************************************************************/

/**

* _set_gpio_direction - set gpio direction

*

* @port:

* @offset:

* @dir: 0 -- input, 1 -- output

*/

static void _set_gpio_direction(struct hisi_gpio_port *port, unsigned offset, int dir)

{

u32 l;

unsigned long flags;

spin_lock_irqsave(&port->lock, flags);

l = __raw_readl(port->base + GPIO_DIR);

if (dir)

l |= (1 << offset);

else

l &= ~(1 << offset);

__raw_writel(l, port->base + GPIO_DIR);

spin_unlock_irqrestore(&port->lock, flags);

}

/**

* hisi_gpio_set - get gpio data

*

*/

static void hisi_gpio_set(struct hisi_gpio_port *port, unsigned offset, int value)

{

void __iomem *reg = port->base + (1 << (offset + 2));

u32 l;

unsigned long flags;

spin_lock_irqsave(&port->lock, flags);

l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);

__raw_writel(l, reg);

spin_unlock_irqrestore(&port->lock, flags);

}

/**

* hisi_gpio_get - get gpio value

*

*/

static int hisi_gpio_get(struct hisi_gpio_port *port, unsigned offset)

{

void __iomem *reg = port->base + (1 << (offset + 2));

u32 gpio_direction;

gpio_direction = __raw_readl(port->base + GPIO_DIR);

if (((gpio_direction >> offset) & 1)) /* output mode */

return (__raw_readl(reg) >> offset) & 1;

else /* input mode */

return 0;

}

/**

* hisi_gpio_direction_input - gpio direction input

*

*/

static int hisi_gpio_direction_input(struct hisi_gpio_port *port, unsigned offset)

{

_set_gpio_direction(port, offset, 0);

return 0;

}

/**

* hisi_gpio_direction_output - gpio direction output

*

*/

static int hisi_gpio_direction_output(struct hisi_gpio_port *port, unsigned offset, int value)

{

hisi_gpio_set(port, offset, value);

_set_gpio_direction(port, offset, 1);

return 0;

}

/**

* hisi_gpio_init - gpio init functions

*

* @ int_trigger_type: 0~4, ref GT911 datasheet

*

* Must be called by goodix_ts_probe functions only once.

*/

static int hisi_gpio_init(struct hisi_gpio_port *port, int int_trigger_type)

{

int i, j;

u32 l;

unsigned offset;

const uint8_t irq_table[] = GTP_IRQ_TAB;

static bool initialed;

if (initialed)

return 0;

printk(KERN_INFO "HISI GPIO hardware\n");

/*1. ioremap */

port->base = ioremap_nocache(GTP_BASE_ADDRESS, GTP_RANGE_SIZE);

if (!port->base) {

dev_err(&ts->client->dev,

"Can't remap gpio address: 0x%x, size:0x%dx\n", GTP_BASE_ADDRESS, GTP_RANGE_SIZE);

return -1;

}

/*2. IOMUX */

/*

writel(reg, IOCONFIG_BASE + 0x178);

writel(reg, IOCONFIG_BASE + 0x17C);

*/

/*3. config rest */

offset = 7;

hisi_gpio_direction_output(port, offset); // output mode

/*4. config int */

offset = 6;

hisi_gpio_direction_input(port, offset); // input mode

//

switch (irq_table[int_trigger_type])

{

case IRQ_TYPE_EDGE_RISING:

{

/* */

l = __raw_readl(port->base + GPIO_IS) & (~(1 << offset));

__raw_writel(l, port->base + GPIO_IS);

/* */

l = __raw_readl(port->base + GPIO_IEV) | (1 << offset);

__raw_writel(l, port->base + GPIO_IEV);

/**/

l = __raw_readl(port->base + GPIO_IBE) & (~(1 << offset));

__raw_writel(l, port->base + GPIO_IBE);

}

break;

case IRQ_TYPE_EDGE_FALLING:

{

/* */

l = __raw_readl(port->base + GPIO_IS) & (~(1 << offset));

__raw_writel(l, port->base + GPIO_IS);

/* */

l = __raw_readl(port->base + GPIO_IEV) & (~(1 << offset));

__raw_writel(l, port->base + GPIO_IEV);

/**/

l = __raw_readl(port->base + GPIO_IBE) & (~(1 << offset));

__raw_writel(l, port->base + GPIO_IBE);

}

break;

case IRQ_TYPE_LEVEL_LOW:

{

/* */

l = __raw_readl(port->base + GPIO_IS) | (1 << offset);

__raw_writel(l, port->base + GPIO_IS);

/* */

l = __raw_readl(port->base + GPIO_IEV) & (~(1 << offset));

__raw_writel(l, port->base + GPIO_IEV);

}

break;

case IRQ_TYPE_LEVEL_HIGH:

{

/* */

l = __raw_readl(port->base + GPIO_IS) | (1 << offset);

__raw_writel(l, port->base + GPIO_IS);

/* */

l = __raw_readl(port->base + GPIO_IEV) | (1 << offset);

__raw_writel(l, port->base + GPIO_IEV);

}

break;

default:

break;

}

/* disable the interrupt and clear the status */

__raw_writel(~0, port->base + GPIO_IC);

__raw_writel(~0, port->base + GPIO_IE);

spin_lock_init(&port->lock);

initialed = true;

return 0;

}

/**

* hisi_gpio_deinit - DeInit functions

*

*/

static void hisi_gpio_deinit(struct hisi_gpio_port *port)

{

if (!port)

return;

__raw_writel(~0, port->base + GPIO_IC);

__raw_writel(0, port->base + GPIO_IE);

if (port->base)

{

iounmap(port->base);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值