OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [char/] [fbmem.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 *  linux/drivers/char/fbmem.c
3
 *
4
 *  Copyright (C) 1994 Martin Schaller
5
 *
6
 * This file is subject to the terms and conditions of the GNU General Public
7
 * License.  See the file COPYING in the main directory of this archive
8
 * for more details.
9
 *
10
 */
11
 
12
/*
13
 * uClinux revisions for NO_MM
14
 * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
15
 *                     The Silver Hammer Group, Ltd.
16
 */
17
 
18
#include <linux/types.h>
19
#include <linux/errno.h>
20
#include <linux/sched.h>
21
#include <linux/kernel.h>
22
#include <linux/major.h>
23
#include <linux/malloc.h>
24
#include <linux/mman.h>
25
#include <linux/tty.h>
26
 
27
#include <asm/segment.h>
28
#include <asm/bootinfo.h>
29
#include <asm/page.h>
30
#include <asm/pgtable.h>
31
 
32
#include <linux/fb.h>
33
 
34
#define FB_MAJOR        29
35
 
36
#define FB_MODES_SHIFT    5     /* 32 modes per framebuffer */
37
#define FB_NUM_MINORS   256     /* 256 Minors               */
38
#define FB_MAX          (FB_NUM_MINORS / (1 << FB_MODES_SHIFT))
39
 
40
#define GET_INODE(i) MKDEV(FB_MAJOR, (i) << FB_MODES_SHIFT)
41
#define GET_FB_IDX(node) (MINOR(node) >> FB_MODES_SHIFT)
42
#define GET_FB_VAR_IDX(node) (MINOR(node) & ((1 << FB_MODES_SHIFT)-1)) 
43
 
44
struct fb_ops *registered_fb[FB_MAX];
45
struct fb_var_screeninfo *registered_fb_var[FB_MAX];
46
int registered_fb_var_num[FB_MAX];
47
int fb_curr_open[FB_MAX];
48
int fb_open_count[FB_MAX];
49
 
50
static inline int PROC_CONSOLE(void)
51
{
52
        if (!current->tty)
53
                return fg_console;
54
 
55
        if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
56
                /* XXX Should report error here? */
57
                return fg_console;
58
 
59
        if (MINOR(current->tty->device) < 1)
60
                return fg_console;
61
 
62
        return MINOR(current->tty->device) - 1;
63
}
64
 
65
static int
66
fb_read(struct inode *inode, struct file *file, char *buf, int count)
67
{
68
        unsigned long p = file->f_pos;
69
        struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)];
70
        struct fb_fix_screeninfo fix;
71
        char *base_addr;
72
        int copy_size;
73
 
74
        if (! fb)
75
                return -ENODEV;
76
        if (count < 0)
77
                return -EINVAL;
78
 
79
        fb->fb_get_fix(&fix,PROC_CONSOLE());
80
        base_addr=(char *) fix.smem_start;
81
        copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
82
        memcpy_tofs(buf, base_addr+p, copy_size);
83
        file->f_pos += copy_size;
84
        return copy_size;
85
}
86
 
87
static int
88
fb_write(struct inode *inode, struct file *file, const char *buf, int count)
89
{
90
        unsigned long p = file->f_pos;
91
        struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)];
92
        struct fb_fix_screeninfo fix;
93
        char *base_addr;
94
        int copy_size;
95
 
96
        if (! fb)
97
                return -ENODEV;
98
        if (count < 0)
99
                return -EINVAL;
100
        fb->fb_get_fix(&fix, PROC_CONSOLE());
101
        base_addr=(char *) fix.smem_start;
102
        copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
103
        memcpy_fromfs(base_addr+p, buf, copy_size);
104
        file->f_pos += copy_size;
105
        return copy_size;
106
}
107
 
108
 
109
static int
110
fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
111
         unsigned long arg)
112
{
113
        struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)];
114
        struct fb_cmap cmap;
115
        struct fb_var_screeninfo var;
116
        struct fb_fix_screeninfo fix;
117
 
118
        int i,fbidx,vidx;
119
 
120
        if (! fb)
121
                return -ENODEV;
