gpio_get_value的定义

gpio_get_value等一系列函数,并非linux标准函数,而是跟硬件相关的。 通常我们说的driver都是跟外围设备相关的,所以需要我们自己开发,但是这次我们说到的gpio是跟soc相关的,其实也是需要自己定义的,只不过这个自己变成了soc的provider,比如高通,intel等等

a)接口定义在.h文件

有每个cpu平台都有自己定义的gpio_get_value,要继续查看到底是哪个.h文件,要看你现在用的是哪个cpu平台

例如:intel:就是x86

Gpio.h (z:\jb_intel\hardware\intel\linux-2.6\arch\x86\include\asm)


b)具体实现在drivers\gpio里面


==============>

gpio driver:

drivers\gpio

里面有各种平台的gpio.c文件,查看makefile,

根据build 之后生成config,发现只有2个是被编译的,
一个是gpiolib.c,这个是通用的,不是平台相关的
另一个是,比如:obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
==============>

gpiolib.c

int __gpio_get_value(unsigned gpio)
{
struct gpio_chip*chip;
int value;


chip = gpio_to_chip(gpio);
WARN_ON(chip->can_sleep);
value = chip->get ? chip->get(chip, gpio - chip->base) : 0; 

        我们最终要进入到get函数中,去进一步查看。但是首先要知道,是哪个chip的get 函数, 这个由上面的红色语句gpio_to_chip(gpio);得出
trace_gpio_value(gpio, 1, value);
return value;
}
EXPORT_SYMBOL_GPL(__gpio_get_value);



其中语句:chip = gpio_to_chip(gpio);是为了得到当前的chip,进入她的函数定义里面查看

static inline struct gpio_chip *gpio_to_chip(unsigned gpio)
{
return gpio_desc[gpio].chip;
}

继续查看gpio_desc 是从哪里来的,发现有个gpiochip_add 函数 有如下语句:

gpio_desc[id].chip = chip;


继续查看gpiochip_add被谁调用, 发现很多个gpio文件中有gpiochip_add,但是由于我们通过config文件已经知道,是:

obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o

langwell_gpio.c 


发现调用gpiochip_add的地方有2处:

1: platform_driver wp_gpio_driver (name=wp_gpio) 的probe函数

2:    pci_driver lnw_gpio_driver (name=langwell_gpio) 的probe函数

因为是x86平台我们可以猜想,应该是2,但是我们还是可以验证一下

把设备连上pc,adb 进入

sys/bus/pci/drivers/ 下有个langwell_gpio

sys/bus/platform/drivers/下没有wp_gpio

可以证实,我们用的是2


继续查看probe 2 发现:lnw->chip.get = lnw_gpio_get;


由此得知:

gpio_get_value在intel平台上 最终调用了 lnw_gpio_get 来说实现。


========================================================================================================


以上部分仍然处于 对接口的定义阶段,下面我们来看看具体 是怎么实现的

static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset)
{
void __iomem *gplr = gpio_reg(chip, offset, GPLR);//应该是映射   gpio对应的要操作的寄存器GPLR  的地址空间: GPLR, refer to  intel的spec, 一个寄存器:Monitor Pin State。

return readl(gplr) & BIT(offset % 32);//读取GPLR寄存器之后,由于每个bit都代表一个gpio,所以与上BIT(该位gpio);

//通过spec可知,Note: There are a total of 94 configurable Always-On GPIOs on GPIO controller 0. There is no gp_aon_15.

//There are a total of 69 configurable GPIOs on GPIO controller 1. There is no gp_core[5..0],
GP_Core[11..8], gp_core_[25..23] and gp_core[34]
}



=======================================================================================

动态更改 gpio function:

lnw_gpio_set_alt



  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
typedef struct { ISRFunction_t handler; void *handler_param; int irq_type; } GpioIrqDesc_t; static GpioIrqDesc_t gpio_irq_descs[GPIO_NUM]; static __INLINE uint32_t gpio_get_regbase(int gpio) { int gpiox = (gpio >> 5) & 0x3; return REGS_GPIO_BASE + 0x80 * gpiox; } /* static __INLINE int GPIO_BANK(unsigned gpio) { return gpio >> 5; } */ static __INLINE int GPIO_OFFSET(unsigned gpio) { if (gpio == 96) return 2; else if (gpio == 97) return 0; else if (gpio == 98) return 3; else if (gpio == 99) return 1; else return gpio & 0x1F; } static __INLINE void *GPIO_MODREG(unsigned gpio) { return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_DDR); } static __INLINE void *GPIO_WDATAREG(unsigned gpio) { return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_DR); } static __INLINE void *GPIO_RDATAREG(unsigned gpio) { return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_EXT_PORTA); } static __INLINE void *GPIO_INTENREG(unsigned gpio) { return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INTEN); } static __INLINE void *GPIO_INTMASKREG(unsigned gpio) { return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INTMASK); } static __INLINE void *GPIO_INTLVLREG(unsigned gpio) { return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INTTYPE_LEVEL); } static __INLINE void *GPIO_INTPOLREG(unsigned gpio) { return (void*)(gpio_get_regbase(gpio) + GPIO_SWPORTA_INT_POLARITY); } void gpio_request(unsigned gpio) { pinctrl_gpio_request(gpio); } void gpio_direction_output(unsigned gpio, int value) { configASSERT(gpio < GPIO_NUM); gpio_request(gpio); writel(readl(GPIO_MODREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_MODREG(gpio)); if (value) writel(readl(GPIO_WDATAREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio)); else writel(readl(GPIO_WDATAREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio)); } void gpio_direction_input(unsigned gpio) { configASSERT(gpio < GPIO_NUM); gpio_request(gpio); writel(readl(GPIO_MODREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_MODREG(gpio)); } void gpio_set_value(unsigned gpio, int value) { configASSERT(gpio < GPIO_NUM); if (value) writel(readl(GPIO_WDATAREG(gpio)) | (1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio)); else writel(readl(GPIO_WDATAREG(gpio)) & ~(1 << GPIO_OFFSET(gpio)), GPIO_WDATAREG(gpio)); } int gpio_get_value(unsigned gpio) { configASSERT(gpio < GPIO_NUM); return !!(readl(GPIO_RDATAREG(gpio)) & (1 << GPIO_OFFSET(gpio))); } static void gpio_toggle_trigger(unsigned gpio) { u32 pol; pol = readl(GPIO_INTPOLREG(gpio)); if (pol & (1 << GPIO_OFFSET(gpio))) pol &= ~(1 << GPIO_OFFSET(gpio)); else pol |= (1 << GPIO_OFFSET(gpio)); writel(pol, GPIO_INTPOLREG(gpio)); } 根据上述函数配置一个输出模式 频率为24mhz的io口】
07-15

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值