X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Flcd.c;h=cf01a720eb2eff74a8154510cfd970ebbfb60f8d;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=41f2d4e41751e7cf30845b1cd76602c2749256fe;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 41f2d4e41..cf01a720e 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -12,7 +12,7 @@ * */ -#define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ +#define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ #include #include @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -32,11 +33,14 @@ #include "lcd.h" -static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg); +static DEFINE_SPINLOCK(lcd_lock); + +static int lcd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); -static int lcd_present = 1; +static unsigned int lcd_present = 1; +/* used in arch/mips/cobalt/reset.c */ int led_state = 0; #if defined(CONFIG_TULIP) && 0 @@ -57,19 +61,18 @@ int lcd_register_linkcheck_func(int iface_num, void *func, void *cookie) } #endif -static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static int lcd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { struct lcd_display button_display; unsigned long address, a; - int index; switch (cmd) { case LCD_On: udelay(150); BusyCheck(); LCDWriteInst(0x0F); - break; + break; case LCD_Off: udelay(150); @@ -95,7 +98,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, case LCD_Clear: udelay(150); BusyCheck(); - LCDWriteInst(0x01); + LCDWriteInst(0x01); break; case LCD_Cursor_Left: @@ -108,86 +111,95 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, udelay(150); BusyCheck(); LCDWriteInst(0x14); - break; + break; case LCD_Cursor_Off: udelay(150); - BusyCheck(); - LCDWriteInst(0x0C); - break; - - case LCD_Cursor_On: - udelay(150); - BusyCheck(); - LCDWriteInst(0x0F); - break; - - case LCD_Blink_Off: - udelay(150); - BusyCheck(); - LCDWriteInst(0x0E); - break; - - case LCD_Get_Cursor_Pos:{ - struct lcd_display display; + BusyCheck(); + LCDWriteInst(0x0C); + break; + case LCD_Cursor_On: udelay(150); - BusyCheck(); - display.cursor_address = ( LCDReadInst ); - display.cursor_address = ( display.cursor_address & 0x07F ); - if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) - return -EFAULT; + BusyCheck(); + LCDWriteInst(0x0F); + break; + case LCD_Blink_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0E); break; + + case LCD_Get_Cursor_Pos:{ + struct lcd_display display; + + udelay(150); + BusyCheck(); + display.cursor_address = (LCDReadInst); + display.cursor_address = + (display.cursor_address & 0x07F); + if (copy_to_user + ((struct lcd_display *) arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + + break; } - case LCD_Set_Cursor_Pos: { - struct lcd_display display; + case LCD_Set_Cursor_Pos:{ + struct lcd_display display; - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; + if (copy_from_user + (&display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - a = (display.cursor_address | kLCD_Addr ); + a = (display.cursor_address | kLCD_Addr); - udelay(150); - BusyCheck(); - LCDWriteInst( a ); + udelay(150); + BusyCheck(); + LCDWriteInst(a); - break; + break; } - - case LCD_Get_Cursor: { - struct lcd_display display; - udelay(150); - BusyCheck(); - display.character = LCDReadData; + case LCD_Get_Cursor:{ + struct lcd_display display; - if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) - return -EFAULT; - udelay(150); - BusyCheck(); - LCDWriteInst(0x10); + udelay(150); + BusyCheck(); + display.character = LCDReadData; - break; + if (copy_to_user + ((struct lcd_display *) arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; } case LCD_Set_Cursor:{ - struct lcd_display display; - - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; + struct lcd_display display; - udelay(150); - BusyCheck(); - LCDWriteData( display.character ); - udelay(150); - BusyCheck(); - LCDWriteInst(0x10); + if (copy_from_user + (&display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - break; - } + udelay(150); + BusyCheck(); + LCDWriteData(display.character); + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; + } case LCD_Disp_Left: @@ -208,294 +220,330 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, LCDWriteInst(0x02); break; - case LCD_Write: { - struct lcd_display display; - + case LCD_Write:{ + struct lcd_display display; + unsigned int index; + + + if (copy_from_user + (&display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; - - udelay(150); - BusyCheck(); - LCDWriteInst(0x80); - udelay(150); - BusyCheck(); - - for (index = 0; index < (display.size1); index++) { udelay(150); - BusyCheck(); - LCDWriteData( display.line1[index]); - BusyCheck(); - } - - udelay(150); - BusyCheck(); - LCDWriteInst(0xC0); - udelay(150); - BusyCheck(); - for (index = 0; index < (display.size2); index++) { - udelay(150); - BusyCheck(); - LCDWriteData( display.line2[index]); - } - - break; - } - - case LCD_Read: { - struct lcd_display display; + BusyCheck(); + LCDWriteInst(0x80); + udelay(150); + BusyCheck(); - BusyCheck(); - for (address = kDD_R00; address <= kDD_R01; address++) { - a = (address | kLCD_Addr ); + for (index = 0; index < (display.size1); index++) { + udelay(150); + BusyCheck(); + LCDWriteData(display.line1[index]); + BusyCheck(); + } udelay(150); BusyCheck(); - LCDWriteInst( a ); + LCDWriteInst(0xC0); udelay(150); BusyCheck(); - display.line1[address] = LCDReadData; + for (index = 0; index < (display.size2); index++) { + udelay(150); + BusyCheck(); + LCDWriteData(display.line2[index]); + } + + break; } - display.line1[ 0x27 ] = '\0'; - - for (address = kDD_R10; address <= kDD_R11; address++) { - a = (address | kLCD_Addr ); - - udelay(150); - BusyCheck(); - LCDWriteInst( a ); - - udelay(150); - BusyCheck(); - display.line2[address - 0x40 ] = LCDReadData; - } - - display.line2[ 0x27 ] = '\0'; - - if(copy_to_user((struct lcd_display*)arg, &display, - sizeof(struct lcd_display))) - return -EFAULT; - break; - } + case LCD_Read:{ + struct lcd_display display; -// set all GPIO leds to led_display.leds + BusyCheck(); + for (address = kDD_R00; address <= kDD_R01; + address++) { + a = (address | kLCD_Addr); + + udelay(150); + BusyCheck(); + LCDWriteInst(a); + udelay(150); + BusyCheck(); + display.line1[address] = LCDReadData; + } - case LED_Set: { - struct lcd_display led_display; - + display.line1[0x27] = '\0'; - if(copy_from_user(&led_display, (struct lcd_display*)arg, - sizeof(struct lcd_display))) - return -EFAULT; + for (address = kDD_R10; address <= kDD_R11; + address++) { + a = (address | kLCD_Addr); - led_state = led_display.leds; - LEDSet(led_state); + udelay(150); + BusyCheck(); + LCDWriteInst(a); + + udelay(150); + BusyCheck(); + display.line2[address - 0x40] = + LCDReadData; + } + + display.line2[0x27] = '\0'; + + if (copy_to_user + ((struct lcd_display *) arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } + +// set all GPIO leds to led_display.leds + + case LED_Set:{ + struct lcd_display led_display; - break; - } + + if (copy_from_user + (&led_display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; + + led_state = led_display.leds; + LEDSet(led_state); + + break; + } // set only bit led_display.leds - case LED_Bit_Set: { - int i; - int bit=1; - struct lcd_display led_display; + case LED_Bit_Set:{ + unsigned int i; + int bit = 1; + struct lcd_display led_display; - if(copy_from_user(&led_display, (struct lcd_display*)arg, - sizeof(struct lcd_display))) - return -EFAULT; + if (copy_from_user + (&led_display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - for (i=0;i<(int)led_display.leds;i++) - { - bit = 2*bit; + for (i = 0; i < (int) led_display.leds; i++) { + bit = 2 * bit; } - led_state = led_state | bit; - LEDSet(led_state); - break; - } + led_state = led_state | bit; + LEDSet(led_state); + break; + } // clear only bit led_display.leds - case LED_Bit_Clear: { - int i; - int bit=1; - struct lcd_display led_display; + case LED_Bit_Clear:{ + unsigned int i; + int bit = 1; + struct lcd_display led_display; - if(copy_from_user(&led_display, (struct lcd_display*)arg, - sizeof(struct lcd_display))) - return -EFAULT; + if (copy_from_user + (&led_display, (struct lcd_display *) arg, + sizeof(struct lcd_display))) + return -EFAULT; - for (i=0;i<(int)led_display.leds;i++) - { - bit = 2*bit; - } + for (i = 0; i < (int) led_display.leds; i++) { + bit = 2 * bit; + } - led_state = led_state & ~bit; - LEDSet(led_state); - break; - } + led_state = led_state & ~bit; + LEDSet(led_state); + break; + } - case BUTTON_Read: { - button_display.buttons = GPIRead; - if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) - return -EFAULT; - break; - } + case BUTTON_Read:{ + button_display.buttons = GPIRead; + if (copy_to_user + ((struct lcd_display *) arg, &button_display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } - case LINK_Check: { - button_display.buttons = *((volatile unsigned long *) (0xB0100060) ); - if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) - return -EFAULT; - break; - } - - case LINK_Check_2: { - int iface_num; - - /* panel-utils should pass in the desired interface status is wanted for - * in "buttons" of the structure. We will set this to non-zero if the - * link is in fact up for the requested interface. --DaveM - */ - if(copy_from_user(&button_display, (struct lcd_display *)arg, sizeof(button_display))) - return -EFAULT; - iface_num = button_display.buttons; -#if defined(CONFIG_TULIP) && 0 - if (iface_num >= 0 && - iface_num < MAX_INTERFACES && - linkcheck_callbacks[iface_num] != NULL) { + case LINK_Check:{ button_display.buttons = - linkcheck_callbacks[iface_num](linkcheck_cookies[iface_num]); - } else + *((volatile unsigned long *) (0xB0100060)); + if (copy_to_user + ((struct lcd_display *) arg, &button_display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } + + case LINK_Check_2:{ + int iface_num; + + /* panel-utils should pass in the desired interface status is wanted for + * in "buttons" of the structure. We will set this to non-zero if the + * link is in fact up for the requested interface. --DaveM + */ + if (copy_from_user + (&button_display, (struct lcd_display *) arg, + sizeof(button_display))) + return -EFAULT; + iface_num = button_display.buttons; +#if defined(CONFIG_TULIP) && 0 + if (iface_num >= 0 && + iface_num < MAX_INTERFACES && + linkcheck_callbacks[iface_num] != NULL) { + button_display.buttons = + linkcheck_callbacks[iface_num] + (linkcheck_cookies[iface_num]); + } else #endif - button_display.buttons = 0; + button_display.buttons = 0; - if(__copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) - return -EFAULT; - break; - } + if (__copy_to_user + ((struct lcd_display *) arg, &button_display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } // Erase the flash - case FLASH_Erase: { + case FLASH_Erase:{ + + int ctr = 0; - int ctr=0; + if ( !capable(CAP_SYS_ADMIN) ) return -EPERM; - // Chip Erase Sequence - WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); - WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); - WRITE_FLASH( kFlash_Addr1, kFlash_Erase3 ); - WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); - WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); - WRITE_FLASH( kFlash_Addr1, kFlash_Erase6 ); + pr_info(LCD "Erasing Flash\n"); + + // Chip Erase Sequence + WRITE_FLASH(kFlash_Addr1, kFlash_Data1); + WRITE_FLASH(kFlash_Addr2, kFlash_Data2); + WRITE_FLASH(kFlash_Addr1, kFlash_Erase3); + WRITE_FLASH(kFlash_Addr1, kFlash_Data1); + WRITE_FLASH(kFlash_Addr2, kFlash_Data2); + WRITE_FLASH(kFlash_Addr1, kFlash_Erase6); + + while ((!dqpoll(0x00000000, 0xFF)) + && (!timeout(0x00000000))) { + ctr++; + } - printk( "Erasing Flash.\n"); + if (READ_FLASH(0x07FFF0) == 0xFF) { + pr_info(LCD "Erase Successful\n"); + } else if (timeout) { + pr_info(LCD "Erase Timed Out\n"); + } - while ( (!dqpoll(0x00000000,0xFF)) && (!timeout(0x00000000)) ) { - ctr++; + break; } - printk("\n"); - printk("\n"); - printk("\n"); +// burn the flash - if (READ_FLASH(0x07FFF0)==0xFF) { printk("Erase Successful\r\n"); } - else if (timeout) { printk("Erase Timed Out\r\n"); } + case FLASH_Burn:{ - break; - } + volatile unsigned long burn_addr; + unsigned long flags; + unsigned int i, index; + unsigned char *rom; -// burn the flash - - case FLASH_Burn: { - - volatile unsigned long burn_addr; - unsigned long flags; - int i; - unsigned char *rom; - - - struct lcd_display display; - - if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) - return -EFAULT; - rom = (unsigned char *) kmalloc((128),GFP_ATOMIC); - if ( rom == NULL ) { - printk ("broken\n"); - return 1; - } - - printk("Churning and Burning -"); - save_flags(flags); - for (i=0; iRomImage[0]); + } + kfree(rom); - if(!access_ok(VERIFY_WRITE, user_bytes, FLASH_SIZE)) - return -EFAULT; + pr_info(LCD "Flash successfully burned\n"); - printk("Reading Flash"); - for (i=0; iRomImage[0]); + if (!access_ok + (VERIFY_WRITE, user_bytes, FLASH_SIZE)) + return -EFAULT; + pr_info(LCD "Reading Flash"); + for (i = 0; i < FLASH_SIZE; i++) { + unsigned char tmp_byte; + read_addr = kFlashBase + i; + tmp_byte = + *((volatile unsigned char *) + read_addr); + if (__put_user(tmp_byte, &user_bytes[i])) + return -EFAULT; + } + + + break; + } default: - return 0; - break; + return -EINVAL; } @@ -517,7 +565,8 @@ static inline int button_pressed(void) { unsigned long buttons = GPIRead; - if ( (buttons == BUTTON_Next) || (buttons == BUTTON_Next_B) || (buttons == BUTTON_Reset_B) ) + if ((buttons == BUTTON_Next) || (buttons == BUTTON_Next_B) + || (buttons == BUTTON_Reset_B)) return buttons; return 0; } @@ -526,22 +575,22 @@ static inline int button_pressed(void) static int lcd_waiters = 0; -static long lcd_read(struct inode *inode, struct file *file, char *buf, unsigned long count) +static long lcd_read(struct inode *inode, struct file *file, char *buf, + unsigned long count) { long buttons_now; - if(lcd_waiters > 0) + if (lcd_waiters > 0) return -EINVAL; lcd_waiters++; - while(((buttons_now = (long)button_pressed()) == 0) && - !(signal_pending(current))) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2 * HZ); + while (((buttons_now = (long) button_pressed()) == 0) && + !(signal_pending(current))) { + msleep_interruptible(2000); } lcd_waiters--; - if(signal_pending(current)) + if (signal_pending(current)) return -ERESTARTSYS; return buttons_now; } @@ -551,23 +600,22 @@ static long lcd_read(struct inode *inode, struct file *file, char *buf, unsigned */ static struct file_operations lcd_fops = { - .read = lcd_read, - .ioctl = lcd_ioctl, - .open = lcd_open, + .read = lcd_read, + .ioctl = lcd_ioctl, + .open = lcd_open, }; -static struct miscdevice lcd_dev= -{ - LCD_MINOR, +static struct miscdevice lcd_dev = { + MISC_DYNAMIC_MINOR, "lcd", &lcd_fops }; -int lcd_init(void) +static int lcd_init(void) { -unsigned long data; + unsigned long data; - printk("%s\n", LCD_DRIVER); + pr_info("%s\n", LCD_DRIVER); misc_register(&lcd_dev); /* Check region? Naaah! Just snarf it up. */ @@ -575,19 +623,22 @@ unsigned long data; udelay(150); data = LCDReadData; - if ( (data & 0x000000FF) == (0x00) ) { + if ((data & 0x000000FF) == (0x00)) { lcd_present = 0; - printk("LCD Not Present\n"); - } - else { + pr_info(LCD "LCD Not Present\n"); + } else { lcd_present = 1; - WRITE_GAL( kGal_DevBank2PReg, kGal_DevBank2Cfg ); - WRITE_GAL( kGal_DevBank3PReg, kGal_DevBank3Cfg ); - } + WRITE_GAL(kGal_DevBank2PReg, kGal_DevBank2Cfg); + WRITE_GAL(kGal_DevBank3PReg, kGal_DevBank3Cfg); + } return 0; } +static void __exit lcd_exit(void) +{ + misc_deregister(&lcd_dev); +} // // Function: dqpoll @@ -600,17 +651,15 @@ unsigned long data; // // -int dqpoll( volatile unsigned long address, volatile unsigned char data ) { - -volatile unsigned char dq7; - -dq7 = data & 0x80; +static int dqpoll(volatile unsigned long address, volatile unsigned char data) +{ + volatile unsigned char dq7; -return ( (READ_FLASH(address) & 0x80) == dq7 ); + dq7 = data & 0x80; + return ((READ_FLASH(address) & 0x80) == dq7); } - // // Function: timeout // @@ -622,12 +671,13 @@ return ( (READ_FLASH(address) & 0x80) == dq7 ); // // Out: 0 = not timed out, 1 = timed out -int timeout( volatile unsigned long address ) { - - -return ( (READ_FLASH(address) & 0x20) == 0x20 ); - +static int timeout(volatile unsigned long address) +{ + return (READ_FLASH(address) & 0x20) == 0x20; } +module_init(lcd_init); +module_exit(lcd_exit); - +MODULE_AUTHOR("Andrew Bose"); +MODULE_LICENSE("GPL");