122
        switch (cmd) {
123
        case FBIOGET_VSCREENINFO:
124
                i = verify_area(VERIFY_WRITE, (void *) arg,
125
                                sizeof(struct fb_var_screeninfo));
126
                if (i) return i;
127
                fbidx=GET_FB_IDX(inode->i_rdev);
128
                vidx=GET_FB_VAR_IDX(inode->i_rdev);
129
                if (! vidx) /* ask device driver for current */
130
                        i=fb->fb_get_var(&var, PROC_CONSOLE());
131
                else
132
                        var=registered_fb_var[fbidx][vidx-1];
133
                memcpy_tofs((void *) arg, &var, sizeof(var));
134
                return i;
135
        case FBIOPUT_VSCREENINFO:
136
                i = verify_area(VERIFY_WRITE, (void *) arg,
137
                                sizeof(struct fb_var_screeninfo));
138
                if (i) return i;
139
                memcpy_fromfs(&var, (void *) arg, sizeof(var));
140
                i=fb->fb_set_var(&var, PROC_CONSOLE());
141
                memcpy_tofs((void *) arg, &var, sizeof(var));
142
                fbidx=GET_FB_IDX(inode->i_rdev);
143
                vidx=GET_FB_VAR_IDX(inode->i_rdev);
144
                if (! i && vidx)
145
                        registered_fb_var[fbidx][vidx-1]=var;
146
                return i;
147
        case FBIOGET_FSCREENINFO:
148
                i = verify_area(VERIFY_WRITE, (void *) arg,
149
                                sizeof(struct fb_fix_screeninfo));
150
                if (i)  return i;
151
                i=fb->fb_get_fix(&fix, PROC_CONSOLE());
152
                memcpy_tofs((void *) arg, &fix, sizeof(fix));
153
                return i;
154
        case FBIOPUTCMAP:
155
                i = verify_area(VERIFY_READ, (void *) arg,
156
                                sizeof(struct fb_cmap));
157
                if (i) return i;
158
                memcpy_fromfs(&cmap, (void *) arg, sizeof(cmap));
159
                i = verify_area(VERIFY_READ, (void *) cmap.red,
160
                                cmap.len * sizeof(unsigned short));
161
                if (i) return i;
162
                i = verify_area(VERIFY_READ, (void *) cmap.green,
163
                                cmap.len * sizeof(unsigned short));
164
                if (i) return i;
165
                i = verify_area(VERIFY_READ, (void *) cmap.blue,
166
                                cmap.len * sizeof(unsigned short));
167
                if (i) return i;
168
                if (cmap.transp) {
169
                        i = verify_area(VERIFY_READ, (void *) cmap.transp,
170
                                        cmap.len * sizeof(unsigned short));
171
                        if (i) return i;
172
                }
173
                return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE()));
174
        case FBIOGETCMAP:
175
                i = verify_area(VERIFY_READ, (void *) arg,
176
                                sizeof(struct fb_cmap));
177
                if (i)  return i;
178
                memcpy_fromfs(&cmap, (void *) arg, sizeof(cmap));
179
                i = verify_area(VERIFY_WRITE, (void *) cmap.red,
180
                                cmap.len * sizeof(unsigned short));
181
                if (i) return i;
182
                i = verify_area(VERIFY_WRITE, (void *) cmap.green,
183
                                cmap.len * sizeof(unsigned short));
184
                if (i) return i;
185
                i = verify_area(VERIFY_WRITE, (void *) cmap.blue,
186
                                cmap.len * sizeof(unsigned short));
187
                if (i) return i;
188
                if (cmap.transp) {
189
                        i = verify_area(VERIFY_WRITE, (void *) cmap.transp,
190
                                        cmap.len * sizeof(unsigned short));
191
                        if (i) return i;
192
                }
193
                return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE()));
194
        case FBIOPAN_DISPLAY:
195
                i = verify_area(VERIFY_WRITE, (void *) arg,
196
                                sizeof(struct fb_var_screeninfo));
197
                if (i) return i;
198
                memcpy_fromfs(&var, (void *) arg, sizeof(var));
199
                i=fb->fb_pan_display(&var, PROC_CONSOLE());
200
                memcpy_tofs((void *) arg, &var, sizeof(var));
201
                fbidx=GET_FB_IDX(inode->i_rdev);
202
                vidx=GET_FB_VAR_IDX(inode->i_rdev);
203
                if (! i && vidx)
204
                        registered_fb_var[fbidx][vidx-1]=var;
205
                return i;
206
        default:
