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