Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.20 270 lines 5.4 kB view raw
1/* 2 * Drivers for the Total Impact PPC based computer "BRIQ" 3 * by Dr. Karsten Jeppesen 4 * 5 */ 6 7#include <linux/module.h> 8 9#include <linux/types.h> 10#include <linux/errno.h> 11#include <linux/sched.h> 12#include <linux/tty.h> 13#include <linux/timer.h> 14#include <linux/kernel.h> 15#include <linux/wait.h> 16#include <linux/string.h> 17#include <linux/slab.h> 18#include <linux/ioport.h> 19#include <linux/delay.h> 20#include <linux/miscdevice.h> 21#include <linux/fs.h> 22#include <linux/mm.h> 23#include <linux/init.h> 24 25#include <asm/uaccess.h> 26#include <asm/io.h> 27#include <asm/prom.h> 28 29#define BRIQ_PANEL_MINOR 156 30#define BRIQ_PANEL_VFD_IOPORT 0x0390 31#define BRIQ_PANEL_LED_IOPORT 0x0398 32#define BRIQ_PANEL_VER "1.1 (04/20/2002)" 33#define BRIQ_PANEL_MSG0 "Loading Linux" 34 35static int vfd_is_open; 36static unsigned char vfd[40]; 37static int vfd_cursor; 38static unsigned char ledpb, led; 39 40static void update_vfd(void) 41{ 42 int i; 43 44 /* cursor home */ 45 outb(0x02, BRIQ_PANEL_VFD_IOPORT); 46 for (i=0; i<20; i++) 47 outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1); 48 49 /* cursor to next line */ 50 outb(0xc0, BRIQ_PANEL_VFD_IOPORT); 51 for (i=20; i<40; i++) 52 outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1); 53 54} 55 56static void set_led(char state) 57{ 58 if (state == 'R') 59 led = 0x01; 60 else if (state == 'G') 61 led = 0x02; 62 else if (state == 'Y') 63 led = 0x03; 64 else if (state == 'X') 65 led = 0x00; 66 outb(led, BRIQ_PANEL_LED_IOPORT); 67} 68 69static int briq_panel_open(struct inode *ino, struct file *filep) 70{ 71 /* enforce single access */ 72 if (vfd_is_open) 73 return -EBUSY; 74 vfd_is_open = 1; 75 76 return 0; 77} 78 79static int briq_panel_release(struct inode *ino, struct file *filep) 80{ 81 if (!vfd_is_open) 82 return -ENODEV; 83 84 vfd_is_open = 0; 85 86 return 0; 87} 88 89static ssize_t briq_panel_read(struct file *file, char __user *buf, size_t count, 90 loff_t *ppos) 91{ 92 unsigned short c; 93 unsigned char cp; 94 95#if 0 /* Can't seek (pread) on this device */ 96 if (ppos != &file->f_pos) 97 return -ESPIPE; 98#endif 99 100 if (!vfd_is_open) 101 return -ENODEV; 102 103 c = (inb(BRIQ_PANEL_LED_IOPORT) & 0x000c) | (ledpb & 0x0003); 104 set_led(' '); 105 /* upper button released */ 106 if ((!(ledpb & 0x0004)) && (c & 0x0004)) { 107 cp = ' '; 108 ledpb = c; 109 if (copy_to_user(buf, &cp, 1)) 110 return -EFAULT; 111 return 1; 112 } 113 /* lower button released */ 114 else if ((!(ledpb & 0x0008)) && (c & 0x0008)) { 115 cp = '\r'; 116 ledpb = c; 117 if (copy_to_user(buf, &cp, 1)) 118 return -EFAULT; 119 return 1; 120 } else { 121 ledpb = c; 122 return 0; 123 } 124} 125 126static void scroll_vfd( void ) 127{ 128 int i; 129 130 for (i=0; i<20; i++) { 131 vfd[i] = vfd[i+20]; 132 vfd[i+20] = ' '; 133 } 134 vfd_cursor = 20; 135} 136 137static ssize_t briq_panel_write(struct file *file, const char __user *buf, size_t len, 138 loff_t *ppos) 139{ 140 size_t indx = len; 141 int i, esc = 0; 142 143#if 0 /* Can't seek (pwrite) on this device */ 144 if (ppos != &file->f_pos) 145 return -ESPIPE; 146#endif 147 148 if (!vfd_is_open) 149 return -EBUSY; 150 151 for (;;) { 152 char c; 153 if (!indx) 154 break; 155 if (get_user(c, buf)) 156 return -EFAULT; 157 if (esc) { 158 set_led(c); 159 esc = 0; 160 } else if (c == 27) { 161 esc = 1; 162 } else if (c == 12) { 163 /* do a form feed */ 164 for (i=0; i<40; i++) 165 vfd[i] = ' '; 166 vfd_cursor = 0; 167 } else if (c == 10) { 168 if (vfd_cursor < 20) 169 vfd_cursor = 20; 170 else if (vfd_cursor < 40) 171 vfd_cursor = 40; 172 else if (vfd_cursor < 60) 173 vfd_cursor = 60; 174 if (vfd_cursor > 59) 175 scroll_vfd(); 176 } else { 177 /* just a character */ 178 if (vfd_cursor > 39) 179 scroll_vfd(); 180 vfd[vfd_cursor++] = c; 181 } 182 indx--; 183 buf++; 184 } 185 update_vfd(); 186 187 return len; 188} 189 190static struct file_operations briq_panel_fops = { 191 .owner = THIS_MODULE, 192 .read = briq_panel_read, 193 .write = briq_panel_write, 194 .open = briq_panel_open, 195 .release = briq_panel_release, 196}; 197 198static struct miscdevice briq_panel_miscdev = { 199 BRIQ_PANEL_MINOR, 200 "briq_panel", 201 &briq_panel_fops 202}; 203 204static int __init briq_panel_init(void) 205{ 206 struct device_node *root = find_path_device("/"); 207 const char *machine; 208 int i; 209 210 machine = get_property(root, "model", NULL); 211 if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) 212 return -ENODEV; 213 214 printk(KERN_INFO 215 "briq_panel: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n", 216 BRIQ_PANEL_VER); 217 218 if (!request_region(BRIQ_PANEL_VFD_IOPORT, 4, "BRIQ Front Panel")) 219 return -EBUSY; 220 221 if (!request_region(BRIQ_PANEL_LED_IOPORT, 2, "BRIQ Front Panel")) { 222 release_region(BRIQ_PANEL_VFD_IOPORT, 4); 223 return -EBUSY; 224 } 225 ledpb = inb(BRIQ_PANEL_LED_IOPORT) & 0x000c; 226 227 if (misc_register(&briq_panel_miscdev) < 0) { 228 release_region(BRIQ_PANEL_VFD_IOPORT, 4); 229 release_region(BRIQ_PANEL_LED_IOPORT, 2); 230 return -EBUSY; 231 } 232 233 outb(0x38, BRIQ_PANEL_VFD_IOPORT); /* Function set */ 234 outb(0x01, BRIQ_PANEL_VFD_IOPORT); /* Clear display */ 235 outb(0x0c, BRIQ_PANEL_VFD_IOPORT); /* Display on */ 236 outb(0x06, BRIQ_PANEL_VFD_IOPORT); /* Entry normal */ 237 for (i=0; i<40; i++) 238 vfd[i]=' '; 239#ifndef MODULE 240 vfd[0] = 'L'; 241 vfd[1] = 'o'; 242 vfd[2] = 'a'; 243 vfd[3] = 'd'; 244 vfd[4] = 'i'; 245 vfd[5] = 'n'; 246 vfd[6] = 'g'; 247 vfd[7] = ' '; 248 vfd[8] = '.'; 249 vfd[9] = '.'; 250 vfd[10] = '.'; 251#endif /* !MODULE */ 252 253 update_vfd(); 254 255 return 0; 256} 257 258static void __exit briq_panel_exit(void) 259{ 260 misc_deregister(&briq_panel_miscdev); 261 release_region(BRIQ_PANEL_VFD_IOPORT, 4); 262 release_region(BRIQ_PANEL_LED_IOPORT, 2); 263} 264 265module_init(briq_panel_init); 266module_exit(briq_panel_exit); 267 268MODULE_LICENSE("GPL"); 269MODULE_AUTHOR("Karsten Jeppesen <karsten@jeppesens.com>"); 270MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel");