亲,在驱动中直接是使用ipmap的效率要比使用系统哪些xxx_gpio_set函数高,这些函数最终也是调用的iomap。
下面内容是天嵌科技最新的led驱动,s3c_gpio_setpull这类函数需要自行添加到内核中。(内核中有部分函数是存在的)。
/***********************************************************************************
* drivers/char/tq6410_leds.c
* 功能简要:
* 该驱动注册一个字符设备“/dev/EmbedSky-leds”, 用于4个LED。
* 函数简介:
* setGPMDAT_For_LED(int ON_OFF,int which_led), 用于点光亮LED,或者灭掉LED
* 提供的外部接口:
* ioctol(struct inode *inode,struct file *file,unsigned int brightness);
* 用于LED的亮,灭。
* 调用实例:
* 提供控制台,命令式的测试程序。
* 提供QT4界面化的测试程序
*
*************************************************************************************/
#include <linux/miscdevice.h>
#include <linux/input.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <mach/map.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-bank-m.h>
#define DEVICE_NAME "tq6410-leds"
/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
#define IOCTL_GPIO_ON 1
#define IOCTL_GPIO_OFF 0
/* 用来指定LED所用的GPIO引脚 */
static unsigned long gpio_table [] =
{
S3C64XX_GPM(0),
S3C64XX_GPM(1),
};
/* 用来指定GPIO引脚的功能:输出 */
static unsigned int gpio_cfg_table [] =
{
S3C64XX_GPM_OUTPUT(0),
S3C64XX_GPM_OUTPUT(1),
};
#ifdef CONFIG_TQ6410_DEBUG_LEDS
static void tq6410_debug_leds(unsigned int cmd,unsigned long arg)
{
s3c_gpio_setpin(gpio_table[arg], cmd);
}
static void toggle_led(unsigned int cmd,unsigned long arg)
{
int loop=0;
printk("%s : led %ld toggle now: \n",__func__,arg);
for(; loop<11; loop++)
{ cmd = loop%2;
printk("leds %d %s \n",arg+1,(cmd)?"on":"off");
tq6410_debug_leds(cmd,arg);
mdelay(1000);
}
}
#endif
static int tq6410_gpio_open(struct inode *inode, struct file *file)
{
int i;
printk(KERN_INFO " leds opened\n");
for (i = 0; i < sizeof(gpio_table)/sizeof(unsigned long); i++)
{
s3c_gpio_cfgpin(gpio_table[i], gpio_cfg_table[i]);
s3c_gpio_setpin(gpio_table[i], 0);
}
#ifdef CONFIG_TQ6410_DEBUG_LEDS
for (i = 0; i < sizeof(gpio_table)/sizeof(unsigned long); i++)
{
toggle_led(1,i);
}
#endif
return 0;
}
static long tq6410_gpio_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
{
arg -= 1;
if (arg > sizeof(gpio_table)/sizeof(unsigned long))
{
return -EINVAL;
}
switch(cmd)
{
case IOCTL_GPIO_ON:
// 设置指定引脚的输出电平为1
s3c_gpio_setpin(gpio_table[arg], 1);
return 0;
case IOCTL_GPIO_OFF:
// 设置指定引脚的输出电平为0
s3c_gpio_setpin(gpio_table[arg], 0);
return 0;
default:
return -EINVAL;
}
}
/*驱动接口设置*/
static struct file_operations dev_fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = tq6410_gpio_ioctl,
.open = tq6410_gpio_open,
};
/*设备结构的设置*/
static struct miscdevice misc =
{
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
/*初始化设备,配置对应的IO,以及注册设备*/
static int __init tq6410_leds_init(void)
{
int ret;
int i;
for (i = 0; i < sizeof(gpio_table)/sizeof(unsigned long); i++)
{
s3c_gpio_cfgpin(gpio_table[i], gpio_cfg_table[i]);
s3c_gpio_setpin(gpio_table[i], 0);
s3c_gpio_setpull(gpio_table[i], S3C_GPIO_PULL_NONE);
}
ret = misc_register(&misc);
printk(KERN_INFO "TQ6410 LEDs driver successfully probed\n");
return ret;
}
/*注销设备*/
static void __exit tq6410_leds_exit(void)
{
misc_deregister(&misc);
}
module_init(tq6410_leds_init);
module_exit(tq6410_leds_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.embedsky.net");
MODULE_DESCRIPTION("TQ6410 LEDS Driver");
|