aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/lasat/picvue_proc.c
diff options
context:
space:
mode:
authorBrian Murphy <brm@murphy.dk>2007-08-21 16:34:16 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-10-11 18:46:00 -0400
commit1f21d2bde0046e959b53756f74d96dfd040a803b (patch)
tree5ca1a0319982f1e665e57f22bd1dae1d90b07e35 /arch/mips/lasat/picvue_proc.c
parent0caf583398309398ec05fc76bff15c711e9f936d (diff)
[MIPS] Add back support for LASAT platforms
Signed-off-by: Brian Murphy <brian@murphy.dk> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/lasat/picvue_proc.c')
-rw-r--r--arch/mips/lasat/picvue_proc.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
new file mode 100644
index 000000000000..9947c1525822
--- /dev/null
+++ b/arch/mips/lasat/picvue_proc.c
@@ -0,0 +1,191 @@
1/*
2 * Picvue PVC160206 display driver
3 *
4 * Brian Murphy <brian.murphy@eicon.com>
5 *
6 */
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/errno.h>
11
12#include <linux/proc_fs.h>
13#include <linux/interrupt.h>
14
15#include <linux/timer.h>
16
17#include "picvue.h"
18
19static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
20static int pvc_linedata[PVC_NLINES];
21static struct proc_dir_entry *pvc_display_dir;
22static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
23#define DISPLAY_DIR_NAME "display"
24static int scroll_dir, scroll_interval;
25
26static struct timer_list timer;
27
28static void pvc_display(unsigned long data)
29{
30 int i;
31
32 pvc_clear();
33 for (i = 0; i < PVC_NLINES; i++)
34 pvc_write_string(pvc_lines[i], 0, i);
35}
36
37static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0);
38
39static int pvc_proc_read_line(char *page, char **start,
40 off_t off, int count,
41 int *eof, void *data)
42{
43 char *origpage = page;
44 int lineno = *(int *)data;
45
46 if (lineno < 0 || lineno > PVC_NLINES) {
47 printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno);
48 return 0;
49 }
50
51 down(&pvc_sem);
52 page += sprintf(page, "%s\n", pvc_lines[lineno]);
53 up(&pvc_sem);
54
55 return page - origpage;
56}
57
58static int pvc_proc_write_line(struct file *file, const char *buffer,
59 unsigned long count, void *data)
60{
61 int origcount = count;
62 int lineno = *(int *)data;
63
64 if (lineno < 0 || lineno > PVC_NLINES) {
65 printk(KERN_WARNING "proc_write_line: invalid lineno %d\n",
66 lineno);
67 return origcount;
68 }
69
70 if (count > PVC_LINELEN)
71 count = PVC_LINELEN;
72
73 if (buffer[count-1] == '\n')
74 count--;
75
76 down(&pvc_sem);
77 strncpy(pvc_lines[lineno], buffer, count);
78 pvc_lines[lineno][count] = '\0';
79 up(&pvc_sem);
80
81 tasklet_schedule(&pvc_display_tasklet);
82
83 return origcount;
84}
85
86static int pvc_proc_write_scroll(struct file *file, const char *buffer,
87 unsigned long count, void *data)
88{
89 int origcount = count;
90 int cmd = simple_strtol(buffer, NULL, 10);
91
92 down(&pvc_sem);
93 if (scroll_interval != 0)
94 del_timer(&timer);
95
96 if (cmd == 0) {
97 scroll_dir = 0;
98 scroll_interval = 0;
99 } else {
100 if (cmd < 0) {
101 scroll_dir = -1;
102 scroll_interval = -cmd;
103 } else {
104 scroll_dir = 1;
105 scroll_interval = cmd;
106 }
107 add_timer(&timer);
108 }
109 up(&pvc_sem);
110
111 return origcount;
112}
113
114static int pvc_proc_read_scroll(char *page, char **start,
115 off_t off, int count,
116 int *eof, void *data)
117{
118 char *origpage = page;
119
120 down(&pvc_sem);
121 page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
122 up(&pvc_sem);
123
124 return page - origpage;
125}
126
127
128void pvc_proc_timerfunc(unsigned long data)
129{
130 if (scroll_dir < 0)
131 pvc_move(DISPLAY|RIGHT);
132 else if (scroll_dir > 0)
133 pvc_move(DISPLAY|LEFT);
134
135 timer.expires = jiffies + scroll_interval;
136 add_timer(&timer);
137}
138
139static void pvc_proc_cleanup(void)
140{
141 int i;
142 for (i = 0; i < PVC_NLINES; i++)
143 remove_proc_entry(pvc_linename[i], pvc_display_dir);
144 remove_proc_entry("scroll", pvc_display_dir);
145 remove_proc_entry(DISPLAY_DIR_NAME, NULL);
146
147 del_timer(&timer);
148}
149
150static int __init pvc_proc_init(void)
151{
152 struct proc_dir_entry *proc_entry;
153 int i;
154
155 pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
156 if (pvc_display_dir == NULL)
157 goto error;
158
159 for (i = 0; i < PVC_NLINES; i++) {
160 strcpy(pvc_lines[i], "");
161 pvc_linedata[i] = i;
162 }
163 for (i = 0; i < PVC_NLINES; i++) {
164 proc_entry = create_proc_entry(pvc_linename[i], 0644,
165 pvc_display_dir);
166 if (proc_entry == NULL)
167 goto error;
168
169 proc_entry->read_proc = pvc_proc_read_line;
170 proc_entry->write_proc = pvc_proc_write_line;
171 proc_entry->data = &pvc_linedata[i];
172 }
173 proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir);
174 if (proc_entry == NULL)
175 goto error;
176
177 proc_entry->write_proc = pvc_proc_write_scroll;
178 proc_entry->read_proc = pvc_proc_read_scroll;
179
180 init_timer(&timer);
181 timer.function = pvc_proc_timerfunc;
182
183 return 0;
184error:
185 pvc_proc_cleanup();
186 return -ENOMEM;
187}
188
189module_init(pvc_proc_init);
190module_exit(pvc_proc_cleanup);
191MODULE_LICENSE("GPL");