15_LED驅動二

本章的主要目的是,對4412的32組IO口進行相同的配置操作,配合LED燈的狀態和 萬用表電壓來檢測IO口的好壞。

1. 32組IO口信息

將32組IO的虛擬地址宏進行整理如下:

static int led_gpios[] = {
	EXYNOS4_GPL2(0),EXYNOS4_GPK1(1),
	EXYNOS4_GPD0(0),
	
	EXYNOS4_GPX1(0),EXYNOS4_GPX1(3),EXYNOS4_GPX1(5),EXYNOS4_GPX1(6),
	EXYNOS4_GPX3(0),EXYNOS4_GPX2(6),EXYNOS4_GPX2(7),EXYNOS4_GPX3(5),
	
	EXYNOS4212_GPJ1(3),EXYNOS4_GPL0(1),EXYNOS4_GPL0(3),EXYNOS4212_GPJ1(0),
	EXYNOS4212_GPJ1(2),EXYNOS4212_GPJ1(1),EXYNOS4212_GPJ0(7),EXYNOS4212_GPJ0(6),
	EXYNOS4212_GPJ0(5),EXYNOS4212_GPJ0(4),EXYNOS4212_GPJ0(0),EXYNOS4212_GPJ0(3),
	EXYNOS4212_GPJ0(1),EXYNOS4212_GPJ0(2),
	
	EXYNOS4_GPK3(6),EXYNOS4_GPK3(1),EXYNOS4_GPK3(4),EXYNOS4_GPK3(0),
	EXYNOS4_GPK3(3),EXYNOS4_GPK3(5),EXYNOS4_GPC1(1),
};

2. 驅動代碼

gpios.c

#include <linux/init.h>
#include <linux/module.h>
/*驅動註冊的頭文件,包含驅動的結構體和註冊和卸載的函數*/
#include <linux/platform_device.h>
/*註冊雜項設備頭文件*/
#include <linux/miscdevice.h>
/*註冊設備節點的文件結構體*/
#include <linux/fs.h>
/*Linux中申請GPIO的頭文件*/
#include <linux/gpio.h>
/*三星平臺的GPIO配置函數頭文件*/
/*三星平臺EXYNOS系列平臺,GPIO配置參數宏定義頭文件*/
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
/*三星平臺4412平臺,GPIO宏定義頭文件*/
#include <mach/gpio-exynos4.h>
#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_gpio"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");

/*led的兩個IO,網絡是KP_COL0,VDD50_EN*/
/*蜂鳴器的1個IO,網絡是MOTOR_PWM*/
/*矩陣鍵盤的8個IO,網絡是CHG_FLT,HOOK_DET,CHG_UOK,XEINT14_BAK,
GM_INT1,6260_GPIO1,CHG_COK,XEINT29/KP_ROW13/ALV_DBG25*/
/*攝像頭的14個IO,網絡是CAM_MCLK,CAM2M_RST,CAM2M_PWDN,
CAM_D5,CAM_D7,CAM_D6,CAM_D4,CAM_D3,CAM_D2,CAM_D1,
CAM_PCLK,CAM_D0,CAM_VSYNC,CAM_HREF。
I2C_SDA7,I2C_SCL7也是可以設置爲GPIO,不過總線一般不要去動它*/
/*WIFI模塊的7個IO,WIFI_D3,WIFI_CMD,WIFI_D1,WIFI_CLK,WIFI_D0,WIFI_D2,GPC1_1*/
/*串口RX和TX等也是可以設置爲GPIO,一般不要動它*/
/*數組中有32個引出到端子或者模塊的IO,還有類似sd卡等也是可以作爲GPIO,
其它引到連接器但是沒有使用的GPIO等等*/
/*SCP管腳編號和POP的稍微有點不同,下面是SCP的*/
static int led_gpios[] = {
	EXYNOS4_GPL2(0),EXYNOS4_GPK1(1),
	EXYNOS4_GPD0(0),
	
	EXYNOS4_GPX1(0),EXYNOS4_GPX1(3),EXYNOS4_GPX1(5),EXYNOS4_GPX1(6),
	EXYNOS4_GPX3(0),EXYNOS4_GPX2(6),EXYNOS4_GPX2(7),EXYNOS4_GPX3(5),
	
	EXYNOS4212_GPJ1(3),EXYNOS4_GPL0(1),EXYNOS4_GPL0(3),EXYNOS4212_GPJ1(0),
	EXYNOS4212_GPJ1(2),EXYNOS4212_GPJ1(1),EXYNOS4212_GPJ0(7),EXYNOS4212_GPJ0(6),
	EXYNOS4212_GPJ0(5),EXYNOS4212_GPJ0(4),EXYNOS4212_GPJ0(0),EXYNOS4212_GPJ0(3),
	EXYNOS4212_GPJ0(1),EXYNOS4212_GPJ0(2),
	
	EXYNOS4_GPK3(6),EXYNOS4_GPK3(1),EXYNOS4_GPK3(4),EXYNOS4_GPK3(0),
	EXYNOS4_GPK3(3),EXYNOS4_GPK3(5),EXYNOS4_GPC1(1),
};

