mdm9x07的GPIO相关笔记

居然快一年没有更新博客了,近段时间看了下以前的一些笔记,发现做过的项目,学习的知识都忘了差不多,其实还是应该抽点时间出来记录下。

当然先列出参考文章:

http://blog.chinaunix.net/uid-27717694-id-3624294.html                     GPIO的驱动模型
http://www.wowotech.net/gpio_subsystem/io-port-control.html             linux内核中的GPIO系统之(1):软件框架

使用芯片平台 mdm9x07.

GPIO是与硬件体系密切相关的,linux提供一个模型来让驱动统一处理GPIO,即各个板卡都有实现自己的gpio_chip控制模块:request, free, input,output, get,set,irq...然后把控制模块注册到内核中,这时会改变全局gpio数组:gpio_desc[].当用户请求gpio时,就会到这个数组中找到,并调用这个GPIO对应的gpio_chip的处理函数
表示一个gpio口,含对应的gpio_chip.

对于每一个gpio,都有一个gpio描述符,这个描述符包含了这个gpio所属的控制器即chip和一些标志,label等

gpio描述符
struct gpio_desc {
	struct gpio_chip	*chip;
	unsigned long		flags;
/* flag symbols are bit numbers */
#define FLAG_REQUESTED	0					//GPIO 申请的标志,已申请的话该标志是1,否则是0
#define FLAG_IS_OUT	1
#define FLAG_EXPORT	2	/* protected by sysfs_lock */
#define FLAG_SYSFS	3	/* exported via /sys/class/gpio/control */
#define FLAG_TRIG_FALL	4	/* trigger on falling edge */
#define FLAG_TRIG_RISE	5	/* trigger on rising edge */
#define FLAG_ACTIVE_LOW	6	/* value has active low */
#define FLAG_OPEN_DRAIN	7	/* Gpio is open drain type */
#define FLAG_OPEN_SOURCE 8	/* Gpio is open source type */
#define FLAG_USED_AS_IRQ 9	/* GPIO is connected to an IRQ */

#define ID_SHIFT	16	/* add new flags before this one */

#define GPIO_FLAGS_MASK		((1 << ID_SHIFT) - 1)
#define GPIO_TRIGGER_MASK	(BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE))

	const char		*label;
};

static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];     --- 采用了一个具有ARCH_NR_GPIOS大小的gpio描述符数组。这个描述符数组便代表了系统所有的gpio

#define ARCH_NR_GPIOS        512                        --- 即系统现在有144个GPIO口


通过这个结构抽象化所有的GPIO源,而让板上其它的模块可以用相同的接口调用使用这些GPIO

struct gpio_chip
{
	const char			*label;
	struct device		*dev;
	struct module		*owner;
	struct list_head    list;

	int			(*request)(struct gpio_chip *chip,unsigned offset);								//请求gpio
	void		(*free)(struct gpio_chip *chip,unsigned offset);								//释放gpio
	int			(*get_direction)(struct gpio_chip *chip,unsigned offset);						//获取方向
	int			(*direction_input)(struct gpio_chip *chip,unsigned offset);						//配置gpio为输入,返回当前gpio状态
	int			(*direction_output)(struct gpio_chip *chip,unsigned offset, int value);			//配置gpio为输出,并设置为value
	int			(*get)(struct gpio_chip *chip,unsigned offset);									//获取gpio的状态		
	void		(*set)(struct gpio_chip *chip,unsigned offset, int value);						//设置gpio为value值		
	int			(*set_debounce)(struct gpio_chip *chip,unsigned offset,unsigned debounce);		//设置消抖动时间,尤其是gpio按键时有用
	int			(*to_irq)(struct gpio_chip *chip,unsigned offset);								//把gpio号转换为中断号
	void		(*dbg_show)(struct seq_file *s,struct gpio_chip *chip);
	int			base;																			// 这个gpio控制器的gpio开始编号
	u16			ngpio;																			//这个gpio控制器说控制的gpio数
	struct gpio_desc	*desc;
	const char		*const *names;
	bool			can_sleep;
	bool			irq_not_threaded;
	bool			exported;

#ifdef CONFIG_GPIOLIB_IRQCHIP
	struct irq_chip		*irqchip;
	struct irq_domain	*irqdomain;
	unsigned int		irq_base;
	irq_flow_handler_t	irq_handler;
	unsigned int		irq_default_type;
#endif

#if defined(CONFIG_OF_GPIO)
	struct device_node *of_node;
	int of_gpio_n_cells;
	int (*of_xlate)(struct gpio_chip *gc,
			const struct of_phandle_args *gpiospec, u32 *flags);
#endif
#ifdef CONFIG_PINCTRL
	struct list_head pin_ranges;
#endif
}

开始一些有用的命令了

cat /sys/kernel/debug/gpio
这个命令可以得到全部GPIO的状态

具体代码分析如下:

gpiolib.c
static int __init gpiolib_debugfs_init(void)
	(void) debugfs_create_file("gpio", S_IFREG | S_IRUGO,NULL, NULL, &gpiolib_operations);
	
static const struct file_operations gpiolib_operations = {
	.owner		= THIS_MODULE,
	.open		= gpiolib_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static int gpiolib_open(struct inode *inode, struct file *file)
	return seq_open(file, &gpiolib_seq_ops);	
	
static const struct seq_operations gpiolib_seq_ops = {
	.start = gpiolib_seq_start,
	.next = gpiolib_seq_next,
	.stop = gpiolib_seq_stop,
	.show = gpiolib_seq_show,
};	

static int gpiolib_seq_show(struct seq_file *s, void *v)
	struct gpio_chip *chip = v;
	seq_printf(s, "%sGPIOs %d-%d", (char *)s->private,chip->base, chip->base + chip->ngpio - 1);		--- 即 GPIOs 0-79
	dev = chip->dev;
	seq_printf(s, ", %s/%s", dev->bus ? dev->bus->name : "no-bus",dev_name(dev));						--- 即 platform/1000000.pinctrl
	seq_printf(s, ", %s", chip->label);																	--- 即 , 1000000.pinctrl
	seq_printf(s, ":\n");																				--- 即 GPIOs 0-79, platform/1000000.pinctrl, 1000000.pinctrl:
	chip->dbg_show(s, chip);		
		
Pinctrl-msm.c (drivers\pinctrl\qcom)
static struct gpio_chip msm_gpio_template = {
	.direction_input  = msm_gpio_direction_input,
	.direction_output = msm_gpio_direction_output,
	.get              = msm_gpio_get,
	.set              = msm_gpio_set,
	.request          = msm_gpio_request,
	.free             = msm_gpio_free,
	.dbg_show         = msm_gpio_dbg_show,
};

static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
	for (i = 0; i < chip->ngpio; i++, gpio++) 
	msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值