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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [macintosh/] [ans-lcd.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * /dev/lcd driver for Apple Network Servers.
3
 */
4
 
5
#include <linux/types.h>
6
#include <linux/errno.h>
7
#include <linux/kernel.h>
8
#include <linux/miscdevice.h>
9
#include <linux/fcntl.h>
10
#include <linux/init.h>
11
#include <linux/delay.h>
12
#include <linux/fs.h>
13
 
14
#include <asm/uaccess.h>
15
#include <asm/sections.h>
16
#include <asm/prom.h>
17
#include <asm/io.h>
18
 
19
#include "ans-lcd.h"
20
 
21
#define ANSLCD_ADDR             0xf301c000
22
#define ANSLCD_CTRL_IX 0x00
23
#define ANSLCD_DATA_IX 0x10
24
 
25
static unsigned long anslcd_short_delay = 80;
26
static unsigned long anslcd_long_delay = 3280;
27
static volatile unsigned char __iomem *anslcd_ptr;
28
 
29
#undef DEBUG
30
 
31
static void
32
anslcd_write_byte_ctrl ( unsigned char c )
33
{
34
#ifdef DEBUG
35
        printk(KERN_DEBUG "LCD: CTRL byte: %02x\n",c);
36
#endif
37
        out_8(anslcd_ptr + ANSLCD_CTRL_IX, c);
38
        switch(c) {
39
                case 1:
40
                case 2:
41
                case 3:
42
                        udelay(anslcd_long_delay); break;
43
                default: udelay(anslcd_short_delay);
44
        }
45
}
46
 
47
static void
48
anslcd_write_byte_data ( unsigned char c )
49
{
50
        out_8(anslcd_ptr + ANSLCD_DATA_IX, c);
51
        udelay(anslcd_short_delay);
52
}
53
 
54
static ssize_t
55
anslcd_write( struct file * file, const char __user * buf,
56
                                size_t count, loff_t *ppos )
57
{
58
        const char __user *p = buf;
59
        int i;
60
 
61
#ifdef DEBUG
62
        printk(KERN_DEBUG "LCD: write\n");
63
#endif
64
 
65
        if (!access_ok(VERIFY_READ, buf, count))
66
                return -EFAULT;
67
        for ( i = *ppos; count > 0; ++i, ++p, --count )
68
        {
69
                char c;
70
                __get_user(c, p);
71
                anslcd_write_byte_data( c );
72
        }
73
        *ppos = i;
74
        return p - buf;
75
}
76
 
77
static int
78
anslcd_ioctl( struct inode * inode, struct file * file,
79
                                unsigned int cmd, unsigned long arg )
80
{
81
        char ch, __user *temp;
82
 
83
#ifdef DEBUG
84
        printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg);
85
#endif
86
 
87
        switch ( cmd )
88
        {
89
        case ANSLCD_CLEAR:
90
                anslcd_write_byte_ctrl ( 0x38 );
91
                anslcd_write_byte_ctrl ( 0x0f );
92
                anslcd_write_byte_ctrl ( 0x06 );
93
                anslcd_write_byte_ctrl ( 0x01 );
94
                anslcd_write_byte_ctrl ( 0x02 );
95
                return 0;
96
        case ANSLCD_SENDCTRL:
97
                temp = (char __user *) arg;
98
                __get_user(ch, temp);
99
                for (; ch; temp++) { /* FIXME: This is ugly, but should work, as a \0 byte is not a valid command code */
100
                        anslcd_write_byte_ctrl ( ch );
101
                        __get_user(ch, temp);
102
                }
103
                return 0;
104
        case ANSLCD_SETSHORTDELAY:
105
                if (!capable(CAP_SYS_ADMIN))
106
                        return -EACCES;
107
                anslcd_short_delay=arg;
108
                return 0;
109
        case ANSLCD_SETLONGDELAY:
110
                if (!capable(CAP_SYS_ADMIN))
111
                        return -EACCES;
112
                anslcd_long_delay=arg;
113
                return 0;
114
        default:
115
                return -EINVAL;
116
        }
117
}
118
 
119
static int
120
anslcd_open( struct inode * inode, struct file * file )
121
{
122
        return 0;
123
}
124
 
125
const struct file_operations anslcd_fops = {
126
        .write  = anslcd_write,
127
        .ioctl  = anslcd_ioctl,
128
        .open   = anslcd_open,
129
};
130
 
131
static struct miscdevice anslcd_dev = {
132
        ANSLCD_MINOR,
133
        "anslcd",
134
        &anslcd_fops
135
};
136
 
137
const char anslcd_logo[] =      "********************"  /* Line #1 */
138
                                "*      LINUX!      *"  /* Line #3 */
139
                                "*    Welcome to    *"  /* Line #2 */
140
                                "********************"; /* Line #4 */
141
 
142
static int __init
143
anslcd_init(void)
144
{
145
        int a;
146
        int retval;
147
        struct device_node* node;
148
 
149
        node = of_find_node_by_name(NULL, "lcd");
150
        if (!node || !node->parent || strcmp(node->parent->name, "gc")) {
151
                of_node_put(node);
152
                return -ENODEV;
153
        }
154
        of_node_put(node);
155
 
156
        anslcd_ptr = ioremap(ANSLCD_ADDR, 0x20);
157
 
158
        retval = misc_register(&anslcd_dev);
159
        if(retval < 0){
160
                printk(KERN_INFO "LCD: misc_register failed\n");
161
                iounmap(anslcd_ptr);
162
                return retval;
163
        }
164
 
165
#ifdef DEBUG
166
        printk(KERN_DEBUG "LCD: init\n");
167
#endif
168
 
169
        anslcd_write_byte_ctrl ( 0x38 );
170
        anslcd_write_byte_ctrl ( 0x0c );
171
        anslcd_write_byte_ctrl ( 0x06 );
172
        anslcd_write_byte_ctrl ( 0x01 );
173
        anslcd_write_byte_ctrl ( 0x02 );
174
        for(a=0;a<80;a++) {
175
                anslcd_write_byte_data(anslcd_logo[a]);
176
        }
177
        return 0;
178
}
179
 
180
static void __exit
181
anslcd_exit(void)
182
{
183
        misc_deregister(&anslcd_dev);
184
        iounmap(anslcd_ptr);
185
}
186
 
187
module_init(anslcd_init);
188
module_exit(anslcd_exit);

powered by: WebSVN 2.1.0

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