#define LED_NUM		ARRAY_SIZE(led_gpios)

static long hello_ioctl( struct file *files, unsigned int cmd, unsigned long arg){
	printk("cmd is %d,arg is %d\n",cmd,arg);
	
	switch(cmd)
	{
		case 0:
		case 1:
			if (arg > LED_NUM) {
				return -EINVAL;
			}

			gpio_set_value(led_gpios[arg], cmd);
			break;

		default:
			return -EINVAL;
	}
	
	gpio_set_value(led_gpios[2], 0);
	
	return 0;
}

static int hello_release(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello release\n");
	return 0;
}

static int hello_open(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello open\n");
	return 0;
}

static struct file_operations hello_ops = {
	.owner = THIS_MODULE,
	.open = hello_open,
	.release = hello_release,
	.unlocked_ioctl = hello_ioctl,
};

static  struct miscdevice hello_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICE_NAME,
	.fops = &hello_ops,
};

static int hello_probe(struct platform_device *pdv){
	int ret,i;
	
	printk(KERN_EMERG "\tinitialized\n");
	
	for(i=0; i<LED_NUM; i++)
	{
		ret = gpio_request(led_gpios[i], "LED");
		if (ret) {
			printk("%s: request GPIO %d for LED failed, ret = %d\n", DRIVER_NAME,
					i, ret);
			}
		else{
			s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);
			gpio_set_value(led_gpios[i], 1);			
		}
	}
	gpio_set_value(led_gpios[2], 0);
	
	misc_register(&hello_dev);
	if(ret<0)
	{
		printk("leds:register device failed!\n");
		goto exit;
	}
	return 0;

exit:
	misc_deregister(&hello_dev);
	return ret;
}

static int hello_remove(struct platform_device *pdv){
	int i;
	
	printk(KERN_EMERG "\tremove\n");
	
	for(i=0; i<LED_NUM; i++)
	{
		gpio_free(led_gpios[i]);
	}
	
	misc_deregister(&hello_dev);
	return 0;
}

static void hello_shutdown(struct platform_device *pdv){
	;
}

static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
	return 0;
}

static int hello_resume(struct platform_device *pdv){
	return 0;
}

struct platform_driver hello_driver = {
	.probe = hello_probe,
	.remove = hello_remove,
	.shutdown = hello_shutdown,
	.suspend = hello_suspend,
	.resume = hello_resume,
	.driver = {
		.name = DRIVER_NAME,
		.owner = THIS_MODULE,
	}
};

static int hello_init(void)
{
	int DriverState;
	printk(KERN_EMERG "HELLO WORLD enter!\n");
	DriverState = platform_driver_register(&hello_driver);
	printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
	return 0;
}

static void hello_exit(void)
{
	printk(KERN_EMERG "HELLO WORLD exit!\n");
	void free_irq(unsigned int irq,void *dev_id);
	platform_driver_unregister(&hello_driver);	
}

module_init(hello_init);
module_exit(hello_exit);

 

3. 用戶應用代碼

invoke_gpios.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>

#define GPIOS 32

int main(int argc , char **argv){
	int fd,i,cmd=2;
	char *hello_node = "/dev/hello_gpio";
	char *cmd0 = "0"; 
	char *cmd1 = "1";
	
	printf("argv[0] is %s;argv[1] is %s;",argv[0],argv[1]);
	
	if(strcmp(argv[1], cmd0) == 0){
		cmd = 0;
		printf("cmd is 0!\n");
	}
	if(strcmp(argv[1], cmd1) == 0){
		cmd = 1;
		printf("cmd is 1!\n");
	}
	
/*O_RDWR只讀打開,O_NDELAY非阻塞方式*/	
	if((fd = open(hello_node,O_RDWR|O_NDELAY))<0){
		printf("APP open %s failed!\n",hello_node);
	}
	else{
		printf("APP open %s success!\n",hello_node);
		for(i=0;i<GPIOS;i++){
			ioctl(fd,cmd,i);
			printf("APP ioctl %s ,cmd is %d,i is %d!\n",hello_node,cmd,i);
		}
	}
	
	close(fd);
}

 

4. 程序調試信息

 

 

5. 注意事項

(1)需要去掉佔用GPIO的驅動

去掉佔用調用的GPIO驅動,包括leds,buzzer,camera ov5640,WIFI mt6620
• VIDEO_OV5640
– Device Drivers
– Multimedia support(MEDIA_SUPPORT [=y])
– Video capture adapters(VIDEO_CAPTURE_DRIVERS [=y])(去掉)
• MTK_COMBO_CHIP_MT6620
– Device Drivers
– MediaTek Connectivity Combo Chip Config
– MediaTek Connectivity Combo Chip Support (MTK_COMBO [=y])(去掉)
– Select Chip (<choice> [=y])
• Enable LEDS config
– Device Drivers
– Character devices
– Enable LEDS config
• Enable BUZZER config
– Device Drivers
– Character devices
– Enable BUZZER config
(2)本章的雜項設備名稱和驅動名稱是不一致的

#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_gpio"

 

發佈了99 篇原創文章 · 獲贊 63 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章