207
                return (fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE()));
208
        }
209
}
210
 
211
static int
212
fb_mmap(struct inode *inode, struct file *file, struct vm_area_struct * vma)
213
{
214
        struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)];
215
        struct fb_fix_screeninfo fix;
216
 
217
        if (! fb)
218
                return -ENODEV;
219
        fb->fb_get_fix(&fix, PROC_CONSOLE());
220
#ifndef NO_MM
221
        if ((vma->vm_end - vma->vm_start + vma->vm_offset) > fix.smem_len)
222
                return -EINVAL;
223
        vma->vm_offset += fix.smem_start;
224
        if (vma->vm_offset & ~PAGE_MASK)
225
                return -ENXIO;
226
        if (m68k_is040or060) {
227
                pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
228
                /* Use write-through cache mode */
229
                pgprot_val(vma->vm_page_prot) |= _PAGE_CACHE040W;
230
        }
231
        if (remap_page_range(vma->vm_start, vma->vm_offset,
232
                             vma->vm_end - vma->vm_start, vma->vm_page_prot))
233
                return -EAGAIN;
234
        vma->vm_inode = inode;
235
        inode->i_count++;
236
#else /* !NO_MM */
237
        vma->vm_start = fix.smem_start+vma->vm_offset;
238
#endif /* !NO_MM */
239
        return 0;
240
}
241
 
242
static int
243
fb_open(struct inode *inode, struct file *file)
244
{
245
        int fbidx=GET_FB_IDX(inode->i_rdev);
246
        int vidx=GET_FB_VAR_IDX(inode->i_rdev);
247
        struct fb_ops *fb = registered_fb[fbidx];
248
        int err;
249
 
250
        if (! vidx)             /* fb?current always succeeds */
251
                return 0;
252
        if (vidx > registered_fb_var_num[fbidx])
253
                return -EINVAL;
254
        if (fb_curr_open[fbidx] && fb_curr_open[fbidx] != vidx)
255
                return -EBUSY;
256
        if (file->f_mode & 2) /* only set parameters if opened writeable */
257
                if ((err=fb->fb_set_var(registered_fb_var[fbidx] + vidx-1, PROC_CONSOLE())))
258
                        return err;
259
        fb_curr_open[fbidx] = vidx;
260
        fb_open_count[fbidx]++;
261
        return 0;
262
}
263
 
264
static void
265
fb_release(struct inode *inode, struct file *file)
266
{
267
        int fbidx=GET_FB_IDX(inode->i_rdev);
268
        int vidx=GET_FB_VAR_IDX(inode->i_rdev);
269
        if (! vidx)
270
                return;
271
        if (! (--fb_open_count[fbidx]))
272
                fb_curr_open[fbidx]=0;
273
}
274
 
275
static struct file_operations fb_fops = {
276
        NULL,           /* lseek        */
277
        fb_read,        /* read         */
278
        fb_write,       /* write        */
279
        NULL,           /* readdir      */
280
        NULL,           /* select       */
281
        fb_ioctl,       /* ioctl        */
282
        fb_mmap,        /* mmap         */
283
        fb_open,        /* open         */
284
        fb_release,     /* release      */
285
        NULL            /* fsync        */
286
};
287
 
288
int
289
register_framebuffer(char *id, int *node, struct fb_ops *fbops, int fbvar_num,
290
                     struct fb_var_screeninfo *fbvar)
291
{
292
        int i;
293
        for (i = 0 ; i < FB_MAX; i++)
294
                if (! registered_fb[i])
295
                        break;
296
        if (i == FB_MAX)
297
                return -ENXIO;
298
        registered_fb[i]=fbops;
299
        registered_fb_var[i]=fbvar;
300
        registered_fb_var_num[i]=fbvar_num;
301
        *node=GET_INODE(i);
302
        return 0;
303
}
304
 
305
int
306
unregister_framebuffer(int node)
307
{
308
        int i=GET_FB_IDX(node);
309
        if (! registered_fb[i])
310
                return -EINVAL;
311
        registered_fb[i]=NULL;
312
        registered_fb_var[i]=NULL;
313
        return 0;
314
}
315
 
316
int
317
fbmem_init(void)
318
{
319
        if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
320
                printk("unable to get major %d for fb devs\n", FB_MAJOR);
321
        return 0;
322
}
323
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.