[PATCH 2.6.19-rc1 update 2] drivers: add LCD support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Andrew, here it is the patch for converting the cfag12864b driver
to a framebuffer driver as Pavel requested and as I promised :)

Pavel, yep, now I can login in my tiny 128x64 LCD.
It is pretty amazing to run vi on it... ;)

Tested and working fine.
---
miguelojeda-2.6.19-rc1-add-LCD-support-update2.patch

Converts cfag12864b driver into a framebuffer one.


Brief
-----

     - Removes the auxlcdclass.
     - Removes a lot of code.
     - Adds refreshing related code.
     - Adds the cfag12864bfb module.
     - Updates documentation, .h, ...
     - Many minor changes


Patched files Index
-------------------

 CREDITS                              |    4
 Documentation/ABI/testing/cfag12864b |   56 ---
 Documentation/auxdisplay/auxdisplay  |   37 --
 Documentation/auxdisplay/cfag12864b  |  298 +-------------------
 MAINTAINERS                          |    6
 drivers/auxdisplay/Kconfig           |   48 ++-
 drivers/auxdisplay/Makefile          |    3
 drivers/auxdisplay/auxlcdclass.c     |   75 -----
 drivers/auxdisplay/cfag12864b.c      |  356 +++++--------------------
 drivers/auxdisplay/cfag12864bfb.c    |  165 +++++++++++
 drivers/auxdisplay/fbcfag12864b.c    |  226 ---------------
 drivers/auxdisplay/ks0108.c          |    2
 include/linux/auxlcdclass.h          |   33 --
 include/linux/cfag12864b.h           |   15 -
 14 files changed, 296 insertions(+), 1028 deletions(-)


miguelojeda-2.6.19-rc1-add-LCD-support-update2.patch
Signed-off-by: Miguel Ojeda Sandonis <[email protected]>
---
diff -uprN -X dontdiff linux-2.6.19-rc1-x/CREDITS linux-2.6.19-rc1/CREDITS
--- linux-2.6.19-rc1-x/CREDITS	2006-10-10 12:57:41.000000000 +0000
+++ linux-2.6.19-rc1/CREDITS	2006-10-12 12:26:23.000000000 +0000
@@ -2564,7 +2564,9 @@ S: Australia
 
 N: Miguel Ojeda Sandonis
 E: [email protected]
-D: Author: LCD and LCD Controller drivers (ks0108, cfag12864b)
+D: Author: Auxiliary LCD Controller driver (ks0108)
+D: Author: Auxiliary LCD driver (cfag12864b)
+D: Author: Auxiliary LCD framebuffer driver (cfag12864bfb)
 D: Maintainer: Auxiliary display drivers tree (drivers/auxdisplay/*)
 S: C/ Mieses 20, 9-B
 S: Valladolid 47009
diff -uprN -X dontdiff linux-2.6.19-rc1-x/Documentation/ABI/testing/cfag12864b linux-2.6.19-rc1/Documentation/ABI/testing/cfag12864b
--- linux-2.6.19-rc1-x/Documentation/ABI/testing/cfag12864b	2006-10-10 12:57:41.000000000 +0000
+++ linux-2.6.19-rc1/Documentation/ABI/testing/cfag12864b	1970-01-01 00:00:00.000000000 +0000
@@ -1,56 +0,0 @@
-What:		drivers/auxdisplay/cfag12864b driver
-Date:		2006-10-06
-KernelVersion:	2.6.18
-Contact:	Miguel Ojeda Sandonis <[email protected]>
-Description:	
-		The cfag12864b LCD driver defines one way to communicate
-		with the lcd:
-
-		1.    Use seek and write syscalls. Bytes written appear on
-		   the screen without any formatting on the position pointed
-		   by the file offset.
-
-		      It is hardware dependent. It should be used to modify
-		   specific display's pixels to achieve higher refreshing
-		   rates.
-
-		      This method allows you to change each byte of the device,
-		   so you can achieve a higher update rate updating only the
-		   pixels you are going to change.
-
-		      The device size is 1024 == CFAG12864B_SIZE.
-
-		      You can write and seek the device. The first 512 bytes
-		   write to the first k0108 controller (left display half) and
-		   the last 512 bytes write to the second ks0108 controller
-		   (right display half).
-
-		      Each controller is divided into 8 pages.
-		      Each page has 64 addresses (bytes).
-
-		                     Controller 0 Controller 1
-		                     _________________________
-		         Page 0 --> |____________|____________|
-		         Page 1 --> |____________|____________|
-		         Page 2 --> |____________|____________|
-		         Page 3 --> |____________|____________|
-		         Page 4 --> |____________|____________|
-		         Page 5 --> |____________|____________|
-		         Page 6 --> |____________|____________|
-		         Page 7 --> |____________|____________|
-		                     <--- 64 --->
-		                       Addresses
-
-		      The beggining of the file is at controller 0, page 0,
-		   address 0.
-
-		      When you reach the position 64, you are writing to the
-		   same controller, next page, address 0.
-
-		      After 512 bytes written, you are writing to the second
-		   controller, starting at page 0 and address 0 again.
-
-		      For more information and examples, see
-		   Documentation/auxdisplay/cfag12864b
-
-Users:		
diff -uprN -X dontdiff linux-2.6.19-rc1-x/Documentation/auxdisplay/auxdisplay linux-2.6.19-rc1/Documentation/auxdisplay/auxdisplay
--- linux-2.6.19-rc1-x/Documentation/auxdisplay/auxdisplay	2006-10-10 12:57:42.000000000 +0000
+++ linux-2.6.19-rc1/Documentation/auxdisplay/auxdisplay	1970-01-01 00:00:00.000000000 +0000
@@ -1,37 +0,0 @@
-	=======================================
-	Auxiliary Display Drivers Documentation
-	=======================================
-
-License:		GPLv2
-Author & Maintainer:	Miguel Ojeda Sandonis <[email protected]>
-Date:			2006-10-04
-
---------
-0. INDEX
---------
-
-	1. NEW DISPLAY DRIVERS
-	2. GENERAL TIPS
-
-
-
-----------------------
-1. NEW DISPLAY DRIVERS
-----------------------
-
-Feel free to send me new display drivers. I will try to do my best.
-
-If you don't get any answer, send your patch directly to the linux-kernel ml.
-
-
-
----------------
-2. GENERAL TIPS
----------------
-
-- Divide your driver into the controller driver, like ks0108,
-  and the specific display series driver, like cfag12864b.
-
-- Claim for your IO ports in the controller driver.
-
-EOF
diff -uprN -X dontdiff linux-2.6.19-rc1-x/Documentation/auxdisplay/cfag12864b linux-2.6.19-rc1/Documentation/auxdisplay/cfag12864b
--- linux-2.6.19-rc1-x/Documentation/auxdisplay/cfag12864b	2006-10-10 12:57:42.000000000 +0000
+++ linux-2.6.19-rc1/Documentation/auxdisplay/cfag12864b	2006-10-12 12:34:31.000000000 +0000
@@ -4,7 +4,7 @@
 
 License:		GPLv2
 Author & Maintainer:	Miguel Ojeda Sandonis <[email protected]>
-Date:			2006-10-06
+Date:			2006-10-11
 
 
 
@@ -16,10 +16,6 @@ Date:			2006-10-06
 	2. DEVICE INFORMATION
 	3. WIRING
 	4. USER-SPACE PROGRAMMING
-		4.1. Direct writing
-	5. USEFUL FILES
-		5.1. cfag12864b.h
-		5.2. bmpwriter.h
 
 
 ---------------------
@@ -67,103 +63,27 @@ You can get help at Crystalfontz and LCD
 4. USERSPACE PROGRAMMING
 ------------------------
 
-This interface is described briefly at Documentation/ABI/testing/cfag12864b
+The cfag12864bfb describes a framebuffer driver (/dev/fbX).
 
-Include a copy of the provided header:
-
-	#include "cfag12864b.h"
-
-Open the device for writing, /dev/cfag12864b0:
-
-	FILE * fdisplay = fopen("/dev/cfag12864b0","wb");
-
-For writing to the display, you have the following options:
-		
-
-4.1. Direct writing
--------------------
-
-This method allows you to change each byte of the device,
-so you can achieve a higher update rate updating only the pixels
-you are going to change.
-
-The device size is 1024 == CFAG12864B_SIZE.
-
-You can write and seek the device. The first 512 bytes write to
-the first k0108 controller (left display half) and the last 512 bytes
-write to the second ks0108 controller (right display half).
-
-Each controller is divided into 8 pages. Each page has 64 bytes.
-
-            Controller 0 Controller 1
-            _________________________
-Page 0 --> |____________|____________|
-Page 1 --> |____________|____________|
-Page 2 --> |____________|____________|
-Page 3 --> |____________|____________|
-Page 4 --> |____________|____________|
-Page 5 --> |____________|____________|
-Page 6 --> |____________|____________|
-Page 7 --> |____________|____________|
-            <--- 64 --->
-
-The beggining of the file is at controller 0, page 0, address 0.
-
-When you reach the position 64, you are writing to the same controller,
-next page, address 0.
-
-After 512 bytes written, you are writing to the second controller, starting
-at page 0 and address 0 again.
-
-You will understand how the device work executing some commands:
-
-	Write some stuff:
-		# echo -n A > /dev/cfag12864b0
-		# echo -n a > /dev/cfag12864b0
-		# echo AAAAAA > /dev/cfag12864b0
-		# echo 000000 > /dev/cfag12864b0
-		# echo Hello world! > /dev/cfag12864b0
-		# echo Hello world! Hello world! > /dev/cfag12864b0
-
-	Clear the display:
-		# cat /dev/zero > /dev/cfag12864b0
-
-	Fill with random values:
-		# cat /dev/random > /dev/cfag12864b0
-	...
-
-After you understand it, code your functions to change specific bytes.
-
-Use functions like fwrite() and fseek() to control the device, like:
-
-	fseek(fdisplay, ipage * CFAG12864B_HEIGHT, SEEK_SET);
-	fseek(fdisplay, icontroller * CFAG12864B_SIZE / 2, SEEK_SET);
-
-	fwrite(bufpage, 1, CFAG12864B_HEIGHT, fdisplay);
-	fwrite(bufcontroller, 1, CFAG12864B_SIZE / 2, fdisplay);
-	fwrite(bufdisplay, 1, CFAG12864B_SIZE, fdisplay);
-
-	...
-
-
----------------
-5. USEFUL FILES
----------------
-
-
-5.1 cfag12864b.h
-----------------
+It has a size of 128 * 64 = 8192 bytes. Each one represents one pixel.
+If the value is 0, the pixel will turn off.
+If the greater than 0, the pixel will turn on.
+
+You may are asking why it isn't 1024 bytes long, with 1 bit per pixel.
+Well, the refreshing is made by the CPU, so it has to be as fast as
+possible. If we use 1024 bytes only, the conversion from the fb format
+to the cfag12864b hardware dependent format would use far more
+integer operations and bit operations as well.
 
 You can use a copy of this header in your userspace programs.
 
----
+---8<---
 /*
  *    Filename: cfag12864b.h
- *     Version: 0.1.0
  * Description: cfag12864b LCD Display Driver Header for user-space apps
  *
  *      Author: Miguel Ojeda Sandonis <[email protected]>
- *        Date: 2006-09-30
+ *        Date: 2006-10-11
  */
 
 #ifndef _CFAG12864B_H_
@@ -171,198 +91,10 @@ You can use a copy of this header in you
 
 #define CFAG12864B_WIDTH	(128)
 #define CFAG12864B_HEIGHT	(64)
-#define CFAG12864B_FORMATSIZE	((CFAG12864B_WIDTH)*(CFAG12864B_HEIGHT))
-#define CFAG12864B_SIZE		(1024)
+#define CFAG12864B_SIZE		((CFAG12864B_WIDTH)*(CFAG12864B_HEIGHT))
 
 #endif // _CFAG12864B_H_
----
-
-
-
-5.2 Example BMP writer
-----------------------
-
-You can take ideas from this code and start programming. I think it is useful
-for understanding how the driver can be used. It just works, don't expect
-good BMP-related code. I chose such bitmap format because it is simple.
-
-The program reads a .bmp 128x64 2-colors file, converts it to a
-boolean [128*64] buffer and then uses ioctl to display it on the screen.
-
----
-/*
- *    Filename: bmpwriter.h
- *     Version: 0.1.0
- * Description: BMP Writer sample app for cfag12864b LCD driver
- *
- *      Author: Miguel Ojeda Sandonis <[email protected]>
- *        Date: 2006-09-30
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "cfag12864b.h"
-
-#define BMP_SIZE 1024
-
-union dword
-{
-	unsigned int u32;
-	unsigned char u8[4];
-};
-
-#define Bit(n)   ((unsigned char)(1<<(n)))
-
-void BMP2Format(unsigned char * src, unsigned char * dest)
-{
-	const unsigned int width = CFAG12864B_WIDTH;
-	const unsigned int height = CFAG12864B_HEIGHT;
-	const unsigned int bits = 8;
-
-	unsigned int  y,x,bit;
-
-	for(y=0; y<height; ++y)
-	for(x=0; x<width/bits; ++x)
-	for(bit=0; bit<bits; ++bit)
-		dest[x * bits + bit + (height - y - 1) * width] =
-			src[y * width / bits + x] & Bit(bits - bit - 1) ? 0 : 1;
-}
-
-void Format2cfag12864b(unsigned char * src, unsigned char * dest)
-{
-	unsigned short controller,page,address,bit;
-
-	for(controller=0; controller<2; ++controller)
-	for(page=0; page<8; ++page)
-	for(address=0; address<64; ++address) {
-		dest[(controller*8+page)*64+address]=0;
-		for(bit=0; bit<8; ++bit)
-			if(src[controller*64+address+(page*8+bit)*CFAG12864B_WIDTH])
-				dest[(controller*8+page)*64+address]|=Bit(bit);
-	}
-}
-
-int main(int argc, char * argv[])
-{
-	const unsigned int Width = CFAG12864B_WIDTH;
-	const unsigned int Height = CFAG12864B_HEIGHT;
-	const unsigned int Size = CFAG12864B_SIZE;
-	const unsigned int BPP = 1;
-	const unsigned int HeaderSize = 0x3E;
-	const unsigned int BMPSize = BMP_SIZE;
-
-	unsigned char c;
-	unsigned int i,j;
-	union dword n;
-
-	unsigned char Buffer_BMP[BMP_SIZE];
-	unsigned char Buffer_Matrix[CFAG12864B_FORMATSIZE];
-	unsigned char Buffer_cfag12864b[CFAG12864B_SIZE];
-
-	FILE * fdisplay;
-	FILE * fbmp;
-
-	// Check args
-	if(argc!=3) {
-		printf("%s: Bad number of arguments. Expected 3\n",
-			argv[0]);
-		return -1;
-	}
-	
-	// Open file
-	fbmp = fopen(argv[2],"rb");
-	if(fbmp==NULL) {
-		printf("%s: Can't open %s\n",argv[0], argv[2]);
-		return -2;
-	}
-
-	// Check file size
-	fseek(fbmp,0,SEEK_END);
-	i=ftell(fbmp);
-	if(i!=HeaderSize+Size) {
-		printf("%s: Bad file size. %i instead of %i\n",
-			argv[0], i, HeaderSize+Size);
-		fclose(fbmp);
-		return -3;
-	}
-
-	// Check both magic BMP bytes
-	fseek(fbmp,0,SEEK_SET);
-	c = fgetc(fbmp);
-	if(c!='B') {
-		printf("%s: Bad first magic byte. '%c' instead of 'B'\n",
-			argv[0], c);
-		fclose(fbmp);
-		return -4;
-	}
-	c = fgetc(fbmp);
-	if(c!='M') {
-		printf("%s: Bad second magic byte. '%c' instead of 'M'\n",
-			argv[0], c);
-		fclose(fbmp);
-		return -5;
-	}
-
-	// Check this is a 128x64 1-bpp BMP file
-	fseek(fbmp,0x12,SEEK_SET);
-	for(i=0; i<4; ++i)
-		n.u8[i] = fgetc(fbmp);
-	if(n.u32!=Width) {
-		printf("%s: Bad width. %i instead of %i\n",
-			argv[0], n.u32, Width);
-		fclose(fbmp);
-		return -6;
-	}
-	for(i=0; i<4; ++i)
-		n.u8[i] = fgetc(fbmp);
-	if(n.u32!=Height) {
-		printf("%s: Bad width. %i instead of %i\n",
-			argv[0], n.u32, Height);
-		fclose(fbmp);
-		return -7;
-	}
-	fseek(fbmp,0x1C,SEEK_SET);
-	c = fgetc(fbmp);
-	if(c!=BPP) {
-		printf("%s: Bad bpp. %i instead of %i\n",
-			argv[0], c, BPP);
-		fclose(fbmp);
-		return -8;
-	}
-
-	// Get bitmap data
-	fseek(fbmp,0x3E,SEEK_SET);
-	fread(Buffer_BMP,1,BMPSize,fbmp);
-	fclose(fbmp);
-
-	// Transform BMP data to 2D matrix
-	BMP2Format(Buffer_BMP,Buffer_Matrix);
-
-	// Transform 2D matrix to cfag12864b RAW format
-	Format2cfag12864b(Buffer_cfag12864b);
-
-	// Open file
-	fdisplay = fopen(argv[1],"wb");
-	if(fdisplay == NULL) {
-		printf("%s: Can't open %s\n", argv[0], argv[1]);
-		return -9;
-	}
-
-	// Send RAW image
-	fwrite(Buffer_cfag12864b,1,CFAG12864B_SIZE,fdisplay);
-
-	// Close file
-	fclose(fdisplay);
-
-	return 0;
-}
----
+---8<---
 
 
 EOF
diff -uprN -X dontdiff linux-2.6.19-rc1-x/drivers/auxdisplay/auxlcdclass.c linux-2.6.19-rc1/drivers/auxdisplay/auxlcdclass.c
--- linux-2.6.19-rc1-x/drivers/auxdisplay/auxlcdclass.c	2006-10-10 12:58:44.000000000 +0000
+++ linux-2.6.19-rc1/drivers/auxdisplay/auxlcdclass.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,75 +0,0 @@
-/*
- *    Filename: auxlcdclass.c
- *     Version: 0.1.0
- * Description: Auxiliary LCD Class
- *     License: GPLv2
- *     Depends: -
- *
- *      Author: Copyright (C) Miguel Ojeda Sandonis <[email protected]>
- *        Date: 2006-10-05
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/auxlcdclass.h>
-
-#define AUXLCDCLASS_NAME "auxlcd"
-
-/*
- * Exported Display Data
- */
-
-struct class *auxlcdclass_class;
-EXPORT_SYMBOL_GPL(auxlcdclass_class);
-
-/*
- * Module Init & Exit
- */
-
-static int __init auxlcdclass_init(void)
-{
-	int ret = -EINVAL;
-
-	auxlcdclass_class = class_create(THIS_MODULE, AUXLCDCLASS_NAME);
-	if (IS_ERR(auxlcdclass_class)) {
-		printk(KERN_ERR AUXLCDCLASS_NAME ": ERROR: "
-			"can't create %s class\n", AUXLCDCLASS_NAME);
-		goto none;
-	}
-
-	return 0;
-
-none:
-	return ret;
-}
-
-static void __exit auxlcdclass_exit(void)
-{
-	class_destroy(auxlcdclass_class);
-}
-
-module_init(auxlcdclass_init);
-module_exit(auxlcdclass_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Miguel Ojeda Sandonis <[email protected]>");
-MODULE_DESCRIPTION("Auxiliary LCD Class");
-
diff -uprN -X dontdiff linux-2.6.19-rc1-x/drivers/auxdisplay/cfag12864b.c linux-2.6.19-rc1/drivers/auxdisplay/cfag12864b.c
--- linux-2.6.19-rc1-x/drivers/auxdisplay/cfag12864b.c	2006-10-10 12:58:44.000000000 +0000
+++ linux-2.6.19-rc1/drivers/auxdisplay/cfag12864b.c	2006-10-12 13:35:31.000000000 +0000
@@ -3,10 +3,10 @@
  *     Version: 0.1.0
  * Description: cfag12864b LCD driver
  *     License: GPLv2
- *     Depends: auxlcdclass ks0108
+ *     Depends: ks0108
  *
  *      Author: Copyright (C) Miguel Ojeda Sandonis <[email protected]>
- *        Date: 2006-10-06
+ *        Date: 2006-10-12
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -29,8 +29,11 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
+#include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/auxlcdclass.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+#include <linux/vmalloc.h>
 #include <linux/ks0108.h>
 #include <linux/cfag12864b.h>
 #include <asm/uaccess.h>
@@ -38,17 +41,13 @@
 #define CFAG12864B_NAME "cfag12864b"
 
 /*
- * Device
+ * Module Parameters
  */
 
-static const unsigned int cfag12864b_firstminor;
-static const unsigned int cfag12864b_ndevices = 1;
-static int cfag12864b_major;
-static int cfag12864b_minor;
-static dev_t cfag12864b_devt;
-struct cdev cfag12864b_chardevice;
-static unsigned char * cfag12864b_buffer;
-DECLARE_MUTEX(cfag12864b_mutex);
+static unsigned int cfag12864b_rate = CONFIG_CFAG12864B_RATE;
+module_param(cfag12864b_rate, uint, S_IRUGO);
+MODULE_PARM_DESC(cfag12864b_rate,
+	"Refresh rate (hertzs)");
 
 /*
  * cfag12864b Commands
@@ -69,7 +68,7 @@ DECLARE_MUTEX(cfag12864b_mutex);
  *	
  */
 
-#define bit(n)   (((unsigned char)1)<<(n))
+#define bit(n) (((unsigned char)1)<<(n))
 
 #define CFAG12864B_BIT_E	(0)
 #define CFAG12864B_BIT_CS1	(2)
@@ -112,7 +111,8 @@ static void cfag12864b_di(unsigned char 
 	cfag12864b_setbit(state, CFAG12864B_BIT_DI);
 }
 
-static void cfag12864b_setcontrollers(unsigned char first, unsigned char second)
+static void cfag12864b_setcontrollers(unsigned char first,
+	unsigned char second)
 {
 	if (first)
 		cfag12864b_cs1(0);
@@ -179,53 +179,27 @@ static void cfag12864b_nop(void)
 }
 
 /*
- * Auxiliary
+ * cfag12864b Internal Commands
  */
 
-static void normalizeoffset(unsigned int *offset)
-{
-	if (*offset >= CFAG12864B_PAGES * CFAG12864B_ADDRESSES)
-		*offset -= CFAG12864B_PAGES * CFAG12864B_ADDRESSES;
-}
-
-static unsigned char calcaddress(unsigned int offset)
-{
-	normalizeoffset(&offset);
-	return offset % CFAG12864B_ADDRESSES;
-}
-
-static unsigned char calccontroller(unsigned int offset)
-{
-	if (offset < CFAG12864B_PAGES * CFAG12864B_ADDRESSES)
-		return 0;
-	return 1;
-}
-
-static unsigned char calcpage(unsigned int offset)
-{
-	normalizeoffset(&offset);
-	return offset / CFAG12864B_ADDRESSES;
-}
-
-/*
- * cfag12864b Internal Commands (don't lock)
- */
+unsigned char *cfag12864b_buffer;
+EXPORT_SYMBOL_GPL(cfag12864b_buffer);
 
-void cfag12864b_on_nolock(void)
+static void cfag12864b_on(void)
 {
 	cfag12864b_setcontrollers(1, 1);
 	cfag12864b_displaystate(1);
 }
 
-void cfag12864b_off_nolock(void)
+static void cfag12864b_off(void)
 {
 	cfag12864b_setcontrollers(1, 1);
 	cfag12864b_displaystate(0);
 }
 
-void cfag12864b_clear_nolock(void)
+static void cfag12864b_clear(void)
 {
-	unsigned char i,j;
+	unsigned char i, j;
 
 	cfag12864b_setcontrollers(1, 1);
 	for (i = 0; i < CFAG12864B_PAGES; i++) {
@@ -236,268 +210,81 @@ void cfag12864b_clear_nolock(void)
 	}
 }
 
-void cfag12864b_write_nolock(unsigned short offset, const unsigned char *buffer,
-	unsigned short count)
-{
-	unsigned short i;
-
-	/* Invalid values: They get updated at the first cycle */
-	unsigned char controller = 0xFF;
-	unsigned char page = 0xFF;
-	unsigned char address = 0xFF;
-
-	unsigned char tmpcontroller, tmppage, tmpaddress;
-
-	if (offset > CFAG12864B_SIZE)
-		return;
-	if (count + offset > CFAG12864B_SIZE)
-		count = CFAG12864B_SIZE - offset;
-
-	for (i = 0; i < count; i++, offset++, address++) {
-		tmpcontroller = calccontroller(offset);
-		tmppage = calcpage(offset);
-		tmpaddress = calcaddress(offset);
-
-		if (controller != tmpcontroller) {
-			controller = tmpcontroller;
-			cfag12864b_controller(controller);
-			cfag12864b_nop();
-		}
-		if (page != tmppage) {
-			page = tmppage;
-			cfag12864b_page(page);
-			cfag12864b_nop();
-		}
-
-		/* Safe method, still quick */
-		cfag12864b_address(tmpaddress);
-		cfag12864b_nop();
-
-		/* Dummy */
-		cfag12864b_nop();
-
-		cfag12864b_writebyte(buffer[i]);
-	}
-}
-
-void cfag12864b_format_nolock(unsigned char *src)
-{
-	unsigned short i, j, k, n;
-
-	for (i = 0; i < CFAG12864B_CONTROLLERS; i++)
-	for (j = 0; j < CFAG12864B_PAGES; j++)
-	for (k = 0; k < CFAG12864B_ADDRESSES; k++) {
-		cfag12864b_buffer[(i * CFAG12864B_PAGES + j) * CFAG12864B_ADDRESSES + k] = 0;
-		for (n = 0; n < 8; n++)
-			if (src[i * CFAG12864B_ADDRESSES + k + (j * 8 + n) * CFAG12864B_WIDTH])
-				cfag12864b_buffer[(i * CFAG12864B_PAGES + j) * CFAG12864B_ADDRESSES + k] |= bit(n);
-	}
-
-	cfag12864b_write_nolock(0, cfag12864b_buffer, CFAG12864B_SIZE);
-}
-
-/*
- * cfag12864b Exported Commands (do lock)
- */
-
-void cfag12864b_on(void)
-{
-	if (down_interruptible(&cfag12864b_mutex))
-		return;
-
-	cfag12864b_on_nolock();
-
-	up(&cfag12864b_mutex);
-}
-
-void cfag12864b_off(void)
-{
-	if (down_interruptible(&cfag12864b_mutex))
-		return;
-
-	cfag12864b_off_nolock();
-
-	up (&cfag12864b_mutex);
-}
-
-void cfag12864b_clear(void)
-{
-	if (down_interruptible(&cfag12864b_mutex))
-		return;
-
-	cfag12864b_clear_nolock();
-
-	up(&cfag12864b_mutex);
-}
-
-void cfag12864b_write(unsigned short offset, const unsigned char *buffer,
-	unsigned short count)
-{
-	if (down_interruptible(&cfag12864b_mutex))
-		return;
-
-	cfag12864b_write_nolock(offset, buffer, count);
-
-	up(&cfag12864b_mutex);
-}
-
-void cfag12864b_format(unsigned char *src)
-{
-	if (down_interruptible(&cfag12864b_mutex))
-		return;
-
-	cfag12864b_format_nolock(src);
-
-	up(&cfag12864b_mutex);
-}
-
-EXPORT_SYMBOL_GPL(cfag12864b_on);
-EXPORT_SYMBOL_GPL(cfag12864b_off);
-EXPORT_SYMBOL_GPL(cfag12864b_clear);
-EXPORT_SYMBOL_GPL(cfag12864b_write);
-EXPORT_SYMBOL_GPL(cfag12864b_format);
-
 /*
- * cfag12864b_fops (do lock)
+ * Update work
  */
 
-static loff_t cfag12864b_fopseek(struct file *filp, loff_t offset, int whence)
-{
-	loff_t ret = -EINVAL;
-
-	if (down_interruptible(&cfag12864b_mutex))
-		return -ERESTARTSYS;
+static void cfag12864b_update(void *arg);
+static struct workqueue_struct *cfag12864b_workqueue;
+DECLARE_WORK(cfag12864b_work, cfag12864b_update, NULL);
 
-	switch (whence) {
-	case SEEK_SET:
-		ret = offset;
-		break;
-	case SEEK_CUR:
-		ret = filp->f_pos + offset;
-		break;
-	case SEEK_END:
-		ret = CFAG12864B_SIZE + offset;
-		break;
-	}
+static unsigned char cfag12864b_updating;
 
-	if (ret < 0) {
-		ret = -EINVAL;
-		goto none;
-	}
-
-	filp->f_pos = ret;
-
-none:
-	up(&cfag12864b_mutex);
-	return ret;
-}
-
-
-static ssize_t cfag12864b_fopwrite(struct file *filp,
-	const char __user *buffer, size_t count, loff_t *offset)
+static void cfag12864b_update(void *arg)
 {
-	int ret = -EINVAL;
-	int result;
-
-	if (down_interruptible(&cfag12864b_mutex))
-		return -ERESTARTSYS;
+	unsigned char c;
+	unsigned short i, j, k, b;
 
-	if (*offset > CFAG12864B_SIZE) {
-		ret = 0;
-		goto none;
-	}
-	if (*offset + count > CFAG12864B_SIZE)
-		count = CFAG12864B_SIZE - *offset;
-
-	result = copy_from_user(cfag12864b_buffer, buffer, count);
-	if (result != 0) {
-		printk(KERN_ERR CFAG12864B_NAME ": FOP write: ERROR: "
-			"can't copy memory from user\n");
-		ret = -EFAULT;
-		goto none;
+	for (i = 0; i < CFAG12864B_CONTROLLERS; i++) {
+		cfag12864b_controller(i);
+		cfag12864b_nop();
+		for (j = 0; j < CFAG12864B_PAGES; j++) {
+			cfag12864b_page(j);
+			cfag12864b_nop();
+			for (k = 0; k < CFAG12864B_ADDRESSES; k++) {
+				cfag12864b_address(k);
+				cfag12864b_nop();
+				cfag12864b_nop();
+				for (c = 0, b = 0; b < 8; b++)
+					if (cfag12864b_buffer
+						[i * CFAG12864B_ADDRESSES
+						+ k + (j * 8 + b) *
+						CFAG12864B_WIDTH])
+						c |= bit(b);
+				cfag12864b_writebyte(c);
+			}
+		}
 	}
 
-	cfag12864b_write_nolock(*offset, cfag12864b_buffer, count);
-
-	*offset += count;
-	ret = count;
-
-none:
-	up(&cfag12864b_mutex);
-	return ret;
+	if(cfag12864b_updating)
+		queue_delayed_work(cfag12864b_workqueue, &cfag12864b_work,
+			HZ / cfag12864b_rate);
 }
 
-static const struct file_operations cfag12864b_fops =
-{
-	.owner = THIS_MODULE,
-	.llseek = cfag12864b_fopseek,
-	.write = cfag12864b_fopwrite,
-};
-
 /*
  * Module Init & Exit
  */
 
 static int __init cfag12864b_init(void)
 {
-	int result;
 	int ret = -EINVAL;
 
-	cfag12864b_buffer = kmalloc(sizeof(unsigned char) * CFAG12864B_SIZE,
-		GFP_KERNEL);
+	cfag12864b_buffer = vmalloc(sizeof(unsigned char) *
+		CFAG12864B_SIZE);
 	if (cfag12864b_buffer == NULL) {
 		printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
-			"can't alloc buffer (%i bytes)\n", CFAG12864B_SIZE);
+			"can't alloc buffer (%i bytes)\n",
+			CFAG12864B_SIZE);
 		ret = -ENOMEM;
 		goto none;
 	}
 
-	result = alloc_chrdev_region(&cfag12864b_devt, cfag12864b_firstminor,
-		cfag12864b_ndevices, CFAG12864B_NAME);
-	if (result < 0) {
-		printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
-			"can't alloc the char device region\n");
-		ret = result;
-		goto bufferalloced;
-	}
-
-	cfag12864b_major = MAJOR(cfag12864b_devt);
-	cfag12864b_minor = cfag12864b_firstminor;
-	cfag12864b_devt = MKDEV(cfag12864b_major, cfag12864b_minor);
-
-	cfag12864b_clear_nolock();
-	cfag12864b_on_nolock();
-
-	cdev_init(&cfag12864b_chardevice, &cfag12864b_fops);
-	cfag12864b_chardevice.owner = THIS_MODULE;
-	cfag12864b_chardevice.ops = &cfag12864b_fops;
-	result = cdev_add(&cfag12864b_chardevice, cfag12864b_devt,
-		cfag12864b_ndevices);
-	if (result < 0) {
-		printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
-			"unable to add a new char device\n");
-		ret = result;
-		goto regionalloced;
-	}
+	memset(cfag12864b_buffer, 0, CFAG12864B_SIZE);
 
-	if (class_device_create(auxlcdclass_class, NULL, cfag12864b_devt, NULL,
-		"cfag12864b%d", cfag12864b_minor) == NULL) {
-		printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
-			"unable to create a class device for the auxlcdclass\n");
-		ret = -EINVAL;
-		goto cdevadded;
-	}
+	cfag12864b_clear();
+	cfag12864b_on();
 
-	return 0;
+	cfag12864b_workqueue = create_singlethread_workqueue(CFAG12864B_NAME);
+	if(cfag12864b_workqueue == NULL)
+		goto bufferalloced;
 
-cdevadded:
-	cdev_del(&cfag12864b_chardevice);
+	cfag12864b_updating = 1;
+	cfag12864b_update(NULL);
 
-regionalloced:
-	unregister_chrdev_region(cfag12864b_devt, cfag12864b_ndevices);
+	return 0;
 
 bufferalloced:
-	kfree(cfag12864b_buffer);
+	vfree(cfag12864b_buffer);
 
 none:
 	return ret;
@@ -505,17 +292,18 @@ none:
 
 static void __exit cfag12864b_exit(void)
 {
-	cfag12864b_off_nolock();
+	cfag12864b_updating = 0;
+	mdelay((1000 / cfag12864b_rate) * 2);
+	destroy_workqueue(cfag12864b_workqueue);
+
+	cfag12864b_off();
 
-	class_device_destroy(auxlcdclass_class, cfag12864b_devt);
-	cdev_del(&cfag12864b_chardevice);
-	unregister_chrdev_region(cfag12864b_devt, cfag12864b_ndevices);
-	kfree(cfag12864b_buffer);
+	vfree(cfag12864b_buffer);
 }
 
 module_init(cfag12864b_init);
 module_exit(cfag12864b_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Miguel Ojeda Sandonis <[email protected]>");
 MODULE_DESCRIPTION("cfag12864b LCD driver");
diff -uprN -X dontdiff linux-2.6.19-rc1-x/drivers/auxdisplay/cfag12864bfb.c linux-2.6.19-rc1/drivers/auxdisplay/cfag12864bfb.c
--- linux-2.6.19-rc1-x/drivers/auxdisplay/cfag12864bfb.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.19-rc1/drivers/auxdisplay/cfag12864bfb.c	2006-10-12 12:15:17.000000000 +0000
@@ -0,0 +1,165 @@
+/*
+ *    Filename: cfag12864bfb.c
+ *     Version: 0.1.0
+ * Description: cfag12864b LCD framebuffer driver
+ *     License: GPLv2
+ *     Depends: cfag12864b
+ *
+ *      Author: Copyright (C) Miguel Ojeda Sandonis <[email protected]>
+ *        Date: 2006-10-11
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/cfag12864b.h>
+#include <asm/uaccess.h>
+
+#define CFAG12864BFB_NAME "cfag12864bfb"
+
+static struct fb_fix_screeninfo cfag12864bfb_fix __initdata = {
+	.id = "cfag12864b", 
+	.type = FB_TYPE_PACKED_PIXELS,
+	.visual = FB_VISUAL_MONO10,
+	.xpanstep = 0,
+	.ypanstep = 0,
+	.ywrapstep = 0,
+	.line_length = CFAG12864B_WIDTH,
+	.accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo cfag12864bfb_var __initdata = {
+	.xres = CFAG12864B_WIDTH,
+	.yres = CFAG12864B_HEIGHT,
+	.xres_virtual = CFAG12864B_WIDTH,
+	.yres_virtual = CFAG12864B_HEIGHT,
+	.bits_per_pixel = 8,
+	.red = { 0, 8, 0 },
+      	.green = { 0, 8, 0 },
+      	.blue = { 0, 8, 0 },
+	.left_margin = 0,
+	.right_margin = 0,
+	.upper_margin = 0,
+	.lower_margin = 0,
+	.vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_ops cfag12864bfb_ops = {
+	.owner = THIS_MODULE,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+};
+
+static int __init cfag12864bfb_probe(struct platform_device *device)
+{
+	int ret = -EINVAL;
+ 	struct fb_info *info = framebuffer_alloc(0, &device->dev);
+
+	if (!info)
+		goto none;
+
+	info->screen_base = (char __iomem *)cfag12864b_buffer;
+	info->screen_size = CFAG12864B_SIZE;
+	info->fbops = &cfag12864bfb_ops;
+	info->fix = cfag12864bfb_fix;
+	info->var = cfag12864bfb_var;
+	info->pseudo_palette = NULL;
+	info->par = NULL;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+	if (register_framebuffer(info) < 0)
+		goto fballoced;
+
+	platform_set_drvdata(device, info);
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+		info->fix.id);
+
+	return 0;
+
+fballoced:
+	framebuffer_release(info);
+
+none:
+	return ret;
+}
+
+static int cfag12864bfb_remove(struct platform_device *device)
+{
+	struct fb_info *info = platform_get_drvdata(device);
+
+	if (info) {
+		unregister_framebuffer(info);
+		framebuffer_release(info);
+	}
+
+	return 0;
+}
+
+static struct platform_driver cfag12864bfb_driver = {
+	.probe	= cfag12864bfb_probe,
+	.remove = cfag12864bfb_remove,
+	.driver = {
+		.name	= CFAG12864BFB_NAME,
+	},
+};
+
+static struct platform_device *cfag12864bfb_device;
+
+static int __init cfag12864bfb_init(void)
+{
+	int ret = platform_driver_register(&cfag12864bfb_driver);
+
+	if (!ret) {
+		cfag12864bfb_device =
+			platform_device_alloc(CFAG12864BFB_NAME, 0);
+
+		if (cfag12864bfb_device)
+			ret = platform_device_add(cfag12864bfb_device);
+		else
+			ret = -ENOMEM;
+
+		if (ret) {
+			platform_device_put(cfag12864bfb_device);
+			platform_driver_unregister(&cfag12864bfb_driver);
+		}
+	}
+
+	return ret;
+}
+
+static void __exit cfag12864bfb_exit(void)
+{
+	platform_device_unregister(cfag12864bfb_device);
+	platform_driver_unregister(&cfag12864bfb_driver);
+}
+
+module_init(cfag12864bfb_init);
+module_exit(cfag12864bfb_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Miguel Ojeda Sandonis <[email protected]>");
+MODULE_DESCRIPTION("cfag12864b LCD framebuffer driver");
diff -uprN -X dontdiff linux-2.6.19-rc1-x/drivers/auxdisplay/fbcfag12864b.c linux-2.6.19-rc1/drivers/auxdisplay/fbcfag12864b.c
--- linux-2.6.19-rc1-x/drivers/auxdisplay/fbcfag12864b.c	2006-10-10 12:58:44.000000000 +0000
+++ linux-2.6.19-rc1/drivers/auxdisplay/fbcfag12864b.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,226 +0,0 @@
-/*
- *    Filename: fbcfag12864b.c
- *     Version: 0.1.0
- * Description: cfag12864b LCD framebuffer device
- *     License: GPLv2
- *     Depends: cfag12864b
- *
- *      Author: Copyright (C) Miguel Ojeda Sandonis <[email protected]>
- *        Date: 2006-10-10
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <asm/uaccess.h>
-#include "sdum.h"
-#include "fbcommon.h"
-
-static u32 colreg[16];
-
-static struct fb_var_screeninfo rgbfb_var __initdata = {
-	.xres = LCD_X_RES,
-	.yres = LCD_Y_RES,
-	.xres_virtual = LCD_X_RES,
-	.yres_virtual = LCD_Y_RES,
-	.bits_per_pixel = 32,
-	.red.offset = 16,
-	.red.length = 8,
-	.green.offset = 8,
-	.green.length = 8,
-	.blue.offset = 0,
-	.blue.length = 8,
-	.left_margin = 0,
-	.right_margin = 0,
-	.upper_margin = 0,
-	.lower_margin = 0,
-	.vmode = FB_VMODE_NONINTERLACED,
-};
-static struct fb_fix_screeninfo rgbfb_fix __initdata = {
-	.id = "RGBFB",
-	.line_length = LCD_X_RES * LCD_BBP,
-	.type = FB_TYPE_PACKED_PIXELS,
-	.visual = FB_VISUAL_TRUECOLOR,
-	.xpanstep = 0,
-	.ypanstep = 0,
-	.ywrapstep = 0,
-	.accel = FB_ACCEL_NONE,
-};
-
-static int channel_owned;
-
-static int no_cursor(struct fb_info *info, struct fb_cursor *cursor)
-{
-	return 0;
-}
-
-static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			   u_int transp, struct fb_info *info)
-{
-	if (regno > 15)
-		return 1;
-
-	colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) |
-	    ((blue & 0xff00) >> 8);
-	return 0;
-}
-
-static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-	return pnx4008_sdum_mmap(info, vma, NULL);
-}
-
-static struct fb_ops rgbfb_ops = {
-	.fb_mmap = rgbfb_mmap,
-	.fb_setcolreg = rgbfb_setcolreg,
-	.fb_fillrect = cfb_fillrect,
-	.fb_copyarea = cfb_copyarea,
-	.fb_imageblit = cfb_imageblit,
-};
-
-static int rgbfb_remove(struct platform_device *pdev)
-{
-	struct fb_info *info = platform_get_drvdata(pdev);
-
-	if (info) {
-		unregister_framebuffer(info);
-		fb_dealloc_cmap(&info->cmap);
-		framebuffer_release(info);
-		platform_set_drvdata(pdev, NULL);
-		kfree(info);
-	}
-
-	pnx4008_free_dum_channel(channel_owned, pdev->id);
-	pnx4008_set_dum_exit_notification(pdev->id);
-
-	return 0;
-}
-
-static int __devinit rgbfb_probe(struct platform_device *pdev)
-{
-	struct fb_info *info;
-	struct dumchannel_uf chan_uf;
-	int ret;
-	char *option;
-
-	info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
-	if (!info) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base,
-				 (dma_addr_t *) &rgbfb_fix.smem_start,
-				 &rgbfb_fix.smem_len);
-
-	if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0)
-		goto err0;
-	else {
-		channel_owned = ret;
-		chan_uf.channelnr = channel_owned;
-		chan_uf.dirty = (u32 *) NULL;
-		chan_uf.source = (u32 *) rgbfb_fix.smem_start;
-		chan_uf.x_offset = 0;
-		chan_uf.y_offset = 0;
-		chan_uf.width = LCD_X_RES;
-		chan_uf.height = LCD_Y_RES;
-
-		if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0)
-			goto err1;
-
-		if ((ret =
-		     pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON,
-						  pdev->id)) < 0)
-			goto err1;
-
-		if ((ret =
-		     pnx4008_set_dum_channel_dirty_detect(channel_owned,
-							 CONF_DIRTYDETECTION_ON,
-							 pdev->id)) < 0)
-			goto err1;
-	}
-
-	if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor"))
-		rgbfb_ops.fb_cursor = no_cursor;
-
-	info->node = -1;
-	info->flags = FBINFO_FLAG_DEFAULT;
-	info->fbops = &rgbfb_ops;
-	info->fix = rgbfb_fix;
-	info->var = rgbfb_var;
-	info->screen_size = rgbfb_fix.smem_len;
-	info->pseudo_palette = info->par;
-	info->par = NULL;
-
-	ret = fb_alloc_cmap(&info->cmap, 256, 0);
-	if (ret < 0)
-		goto err2;
-
-	ret = register_framebuffer(info);
-	if (ret < 0)
-		goto err3;
-	platform_set_drvdata(pdev, info);
-
-	return 0;
-
-err3:
-	fb_dealloc_cmap(&info->cmap);
-err2:
-	framebuffer_release(info);
-err1:
-	pnx4008_free_dum_channel(channel_owned, pdev->id);
-err0:
-	kfree(info);
-err:
-	return ret;
-}
-
-static struct platform_driver rgbfb_driver = {
-	.driver = {
-		.name = "rgbfb",
-	},
-	.probe = rgbfb_probe,
-	.remove = rgbfb_remove,
-};
-
-static int __init fbcfag12864b_init(void)
-{
-	return platform_driver_register(&rgbfb_driver);
-}
-
-static void __exit fbcfag12864b_exit(void)
-{
-	platform_driver_unregister(&rgbfb_driver);
-}
-
-module_init(fbcfag12864b_init);
-module_exit(fbcfag12864b_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Miguel Ojeda Sandonis <[email protected]>");
-MODULE_DESCRIPTION("cfag12864b LCD driver");
diff -uprN -X dontdiff linux-2.6.19-rc1-x/drivers/auxdisplay/Kconfig linux-2.6.19-rc1/drivers/auxdisplay/Kconfig
--- linux-2.6.19-rc1-x/drivers/auxdisplay/Kconfig	2006-10-10 12:58:44.000000000 +0000
+++ linux-2.6.19-rc1/drivers/auxdisplay/Kconfig	2006-10-12 13:33:50.000000000 +0000
@@ -7,25 +7,10 @@
 
 menu "Auxiliary Display support"
 
-config AUXLCDCLASS
-	tristate "Auxiliary LCD support"
-	default n
-	---help---
-	  If you have a LCD (Liquid Crystal Display), say Y.
-
-	  To compile this as a module, choose M here:
-	  the module will be called auxlcdclass.
-
-	  Most LCD drivers use an I/O port (like the parallel port)
-	  so you will need to say Y or M for them.
-
-	  If unsure, say N.
-
-comment "Parallel port dependent"
-
 config KS0108
 	tristate "KS0108 LCD Controller"
-	depends on AUXLCDCLASS && PARPORT
+	select PARPORT
+	select PARPORT_PC
 	default n
 	---help---
 	  If you have a LCD controlled by one or more KS0108
@@ -94,10 +79,37 @@ config CFAG12864B
 	  Also, you can find help in Crystalfontz and LCDStudio forums.
 	  Check Documentation/lcddisplay/cfag12864b for more information.
 
+	  The LCD framebuffer driver can be attached to a console.
+	  It will work fine. However, you can't attach it to the fbdev driver
+	  of the xorg server.
+
 	  To compile this as a module, choose M here:
-	  the module will be called cfag12864b.
+	  the modules will be called cfag12864b and cfag12864bfb.
 
 	  If unsure, say N.
 
+config CFAG12864B_RATE
+	int "Refresh rate (hertzs)"
+	depends on CFAG12864B
+	default "10"
+	---help---
+	  Refresh rate of the LCD.
+
+	  As the LCD is not memory mapped, the driver has to make the work by
+	  software. This means you should be careful setting this value higher.
+	  If your CPUs are slow or you feel the CPUs are working above your %,
+	  decrease the value.
+
+	  Hints:
+	     Pentium4 3Ghz at 10 Hz uses about 15% CPU time.
+	     Pentium4 3Ghz at 20 Hz uses about 30% CPU time.
+
+	  Be careful modifying this value to a very high value:
+	  You can freeze the computer.
+
+	  If you don't know what I'm talking about, ignore it.
+
+	  If you compile this as a module, you can still override this
+	  value using the module parameters.
 endmenu
 
diff -uprN -X dontdiff linux-2.6.19-rc1-x/drivers/auxdisplay/ks0108.c linux-2.6.19-rc1/drivers/auxdisplay/ks0108.c
--- linux-2.6.19-rc1-x/drivers/auxdisplay/ks0108.c	2006-10-10 12:58:44.000000000 +0000
+++ linux-2.6.19-rc1/drivers/auxdisplay/ks0108.c	2006-10-11 23:20:33.000000000 +0000
@@ -161,7 +161,7 @@ static void __exit ks0108_exit(void)
 module_init(ks0108_init);
 module_exit(ks0108_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Miguel Ojeda Sandonis <[email protected]>");
 MODULE_DESCRIPTION("ks0108 LCD Controller driver");
 
diff -uprN -X dontdiff linux-2.6.19-rc1-x/drivers/auxdisplay/Makefile linux-2.6.19-rc1/drivers/auxdisplay/Makefile
--- linux-2.6.19-rc1-x/drivers/auxdisplay/Makefile	2006-10-10 14:59:46.000000000 +0000
+++ linux-2.6.19-rc1/drivers/auxdisplay/Makefile	2006-10-11 15:51:37.000000000 +0000
@@ -2,6 +2,5 @@
 # Makefile for the kernel auxiliary displays device drivers.
 #
 
-obj-$(CONFIG_AUXLCDCLASS)	+= auxlcdclass.o
 obj-$(CONFIG_KS0108)		+= ks0108.o
-obj-$(CONFIG_CFAG12864B)	+= cfag12864b.o
+obj-$(CONFIG_CFAG12864B)	+= cfag12864b.o cfag12864bfb.o
diff -uprN -X dontdiff linux-2.6.19-rc1-x/include/linux/auxlcdclass.h linux-2.6.19-rc1/include/linux/auxlcdclass.h
--- linux-2.6.19-rc1-x/include/linux/auxlcdclass.h	2006-10-10 12:59:00.000000000 +0000
+++ linux-2.6.19-rc1/include/linux/auxlcdclass.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,33 +0,0 @@
-/*
- *    Filename: auxlcdclass.h
- *     Version: 0.1.0
- * Description: Auxiliary LCD Class Header
- *     License: GPLv2
- *
- *      Author: Copyright (C) Miguel Ojeda Sandonis <[email protected]>
- *        Date: 2006-10-05
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#ifndef _AUXLCDCLASS_H_
-#define _AUXLCDCLASS_H_
-
-#include <linux/device.h>
-
-extern struct class *auxlcdclass_class;
-
-#endif /* _AUXLCDCLASS_H_ */
diff -uprN -X dontdiff linux-2.6.19-rc1-x/include/linux/cfag12864b.h linux-2.6.19-rc1/include/linux/cfag12864b.h
--- linux-2.6.19-rc1-x/include/linux/cfag12864b.h	2006-10-10 12:59:00.000000000 +0000
+++ linux-2.6.19-rc1/include/linux/cfag12864b.h	2006-10-12 12:30:58.000000000 +0000
@@ -5,7 +5,7 @@
  *     License: GPLv2
  *
  *      Author: Copyright (C) Miguel Ojeda Sandonis <[email protected]>
- *        Date: 2006-10-04
+ *        Date: 2006-10-12
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -28,21 +28,12 @@
 
 #define CFAG12864B_WIDTH	(128)
 #define CFAG12864B_HEIGHT	(64)
-#define CFAG12864B_MATRIXSIZE	((CFAG12864B_WIDTH) * (CFAG12864B_HEIGHT))
-
 #define CFAG12864B_CONTROLLERS	(2)
 #define CFAG12864B_PAGES	(8)
 #define CFAG12864B_ADDRESSES	(64)
-#define CFAG12864B_SIZE		((CFAG12864B_CONTROLLERS) * \
-				(CFAG12864B_PAGES) * \
-				(CFAG12864B_ADDRESSES))
+#define CFAG12864B_SIZE		((CFAG12864B_WIDTH)*(CFAG12864B_HEIGHT))
 
-extern void cfag12864b_on(void);
-extern void cfag12864b_off(void);
-extern void cfag12864b_clear(void);
-extern void cfag12864b_write(unsigned short offset,
-	const unsigned char *buffer, unsigned short count);
-extern void cfag12864b_format(unsigned char *src);
+extern unsigned char * cfag12864b_buffer;
 
 #endif /* _CFAG12864B_H_ */
 
diff -uprN -X dontdiff linux-2.6.19-rc1-x/MAINTAINERS linux-2.6.19-rc1/MAINTAINERS
--- linux-2.6.19-rc1-x/MAINTAINERS	2006-10-10 12:57:42.000000000 +0000
+++ linux-2.6.19-rc1/MAINTAINERS	2006-10-12 12:24:08.000000000 +0000
@@ -658,6 +658,12 @@ M:	[email protected]
 L:	[email protected]
 S:	Maintained
 
+CFAG12864BFB LCD FRAMEBUFFER DRIVER
+P:	Miguel Ojeda Sandonis
+M:	[email protected]
+L:	[email protected]
+S:	Maintained
+
 COMMON INTERNET FILE SYSTEM (CIFS)
 P:	Steve French
 M:	[email protected]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux