[PATCH] gxfb: Add an ioctl() to set the gamma correction RAM

Jordan Crouse jordan.crouse at amd.com
Tue Nov 7 22:37:46 EST 2006


Commit:     950d1405bfd7d0e5af72a2bf3abca8ce5d9d0e62
Parent:     38b294619def76fe84c2fdd5286c0ce39f7619a9
commit 950d1405bfd7d0e5af72a2bf3abca8ce5d9d0e62
Author:     Jordan Crouse <jordan.crouse at amd.com>
AuthorDate: Wed Oct 18 14:45:35 2006 -0600
Commit:     Jordan Crouse <jordan.crouse at amd.com>
CommitDate: Wed Oct 18 14:45:35 2006 -0600

    [PATCH] gxfb:  Add an ioctl() to set the gamma correction RAM
    
    Add two new ioctls() to the gxfb driver to allow the user to set
    and get the contents of the gamma correction RAM.
    
    Signed-off-by: Jordan Crouse <jordan.crouse at amd.com>
---
 drivers/video/geode/gxfb_core.c |   46 +++++++++++++++++++++++++++++++++++++--
 drivers/video/geode/video_gx.h  |    8 +++++++
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 7617e3d..5bf2a90 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -30,11 +30,15 @@ #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <asm/uaccess.h>
 
 #include "geodefb.h"
 #include "display_gx.h"
 #include "video_gx.h"
 
+#define FBIOSGAMMA		_IOW('F', 0x20, void *)
+#define FBIOGGAMMA		_IOW('F', 0x21, void *)
+
 static char *mode_option;
 
 /* Modes relevant to the GX (taken from modedb.c) */
@@ -283,10 +287,48 @@ EXPORT_SYMBOL(gxfb_ioctl_func);
 static int gxfb_ioctl( struct fb_info *info, unsigned int cmd,
 		       unsigned long arg)
 {
+	unsigned int gamma[GXFB_GAMMA_DWORDS];
 	int ret = -ENOTTY;
+	struct geodefb_par *par = info->par;
+	int i;
+
+	switch(cmd) {
+	case FBIOSGAMMA:
+		/* Read the gamma information from the user - 256 dwords */
+
+		if (copy_from_user(gamma, (void * __user) arg, GXFB_GAMMA_SIZE))
+			return -EFAULT;
+
+		writel(0, par->vid_regs + GX_GAR);
+
+		/* Sequential writes to the data register will increment the
+		   address automatically  */
+
+		for(i = 0; i < GXFB_GAMMA_DWORDS; i++)
+			writel(gamma[i] & 0xFFFFFF, par->vid_regs + GX_GDR);
 
-	if (gxfb_ioctl_func != NULL)
-		ret = gxfb_ioctl_func(info, cmd, arg);
+		ret = 0;
+		break;
+
+	case FBIOGGAMMA:
+		memset(gamma, 0, GXFB_GAMMA_SIZE);
+		writel(0, par->vid_regs + GX_GAR);
+
+		for(i = 0; i < GXFB_GAMMA_DWORDS;i++)
+			gamma[i] = readl(par->vid_regs + GX_GDR);
+
+		if (copy_to_user((void * __user) arg, gamma, GXFB_GAMMA_SIZE))
+			ret = -EFAULT;
+		else
+			ret = 0;
+
+		break;
+
+	default:
+		if (gxfb_ioctl_func != NULL)
+			ret = gxfb_ioctl_func(info, cmd, arg);
+		break;
+	}
 
 	return ret;
 }
diff --git a/drivers/video/geode/video_gx.h b/drivers/video/geode/video_gx.h
index 4f9c9b3..65952a2 100644
--- a/drivers/video/geode/video_gx.h
+++ b/drivers/video/geode/video_gx.h
@@ -44,6 +44,14 @@ #define GX_MISC_GAM_EN     0x00000001
 #define GX_MISC_DAC_PWRDN  0x00000400
 #define GX_MISC_A_PWRDN    0x00000800
 
+/* Gamma correction RAM - address and data registers */
+
+#define GX_GAR 0x038
+#define GX_GDR 0x040
+
+#define GXFB_GAMMA_DWORDS 256 /* number of dwords in the gamma ram */
+#define GXFB_GAMMA_SIZE (GXFB_GAMMA_DWORDS * sizeof(unsigned int))
+
 /* Geode GX flat panel display control registers */
 
 #define GX_FP_PT1 0x0400


More information about the Commits-kernel mailing list