--- w100fb.c.org	2003-08-15 19:13:28.000000000 +0900
+++ w100fb.c	2003-08-27 21:12:10.000000000 +0900
@@ -54,6 +54,9 @@
 #include <video/fbcon-mfb.h>
 #include <video/fbcon.h>
 
+#include <linux/proc_fs.h>
+#include <asm/proc/pgtable.h>
+
 #include "w100fb.h"
 #include <linux/pm.h>
 
@@ -74,6 +77,7 @@
 static void w100_resume(void);
 static void w100_suspend(u32 mode);
 static void w100_init_qvga_rotation(u16 deg);
+static void w100_init_vga_rotation(u16 deg);
 static void w100_soft_reset(void);
 static void w100_clear_screen(u32 mode,void *fbuf);
 static void w100_vsync(void);
@@ -106,7 +110,7 @@
 #define REMAPPED_CFG_LEN  0x10
 #define REMAPPED_MMR_LEN  0x2000
 #define W100_PHYS_ADR_LEN 0x1000000
-#define MAX_XRES          480
+#define MAX_XRES          640
 #define MAX_YRES          640
 #define BITS_PER_PIXEL    16
 
@@ -177,6 +181,8 @@
 #define LCD_MODE_480    0
 #define LCD_MODE_320    1
 #define LCD_MODE_240    2
+#define LCD_MODE_640    3
+
 #define LCD_MODE_UNKOWN (-1)
 
 int w100fb_lcdMode = LCD_MODE_UNKOWN; //default UNKOWN
@@ -245,6 +251,50 @@
 static void w100_PwmSetup(void);
 static void w100_InitExtMem(u32 mode);
 
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_w100;
+
+static ssize_t w100_read_params(struct file *file, char *buf,
+								   size_t nbytes, loff_t *ppos)
+{
+	char outputbuf[15];
+	int count;
+	if (*ppos>0) /* Assume reading completed in previous read*/
+		return 0;
+	count = sprintf(outputbuf, "aaaaaaaa\n");
+	*ppos += count;
+	if (count>nbytes)	/* Assume output can be read at one time */
+		return -EINVAL;
+	if (copy_to_user(buf, outputbuf, count))
+		return -EFAULT;
+	return count;
+}
+
+static ssize_t w100_write_params(struct file *file, const char *buf,
+									size_t nbytes, loff_t *ppos)
+{
+	int	len;
+	unsigned long		param;
+	unsigned long		regs;
+
+	sscanf(buf,"%x %x",&regs,&param);
+	printk("regs 0x%08X :params  0x%08X\n",regs,param);
+
+	if (regs <= 0x2000){
+		writel(param, remapped_regs+regs);
+	}
+
+	len=strlen(buf);
+
+	return len;
+}
+
+static struct file_operations proc_params_operations = {
+	read:	w100_read_params,
+	write:	w100_write_params,
+};
+#endif
+
 /* ------------------- chipset specific functions -------------------------- */
 
 //
@@ -385,7 +435,7 @@
 
   if (w100fb_lcdMode == LCD_MODE_UNKOWN){
       w100_InitExtMem(LCD_SHARP_VGA);
-  } else if(w100fb_lcdMode == LCD_MODE_480) {
+  } else if( (w100fb_lcdMode == LCD_MODE_480) || (w100fb_lcdMode == LCD_MODE_640) ) {
       w100_InitExtMem(LCD_SHARP_VGA);
   } else {
       w100_InitExtMem(LCD_SHARP_QVGA);
@@ -400,6 +450,32 @@
   writel((u32)(wrap_top_dir.val), remapped_regs+mmWRAP_TOP_DIR);
 
   writel((u32)0x2440, remapped_regs+mmRBBM_CNTL);
+
+#ifdef CONFIG_PROC_FS
+	{
+		struct proc_dir_entry *entry;
+
+		proc_w100 = proc_mkdir("driver/w100", NULL);
+		if (proc_w100 == NULL) {
+			unregister_chrdev(228, "w100");
+			printk(KERN_ERR "w100: can't create /proc/driver/w100\n");
+			return -ENOMEM;
+		}
+		entry = create_proc_entry("w100",
+								  S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
+								  proc_w100);
+		if (entry) {
+			entry->proc_fops = &proc_params_operations;
+		} else {
+			remove_proc_entry("driver/w100", &proc_root);
+			proc_w100 = 0;
+			unregister_chrdev(228, "w100");
+			printk(KERN_ERR "w100: can't create /proc/driver/w100/\n");
+			return -ENOMEM;
+		}
+	}
+#endif
+
 }
 
 //
@@ -454,7 +530,7 @@
 
   fix->smem_start = W100_FB_BASE;
 
-  if(w100fb_lcdMode == LCD_MODE_UNKOWN || w100fb_lcdMode == LCD_MODE_480){
+  if(w100fb_lcdMode == LCD_MODE_UNKOWN || w100fb_lcdMode == LCD_MODE_480 ){
 
       fix->line_length = (480 * BITS_PER_PIXEL) / 8;
       fix->smem_len = 0x200000;
@@ -469,6 +545,11 @@
       fix->line_length = (240 * BITS_PER_PIXEL) / 8;
       fix->smem_len = 0x60000;
 
+  } else if(w100fb_lcdMode == LCD_MODE_640){
+
+      fix->line_length = (640 * BITS_PER_PIXEL) / 8;
+      fix->smem_len = 0x200000;
+
   }
 
   fix->mmio_start = W100_REG_BASE;
@@ -494,13 +575,14 @@
     BUG();
 
   if((par->xres == 480 && par->yres == 640)||
+     (par->xres == 640 && par->yres == 480)||
      (par->xres == 320 && par->yres == 240)||
      (par->xres == 240 && par->yres == 320)){
       par->xres = var->xres;
       par->yres = var->yres;
   }else{
-      par->xres = MAX_XRES;
-      par->yres = MAX_YRES;
+      par->xres = 480;
+      par->yres = 640;
   }
 
   par->xres_virtual =
@@ -547,13 +629,14 @@
 
   // set up screen coordinates
   if((par->xres == 480 && par->yres == 640)||
+     (par->xres == 640 && par->yres == 480)||
      (par->xres == 320 && par->yres == 240)||
      (par->xres == 240 && par->yres == 320)){
       var->xres = par->xres;
       var->yres = par->yres;
   }else{
-      var->xres = MAX_XRES;
-      var->yres = MAX_YRES;
+      var->xres = 480;
+      var->yres = 640;
   }
 
   var->xres_virtual = var->xres;
@@ -873,6 +956,70 @@
 
 	  w100fb_lcdMode = LCD_MODE_240;
 
+      }else if(current_par.xres == 640 && current_par.yres == 480){
+
+	  printk("change resolution 480x640 => 640x480\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  w100_init_vga_rotation( (u16)270 );
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_640;
+
+      }
+      break;
+  case LCD_MODE_640:
+      if(current_par.xres == 320 && current_par.yres == 240){
+
+	  printk("change resolution 640x480 => 320x240\n");
+
+	  w100_PwmSetup();
+	  w100_vsync();
+	  w100_suspend(W100_SUSPEND_EXTMEM);
+	  w100_init_sharp_lcd(LCD_SHARP_QVGA);
+	  w100_init_qvga_rotation( (u16)270 );
+	  w100_InitExtMem(LCD_SHARP_QVGA);
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  lcdtg_lcd_change(LCD_SHARP_QVGA);
+
+	  w100fb_lcdMode = LCD_MODE_320;
+
+      }else if(current_par.xres == 240 && current_par.yres == 320){
+
+	  printk("change resolution 640x480 => 240x320\n");
+
+	  w100_PwmSetup();
+	  w100_vsync();
+	  w100_suspend(W100_SUSPEND_EXTMEM);
+	  w100_init_sharp_lcd(LCD_SHARP_QVGA);
+	  w100_init_qvga_rotation( (u16)0 );
+	  w100_InitExtMem(LCD_SHARP_QVGA);
+  	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  lcdtg_lcd_change(LCD_SHARP_QVGA);
+
+	  w100fb_lcdMode = LCD_MODE_240;
+
+      }else if(current_par.xres == 480 && current_par.yres == 640){
+
+	  printk("change resolution 640x480 => 480x640\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_480;
+
       }
       break;
   case LCD_MODE_240:
@@ -891,6 +1038,22 @@
 
 	  w100fb_lcdMode = LCD_MODE_480;
 
+      }else if(current_par.xres == 640 && current_par.yres == 480){
+
+	  printk("change resolution 240x320 => 640x480\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  w100_init_vga_rotation( (u16)270 );
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_640;
+
       }else if(current_par.xres == 320 && current_par.yres == 240){
 
 	  printk("change resolution 240x320 => 320x240\n");
@@ -917,6 +1080,22 @@
 
 	  w100fb_lcdMode = LCD_MODE_480;
 
+      }else if(current_par.xres == 640 && current_par.yres == 480){
+
+	  printk("change resolution 240x320 => 640x480\n");
+
+	  w100_PwmSetup();
+	  w100_clear_screen(LCD_SHARP_QVGA,NULL);
+	  writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
+	  w100_InitExtMem(LCD_SHARP_VGA);
+	  w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
+	  w100_vsync();
+	  w100_init_sharp_lcd(LCD_SHARP_VGA);
+	  w100_init_vga_rotation( (u16)270 );
+	  lcdtg_lcd_change(LCD_SHARP_VGA);
+
+	  w100fb_lcdMode = LCD_MODE_640;
+
       }else if(current_par.xres == 240 && current_par.yres == 320){
 
 	  printk("change resolution 320x240 => 240x320\n");
@@ -1004,6 +1183,7 @@
 
   switch(w100fb_lcdMode){
   case LCD_MODE_480:
+  case LCD_MODE_640:
       if(isInitTG != 0)
 	  lcdtg_hw_init(LCD_SHARP_VGA);
       break;
@@ -2840,6 +3020,31 @@
     writel((u32)(disp_db_buf_wr_cntl.val), remapped_regs+mmDISP_DB_BUF_CNTL);
 } // w100_init_sharp_lcd
 
+static void w100_init_vga_rotation(u16 deg)
+{
+    // for resolution change and rotation
+    // GRAPHIC_CTRL
+    // GRAPHIC_OFFSET
+    // GRAPHIC_PITCH
+
+    switch(deg){
+    case 0:
+	writel(0x00DE1D66, remapped_regs+mmGRAPHIC_CTRL);
+	writel(0x00800000, remapped_regs+mmGRAPHIC_OFFSET);
+	writel(0x000003c0, remapped_regs+mmGRAPHIC_PITCH);
+	break;
+    case 270:
+	writel(0x00D63c16, remapped_regs+mmGRAPHIC_CTRL);
+	//writel(0x0080027e, remapped_regs+mmGRAPHIC_OFFSET);
+	writel(0x00800000, remapped_regs+mmGRAPHIC_OFFSET);
+	writel(0x00000500, remapped_regs+mmGRAPHIC_PITCH);
+	break;
+    default:
+	// not-support
+	break;
+    }
+}
+
 static void w100_init_qvga_rotation(u16 deg)
 {
     // for resolution change and rotation
@@ -2934,6 +3139,9 @@
 
 	if (w100fb_lcdMode == LCD_MODE_480) {
 		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		if (w100fb_lcdMode == LCD_MODE_640) {
+			w100_init_vga_rotation( (u16)270 );
+		}
 	}
 	else {
 		w100_init_sharp_lcd(LCD_SHARP_QVGA);
@@ -3273,7 +3481,7 @@
 
 static void lcdtg_resume()
 {
-  if (w100fb_lcdMode == LCD_MODE_480) {
+  if (w100fb_lcdMode == LCD_MODE_480 || w100fb_lcdMode == LCD_MODE_640) {
 	  lcdtg_hw_init(LCD_SHARP_VGA);
   }
   else {
