⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ekii-led.c

📁 这是arm9上面的led在linux下的驱动程序,可以编译下载到linux中
💻 C
字号:
/*
* linux/deriver/led/ekii-led.c
* led driver for Embest EduKit II
* Copyright (C) 2005 Embest <www.embedinfo.com>
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>	// error codes
#include <linux/types.h>	// size_t
#include <linux/delay.h>	// mdelay
#include <asm/uaccess.h>
#include <asm/arch-S3C44B0X/s3c44b0x.h>


#undef DEBUG
#ifdef	DEBUG
#define TRACE(str, args...)	printk("led: " str, ## args)
#else
#define TRACE(str, args...)
#endif


#define LED_MAJOR	60
#define LED_DEVNAME "led"

#define GPB_MASK	(3<<4)
#define GPF_MASK	(3<<3)
#define GET_DATA(b, f) ((u8)( ((~b&0x20)>>5) | ((~b&0x10)>>2) | ((~f&0x08)>>2) | ((~f&0x10)>>1) ))
#define SET_DATA(t, b, f) ( b = (((~t&0x01)<<5) | ((~t&0x04)<<2)), f = (((~t&0x02)<<2) | ((~t&0x08)<<1)) )

#define LED_LOCK(u) down(&u->lock);
#define LED_UNLOCK(u) up(&u->lock);

struct unit {
	struct semaphore lock;
	u32 *PCONB;		/* PCONB register */
	u32 *PDATB;		/* PDATB register */
	u32 *PCONF;		/* PCONF register */
	u32 *PDATF;		/* PDATF register */
	u32 *PUPF;		/* PUPF register */
	u32 b;			/* store LED 1 and LED 2 value */
	u32 f;			/* store LED 3 and LED 4 value */
};

static char *version = "Embest Edukit-II led driver version 1.0 (2005-04-18) <www.embedinfo.com>\n";

static struct unit led_unit = {
	.PCONB		= (u32 *)S3C44B0X_PCONB,
	.PDATB		= (u32 *)S3C44B0X_PDATB,
	.PCONF		= (u32 *)S3C44B0X_PCONF,
	.PDATF		= (u32 *)S3C44B0X_PDATF,
	.PUPF		= (u32 *)S3C44B0X_PUPF,
};


static void led_set_value(struct unit *unit, u8 val)
{
	u32 temp;

	SET_DATA(val, unit->b, unit->f);
	
	temp = *unit->PDATB;
	temp &= ~GPB_MASK;
	temp |= unit->b;
	*unit->PDATB = temp;
	
	temp = *unit->PDATF;
	temp &= ~GPF_MASK;
	temp |= unit->f;
	*unit->PDATF = temp;
}


static u8 led_get_value(struct unit *unit)
{
	u8 temp = GET_DATA(unit->b, unit->f);

	return temp;
}


static int led_open(struct inode *inode, struct file *file)
{
	TRACE("open\n");
	file->private_data = &led_unit;
	MOD_INC_USE_COUNT;

	return 0;
}


static int led_release(struct inode *inode, struct file *file)
{
	TRACE("release\n");
	MOD_DEC_USE_COUNT;

	return 0;
}


static ssize_t led_read(struct file *file, char *buf, size_t count, loff_t *offset)
{
	u8 temp;
	int ret;
	struct unit *unit = (struct unit *)file->private_data;

	TRACE("read\n");
	if(count > 1)
		count = 1;
	LED_LOCK(unit);
	temp = led_get_value(unit);
	ret = copy_to_user(buf, &temp, count) ? -EFAULT : count;
	LED_UNLOCK(unit);

	return ret;
}


static ssize_t led_write(struct file *file, const char *buf, size_t count, loff_t *offset)
{
	u8 temp;
	int ret;
	struct unit *unit = (struct unit *)file->private_data;

	TRACE("write\n");
	if(count > 1)
		count = 1;
	LED_LOCK(unit);
	ret = copy_from_user(&temp, buf, count) ? -EFAULT : count;
	if(ret)
		led_set_value(unit, temp);
	LED_UNLOCK(unit);

	return ret;
}


static struct file_operations led_ops = {
	owner:		THIS_MODULE,
	read:		led_read,
	write:		led_write,
	open:		led_open,
	release:	led_release,
};


/*
* led device init
*/
static void __init led_init(struct unit *unit)
{
	u32 temp;

	/* init device lock */
	init_MUTEX(&unit->lock);

	/* init io port */
	temp = *unit->PCONB;
	temp &= ~(3<<4);
	*unit->PCONB = temp;

	temp = *unit->PCONF;
	temp &= ~((3<<8) | (3<<6));
	temp |= ((1<<8) | (1<<6));
	*unit->PCONF = temp;

	temp = *unit->PUPF;
	temp |= (3<<3);
	*unit->PUPF = temp;
	
	/* init data and turn on led*/
	led_set_value(unit, 0x0f);

	/* delay some time */
	mdelay(100);

	/* turn off led */
	led_set_value(unit, 0x00);
}


/*
* module init
*/
int __init led_init_module(void)
{
	int res;

	TRACE("init_module\n");
	/* print version information */
	printk(KERN_INFO "%s", version);
	/* register led device */
	res = register_chrdev(LED_MAJOR, LED_DEVNAME, &led_ops);
	if(res < 0) {
		printk("ekii-led.o: unable to get major %d for led device.\n", LED_MAJOR);
		return res;
	}

	/* then call led_init() */
	led_init(&led_unit);

	return 0;
}


/*
* module cleanup
*/
void __exit led_cleanup(void)
{
	int res;

	TRACE("cleanup\n");
	/* unregister led device */
	res = unregister_chrdev(LED_MAJOR, LED_DEVNAME);
	if(res < 0)
		printk("ekii-led.o: unable to release major %d for led device.\n", LED_MAJOR);
}


module_init(led_init_module);
module_exit(led_cleanup);


MODULE_DESCRIPTION("EduKit-II led driver");
MODULE_AUTHOR("Embest tech&info Co.,Ltd. <www.embedinfo.com>");
MODULE_LICENSE("GPL");



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -