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.33-rc2 267 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/smp_lock.h> 10#include <linux/types.h> 11#include <linux/errno.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 lock_kernel(); 72 /* enforce single access, vfd_is_open is protected by BKL */ 73 if (vfd_is_open) { 74 unlock_kernel(); 75 return -EBUSY; 76 } 77 vfd_is_open = 1; 78 79 unlock_kernel(); 80 return 0; 81} 82 83static int briq_panel_release(struct inode *ino, struct file *filep) 84{ 85 if (!vfd_is_open) 86 return -ENODEV; 87 88 vfd_is_open = 0; 89 90 return 0; 91} 92 93static ssize_t briq_panel_read(struct file *file, char __user *buf, size_t count, 94 loff_t *ppos) 95{ 96 unsigned short c; 97 unsigned char cp; 98 99 if (!vfd_is_open) 100 return -ENODEV; 101 102 c = (inb(BRIQ_PANEL_LED_IOPORT) & 0x000c) | (ledpb & 0x0003); 103 set_led(' '); 104 /* upper button released */ 105 if ((!(ledpb & 0x0004)) && (c & 0x0004)) { 106 cp = ' '; 107 ledpb = c; 108 if (copy_to_user(buf, &cp, 1)) 109 return -EFAULT; 110 return 1; 111 } 112 /* lower button released */ 113 else if ((!(ledpb & 0x0008)) && (c & 0x0008)) { 114 cp = '\r'; 115 ledpb = c; 116 if (copy_to_user(buf, &cp, 1)) 117 return -EFAULT; 118 return 1; 119 } else { 120 ledpb = c; 121 return 0; 122 } 123} 124 125static void scroll_vfd( void ) 126{ 127 int i; 128 129 for (i=0; i<20; i++) { 130 vfd[i] = vfd[i+20]; 131 vfd[i+20] = ' '; 132 } 133 vfd_cursor = 20; 134} 135 136static ssize_t briq_panel_write(struct file *file, const char __user *buf, size_t len, 137 loff_t *ppos) 138{ 139 size_t indx = len; 140 int i, esc = 0; 141 142 if (!vfd_is_open) 143 return -EBUSY; 144 145 for (;;) { 146 char c; 147 if (!indx) 148 break; 149 if (get_user(c, buf)) 150 return -EFAULT; 151 if (esc) { 152 set_led(c); 153 esc = 0; 154 } else if (c == 27) { 155 esc = 1; 156 } else if (c == 12) { 157 /* do a form feed */ 158 for (i=0; i<40; i++) 159 vfd[i] = ' '; 160 vfd_cursor = 0; 161 } else if (c == 10) { 162 if (vfd_cursor < 20) 163 vfd_cursor = 20; 164 else if (vfd_cursor < 40) 165 vfd_cursor = 40; 166 else if (vfd_cursor < 60) 167 vfd_cursor = 60; 168 if (vfd_cursor > 59) 169 scroll_vfd(); 170 } else { 171 /* just a character */ 172 if (vfd_cursor > 39) 173 scroll_vfd(); 174 vfd[vfd_cursor++] = c; 175 } 176 indx--; 177 buf++; 178 } 179 update_vfd(); 180 181 return len; 182} 183 184static const struct file_operations briq_panel_fops = { 185 .owner = THIS_MODULE, 186 .read = briq_panel_read, 187 .write = briq_panel_write, 188 .open = briq_panel_open, 189 .release = briq_panel_release, 190}; 191 192static struct miscdevice briq_panel_miscdev = { 193 BRIQ_PANEL_MINOR, 194 "briq_panel", 195 &briq_panel_fops 196}; 197 198static int __init briq_panel_init(void) 199{ 200 struct device_node *root = of_find_node_by_path("/"); 201 const char *machine; 202 int i; 203 204 machine = of_get_property(root, "model", NULL); 205 if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) { 206 of_node_put(root); 207 return -ENODEV; 208 } 209 of_node_put(root); 210 211 printk(KERN_INFO 212 "briq_panel: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n", 213 BRIQ_PANEL_VER); 214 215 if (!request_region(BRIQ_PANEL_VFD_IOPORT, 4, "BRIQ Front Panel")) 216 return -EBUSY; 217 218 if (!request_region(BRIQ_PANEL_LED_IOPORT, 2, "BRIQ Front Panel")) { 219 release_region(BRIQ_PANEL_VFD_IOPORT, 4); 220 return -EBUSY; 221 } 222 ledpb = inb(BRIQ_PANEL_LED_IOPORT) & 0x000c; 223 224 if (misc_register(&briq_panel_miscdev) < 0) { 225 release_region(BRIQ_PANEL_VFD_IOPORT, 4); 226 release_region(BRIQ_PANEL_LED_IOPORT, 2); 227 return -EBUSY; 228 } 229 230 outb(0x38, BRIQ_PANEL_VFD_IOPORT); /* Function set */ 231 outb(0x01, BRIQ_PANEL_VFD_IOPORT); /* Clear display */ 232 outb(0x0c, BRIQ_PANEL_VFD_IOPORT); /* Display on */ 233 outb(0x06, BRIQ_PANEL_VFD_IOPORT); /* Entry normal */ 234 for (i=0; i<40; i++) 235 vfd[i]=' '; 236#ifndef MODULE 237 vfd[0] = 'L'; 238 vfd[1] = 'o'; 239 vfd[2] = 'a'; 240 vfd[3] = 'd'; 241 vfd[4] = 'i'; 242 vfd[5] = 'n'; 243 vfd[6] = 'g'; 244 vfd[7] = ' '; 245 vfd[8] = '.'; 246 vfd[9] = '.'; 247 vfd[10] = '.'; 248#endif /* !MODULE */ 249 250 update_vfd(); 251 252 return 0; 253} 254 255static void __exit briq_panel_exit(void) 256{ 257 misc_deregister(&briq_panel_miscdev); 258 release_region(BRIQ_PANEL_VFD_IOPORT, 4); 259 release_region(BRIQ_PANEL_LED_IOPORT, 2); 260} 261 262module_init(briq_panel_init); 263module_exit(briq_panel_exit); 264 265MODULE_LICENSE("GPL"); 266MODULE_AUTHOR("Karsten Jeppesen <karsten@jeppesens.com>"); 267MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel");