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