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

📄 led_module_remap.c

📁 基于linux操作系统ATMELARM9200 开发平台的LED演示程序
💻 C
字号:
/*********************************************************************** * * (C) Copyright 2005,5 *  * himai  * All rights left. * * * a simple Device Driver for HM901ESP led device * * Can be loaded as module * * $Id: led.c,v 1.1 2005/01/16   $ * ***********************************************************************//* * Standard in kernel modules */#include <linux/kernel.h>	/* We're doing kernel work	*/#include <linux/module.h>	/* Specifically, a module	*/#include <linux/init.h>		/* for __initfunc		*/#include <asm/uaccess.h>	/* for put_user			*/#include <asm/io.h>        	/* for ioremap                  */#include <asm/arch/hardware.h>	/* atmel RM9200           	*/      #include <asm/arch/pio.h>#define	DEBUG   1#ifdef	DEBUG# define debugk(fmt,args...)	printk(fmt ,##args)#else# define debugk(fmt,args...)#endif/* * Deal with CONFIG_MODVERSIONS */#if CONFIG_MODVERSIONS==1/* # define MODVERSIONS */# include <linux/modversions.h>#endifMODULE_LICENSE("GPL");/* * For character devices */#include <linux/fs.h>		/* character device definitions	*/#include <linux/wrapper.h>	/* wrapper for compatibility with future versions */#ifndef KERNEL_VERSION# define KERNEL_VERSION(a,b,c)	((a)*65536+(b)*256+(c))#endif#define 	SUCCESS 	0#define		LED_MAJOR	42	/* free for demo/sample use	*//* see ATMEL RM9200 datasheet */#define AT91C_BASE_PMC			0xFFFFFC00     /* PMC controller base address */#define PMC_MEM_LEN                	0x70     #define PMC_PCER_OFF                 	0x10      #define PMC_PCSR_OFF                	0x18#define AT91C_BASE_PIOB  		0xFFFFF600     /* PIO-B base address */#define PIO_MEM_LEN               	0xB0#define PIO_PER_OFF                    	0x00#define PIO_OER_OFF			0x10#define PIO_SODR_OFF			0x30#define PIO_CODR_OFF      		0x34#define PIO_ODSR_OFF			0x38/* * Device Declarations  *//* * The name for our device, as it will appear in /proc/devices */#define DEVICE_NAME "ut_led"/* * prevent concurent access of the same device */static int Device_Open = 0;/* * Prototypes */static int __init led_init (void );static int device_open(struct inode *, struct file *);static int device_release(struct inode *, struct file *);static ssize_t device_read(struct file *, char *, size_t, loff_t *);static ssize_t device_write(struct file *, const char *, size_t, loff_t *); struct file_operations led_ops = {    read:       	device_read,    write:      	device_write,    open:       	device_open,    release:    	device_release,};static int Major;static void  *pmc_base, *piob_base;/* * Initialize the driver - Register the character device *    This function configures the GPIO PB12 for output *  */static int __init led_init(void){  unsigned int i;	/* get the remmapped controller base address register */	  pmc_base = ioremap_nocache(AT91C_BASE_PMC, PMC_MEM_LEN);                  /* enable PIOB power */          writel (1 << AT91C_ID_PIOB, pmc_base + PMC_PCER_OFF);  	  i = readl(pmc_base + PMC_PCSR_OFF);	  printk ("pmc_base = 0x%08X\n", (int) pmc_base);	  printk ("PCSR     = 0x%08X\n", i);	  iounmap (pmc_base);	/* set PB12 output */	  piob_base = ioremap_nocache(AT91C_BASE_PIOB, PIO_MEM_LEN);	  writel (AT91C_PIO_PB12, piob_base + PIO_PER_OFF); 	  writel (AT91C_PIO_PB12, piob_base + PIO_OER_OFF); 	  printk ("piob_base = 0x%08X\n", (int) piob_base);	  writel (AT91C_PIO_PB12, piob_base + PIO_CODR_OFF);	/* Register the character device */	  Major = register_chrdev (LED_MAJOR, DEVICE_NAME, &led_ops);	/* Negative values signify an error */	if (Major < 0) 	{		printk ("UT_LED init_module: failed with %d\n", Major);		return Major;	}	Major = LED_MAJOR;	printk ("HM901ESP_LED registred: major = %d\n", Major);	return 0;} /* * called whenever a process attempts to open the device */static int device_open (struct inode *inode, struct file *file){		debugk ("device_open(%p,%p)\n", inode, file);	/*	 * Get major / minor numbers when needed	 */	debugk ("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);	/*	 * exclusive open only	 */	if (Device_Open) 	{		return -EBUSY;	}	/*	 * Be careful here on SMP kernels!	 */	Device_Open++;	/*	 * Make sure that the module isn't removed while	 * the file is open by incrementing the usage count	 */	MOD_INC_USE_COUNT;	return SUCCESS;}/* * Called when a process closes the device. * Doesn't have a return value in version 2.0.x because it can't fail, * but in version 2.2.x it is allowed to fail */static int device_release (struct inode *inode, struct file *file){		debugk ("device_release(%p,%p)\n", inode, file);	/* We're now ready for our next caller */	Device_Open--;	MOD_DEC_USE_COUNT;			/*turn off led*/        writel (AT91C_PIO_PB12, piob_base +  PIO_SODR_OFF);	return 0;}/* * read entry point: */static ssize_t device_read (struct file *file,			    char *buffer,	/* The buffer to fill with data */			    size_t length,	/* The length of the buffer */			    loff_t * offset)	/* Our offset in the file */{	unsigned int i;     	i = readl (piob_base + PIO_ODSR_OFF);	i &= AT91C_PIO_PB12;	copy_to_user (buffer, (void *) &i, 4);	debugk ("Read: value = 0x%08X\n", i);	return (4);		/* read() always returns exactly 4 bytes */}/* * write entry point: dummy here */static ssize_t device_write (struct file *file,			     const char *buffer,	/* buffer */			     size_t length,		/* length of buffer */			     loff_t * offset)		/* offset in the file */{			int 	i;	int  	err;        	if(length > 4)		return -9;			err = copy_from_user ( (void *) &i, buffer, length);         i &= AT91C_PIO_PB12;	if (i)          writel (AT91C_PIO_PB12, piob_base + PIO_SODR_OFF);        else          writel (AT91C_PIO_PB12, piob_base + PIO_CODR_OFF);	debugk ("\nWrite: value = 0x%08X\n", i);  	return (length);}/****************************** **** Module Declarations ***** **************************** */#ifdef MODULE/* * Cleanup - unregister the appropriate file from /proc */static void __exit cleanup_led_module (void){	int ret;	/*	 * Unregister the device	 */	ret = unregister_chrdev (Major, DEVICE_NAME); 	iounmap (piob_base);	debugk ("iounmap: piob_base = 0x%08x\n", (int) piob_base);			/*	 * If there's an error, report it	 */	if (ret < 0) {		printk ("unregister_chrdev: error %d\n", ret);	}}module_init(led_init);module_exit(cleanup_led_module);MODULE_AUTHOR("Himai");MODULE_DESCRIPTION("led driver for HM901ESP"); #endif	/* MODULE */

⌨️ 快捷键说明

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