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

📄 picvue_proc.c

📁 linux 内核源代码
💻 C
字号:
/* * Picvue PVC160206 display driver * * Brian Murphy <brian.murphy@eicon.com> * */#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/proc_fs.h>#include <linux/interrupt.h>#include <linux/timer.h>#include "picvue.h"static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];static int pvc_linedata[PVC_NLINES];static struct proc_dir_entry *pvc_display_dir;static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};#define DISPLAY_DIR_NAME "display"static int scroll_dir, scroll_interval;static struct timer_list timer;static void pvc_display(unsigned long data){	int i;	pvc_clear();	for (i = 0; i < PVC_NLINES; i++)		pvc_write_string(pvc_lines[i], 0, i);}static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0);static int pvc_proc_read_line(char *page, char **start,			     off_t off, int count,			     int *eof, void *data){	char *origpage = page;	int lineno = *(int *)data;	if (lineno < 0 || lineno > PVC_NLINES) {		printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno);		return 0;	}	down(&pvc_sem);	page += sprintf(page, "%s\n", pvc_lines[lineno]);	up(&pvc_sem);	return page - origpage;}static int pvc_proc_write_line(struct file *file, const char *buffer,			   unsigned long count, void *data){	int origcount = count;	int lineno = *(int *)data;	if (lineno < 0 || lineno > PVC_NLINES) {		printk(KERN_WARNING "proc_write_line: invalid lineno %d\n",		       lineno);		return origcount;	}	if (count > PVC_LINELEN)		count = PVC_LINELEN;	if (buffer[count-1] == '\n')		count--;	down(&pvc_sem);	strncpy(pvc_lines[lineno], buffer, count);	pvc_lines[lineno][count] = '\0';	up(&pvc_sem);	tasklet_schedule(&pvc_display_tasklet);	return origcount;}static int pvc_proc_write_scroll(struct file *file, const char *buffer,			   unsigned long count, void *data){	int origcount = count;	int cmd = simple_strtol(buffer, NULL, 10);	down(&pvc_sem);	if (scroll_interval != 0)		del_timer(&timer);	if (cmd == 0) {		scroll_dir = 0;		scroll_interval = 0;	} else {		if (cmd < 0) {			scroll_dir = -1;			scroll_interval = -cmd;		} else {			scroll_dir = 1;			scroll_interval = cmd;		}		add_timer(&timer);	}	up(&pvc_sem);	return origcount;}static int pvc_proc_read_scroll(char *page, char **start,			     off_t off, int count,			     int *eof, void *data){	char *origpage = page;	down(&pvc_sem);	page += sprintf(page, "%d\n", scroll_dir * scroll_interval);	up(&pvc_sem);	return page - origpage;}void pvc_proc_timerfunc(unsigned long data){	if (scroll_dir < 0)		pvc_move(DISPLAY|RIGHT);	else if (scroll_dir > 0)		pvc_move(DISPLAY|LEFT);	timer.expires = jiffies + scroll_interval;	add_timer(&timer);}static void pvc_proc_cleanup(void){	int i;	for (i = 0; i < PVC_NLINES; i++)		remove_proc_entry(pvc_linename[i], pvc_display_dir);	remove_proc_entry("scroll", pvc_display_dir);	remove_proc_entry(DISPLAY_DIR_NAME, NULL);	del_timer(&timer);}static int __init pvc_proc_init(void){	struct proc_dir_entry *proc_entry;	int i;	pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);	if (pvc_display_dir == NULL)		goto error;	for (i = 0; i < PVC_NLINES; i++) {		strcpy(pvc_lines[i], "");		pvc_linedata[i] = i;	}	for (i = 0; i < PVC_NLINES; i++) {		proc_entry = create_proc_entry(pvc_linename[i], 0644,					       pvc_display_dir);		if (proc_entry == NULL)			goto error;		proc_entry->read_proc = pvc_proc_read_line;		proc_entry->write_proc = pvc_proc_write_line;		proc_entry->data = &pvc_linedata[i];	}	proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir);	if (proc_entry == NULL)		goto error;	proc_entry->write_proc = pvc_proc_write_scroll;	proc_entry->read_proc = pvc_proc_read_scroll;	init_timer(&timer);	timer.function = pvc_proc_timerfunc;	return 0;error:	pvc_proc_cleanup();	return -ENOMEM;}module_init(pvc_proc_init);module_exit(pvc_proc_cleanup);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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