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

📄 led.c

📁 这是motorola公司的powerpc芯片上的嵌入式linux上的驱动程序和测试程序
💻 C
字号:
/*********************************************************************** * * (C) Copyright 2002,12 *  * Qi zhaoling  * All rights left. * * * a simple Device Driver for UT850GE led device * * Can be loaded as module * * $Id: led.c,v 1.1 2000/01/14 16:28:49 wd Exp $ * ***********************************************************************//* * Standard in kernel modules */#include <linux/kernel.h>	/* We're doing kernel work	*/#include <linux/module.h>	/* Specifically, a module	*/#include <asm/uaccess.h>	/* for put_user			*/#include <asm/init.h>		/* for __initfunc		*/#include <asm/8xx_immap.h>#include <asm/mpc8xx.h>static volatile iop8xx_t *iop_p = 0;   /*i/o port point of UT850GE*/#define	DEBUG#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>#endif/* * 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	DEBUG	1#define SUCCESS 0#define	LED_MAJOR	42	/* free for demo/sample use	*/#define MAX_LED 2#define LINK_LED 0#define ALARM_LED 1static ushort  UTLed[MAX_LED] = {0x1000, 0x0800};/* * 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 */int 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 *);int init_module(void);void cleanup_module(void);#if 0struct file_operations led_ops ={	NULL,			/* seek		*/	device_read,	device_write,	NULL,			/* readdir	*/	NULL,			/* select	*/	NULL,			/* ioctl	*/	NULL,			/* mmap		*/	device_open,	NULL,			/* flush	*/	device_release		/* close	*/};#endifstruct file_operations led_ops = {    read:       device_read,    write:      device_write,    open:       device_open,    release:    device_release,};static int Major;/* * Initialize the driver - Register the character device *//*__initfunc( int led_init (void) )*/int led_init(void){	if (!iop_p) 	{		/* init i/o port ptr */		unsigned long immr;		asm( "mfspr %0,638": "=r"(immr) : );		immr &= 0xFFFF0000;		iop_p = (iop8xx_t *)&((volatile immap_t *)immr)->im_ioport;	}	/*	 * 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 ("TQM_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){	volatile iop8xx_t *cp = iop_p;		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;	cp->iop_pdpar &= ~UTLed[LINK_LED];  	cp->iop_pddir |=  UTLed[LINK_LED];  /*set to output IO*/	cp->iop_pdpar &= ~UTLed[ALARM_LED];  	cp->iop_pddir |=  UTLed[ALARM_LED]; /*set to output IO*/		/* default is turned on */	cp->iop_pddat &= ~UTLed[ALARM_LED];	cp->iop_pddat &= ~UTLed[LINK_LED];			debugk ("LED_OPEN: pdpar=0x%x  pddir=0x%x  pddat=0x%x\n",		cp->iop_pdpar, cp->iop_pddir, cp->iop_pddat);	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){	volatile iop8xx_t *cp = iop_p;		debugk ("device_release(%p,%p)\n", inode, file);	/* We're now ready for our next caller */	Device_Open--;	MOD_DEC_USE_COUNT;	debugk ("LED_CLOSE: pdpar=0x%x  pddir=0x%x  pddat=0x%x\n",		cp->iop_pdpar, cp->iop_pddir, cp->iop_pddat);			/*turn off led*/	cp->iop_pddat &= ~UTLed[ALARM_LED];	cp->iop_pddat &= ~UTLed[LINK_LED];	debugk ("LED_CLOSE: pdpar=0x%x  pddir=0x%x  pddat=0x%x\n",		cp->iop_pdpar, cp->iop_pddir, cp->iop_pddat);	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 */{	volatile iop8xx_t *cp = iop_p;		unsigned char c[2];		c[0] = cp->iop_pddat & UTLed[LINK_LED];	c[1] = cp->iop_pddat & UTLed[ALARM_LED];		put_user (c[0], buffer++);	put_user (c[1], buffer);		debugk ("Read: value = 0x%02x%02x\n", c[0],c[1]);	return (2);		/* read() always returns exactly two byte */}/* * 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 */{	volatile iop8xx_t *cp = iop_p;			int error;	ushort pddat;	unsigned char c1,c2;        ushort   data;	if(length > 2)		return -9;			pddat  = cp->iop_pddat;        pddat &= ~UTLed[LINK_LED];	pddat &= ~UTLed[ALARM_LED];	if ((error = get_user (c1, buffer++)) != 0) 	{		return (-10);	}	if ((error = get_user (c2, buffer++)) != 0) 	{		return (-20);	}	data = (c1 << 8) | c2;	cp->iop_pddat = pddat | (data & 0x1800) ;	return (length);}/****************************** **** Module Declarations ***** **************************** */#ifdef MODULE/* * Initialize the module */int init_module (void){	return led_init();}/* * Cleanup - unregister the appropriate file from /proc */void cleanup_module (void){	int ret;	/*	 * Unregister the device	 */	ret = unregister_chrdev (Major, DEVICE_NAME);	/*	 * If there's an error, report it	 */	if (ret < 0) {		printk ("unregister_chrdev: error %d\n", ret);	}}#endif	/* MODULE */

⌨️ 快捷键说明

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