summaryrefslogtreecommitdiffstats
path: root/drivers/video/macfb.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
commit86464aed71025541805e7b1515541aee89879e33 (patch)
treee01a457a4912a8553bc65524aa3125d51f29f810 /drivers/video/macfb.c
parent88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff)
Merge with Linux 2.2.1.
Diffstat (limited to 'drivers/video/macfb.c')
-rw-r--r--drivers/video/macfb.c165
1 files changed, 154 insertions, 11 deletions
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 2d0ad2924..0f964f60a 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -22,6 +22,7 @@
#include <asm/macintosh.h>
#include <linux/fb.h>
+#include <video/fbcon.h>
/* conditionalize these ?? */
#include <video/fbcon-mfb.h>
#include <video/fbcon-cfb2.h>
@@ -154,13 +155,15 @@ static void macfb_encode_fix(struct fb_fix_screeninfo *fix,
strcpy(fix->id,"Macintosh");
/*
- * X works, but screen wraps ...
+ * fbmem.c accepts non page aligned mappings now!
*/
- fix->smem_start=(char *)(mac_videobase&PAGE_MASK);
- fix->smem_offset=(mac_videobase&~PAGE_MASK);
- fix->smem_len=PAGE_ALIGN(mac_videosize);
+ fix->smem_start=(char *)mac_videobase;
+ fix->smem_len=mac_videosize;
fix->type = FB_TYPE_PACKED_PIXELS;
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ if (mac_depth == 1)
+ fix->visual = FB_VISUAL_MONO01;
+ else
+ fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
fix->xpanstep=0;
fix->ypanstep=0;
fix->ywrapstep=0;
@@ -203,7 +206,7 @@ static void macfb_set_disp(int con)
macfb_get_fix(&fix, con, 0);
- display->screen_base = fix.smem_start+fix.smem_offset;
+ display->screen_base = fix.smem_start;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -212,7 +215,8 @@ static void macfb_set_disp(int con)
display->line_length = fix.line_length;
display->next_line = fix.line_length;
display->can_soft_blank = 0;
- display->inverse = inverse;
+ display->inverse =
+ (fix.visual == FB_VISUAL_MONO01 ? !inverse : inverse);
switch (mac_depth) {
#ifdef FBCON_HAS_MFB
@@ -251,6 +255,140 @@ static int macfb_set_var(struct fb_var_screeninfo *var, int con,
return 0;
}
+/*
+ * Color map handling - hardcoded maps!!
+ *
+ * 2.0 color map primitives, copied from atafb.c
+ */
+
+/*
+ * should be kmalloc'ed on request
+ */
+static short red256[256], green256[256], blue256[256];
+
+static short red16[]=
+ { 0x0000,0x0000,0x0000,0x0000,0x8080,0x8080,0x8080,0xc0c0,
+ 0x8080,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff};
+static short green16[]=
+ { 0x0000,0x0000,0x8080,0x8080,0x0000,0x0000,0x8080,0xc0c0,
+ 0x8080,0x0000,0xffff,0xffff,0x0000,0x0000,0xffff,0xffff};
+static short blue16[]=
+ { 0x0000,0x8080,0x0000,0x8080,0x0000,0x8080,0x0000,0xc0c0,
+ 0x8080,0xffff,0x0000,0xffff,0x0000,0xffff,0x0000,0xffff};
+
+static short red4[]=
+ { 0x0000,0x8080,0xffff,0xffff};
+static short green4[]=
+ { 0x0000,0x8080,0x0000,0xffff};
+static short blue4[]=
+ { 0x0000,0x8080,0x0000,0xffff};
+
+static short red2[]=
+ { 0x0000,0xffff};
+static short green2[]=
+ { 0x0000,0xffff};
+static short blue2[]=
+ { 0x0000,0xffff};
+
+struct fb_cmap default_256_colors = { 0, 256, red256, green256, blue256, NULL };
+struct fb_cmap default_16_colors = { 0, 16, red16, green16, blue16, NULL };
+struct fb_cmap default_4_colors = { 0, 4, red4, green4, blue4, NULL };
+struct fb_cmap default_2_colors = { 0, 2, red2, green2, blue2, NULL };
+
+static int mac_set_cmap256(struct fb_cmap* cmap)
+{
+ int i,start;
+ unsigned short *red,*green,*blue;
+ unsigned short cval[] = {0xffff, 0xcccc, 0x9999,
+ 0x6666, 0x3333, 0x0000 };
+ unsigned short gval[] = {0x0a0a, 0x1414, 0x1e1e,
+ 0x2828, 0x3232, 0x3c3c,
+ 0x4646, 0x5050, 0x5a5a,
+ 0x6464, 0x6e6e, 0x7878,
+ 0x8282, 0x8c8c, 0x9696,
+ 0xa0a0, 0xaaaa, 0xb4b4,
+ 0xbebe, 0xc8c8, 0xd2d2,
+ 0xdcdc, 0xe6e6, 0xf0f0};
+
+ red=cmap->red;
+ green=cmap->green;
+ blue=cmap->blue;
+ start=cmap->start;
+
+ if (start < 0)
+ return -EINVAL;
+ if (cmap->len < 255)
+ return -EINVAL;
+ /* 16 ANSI colors */
+ for (i=0 ; i < 16 ; i++) {
+ *red++ = red16[i];
+ *green++ = green16[i];
+ *blue++ = blue16[i];
+ }
+ /* 216 colors (6x6x6) map) */
+ for (i=16 ; i < 232 ; i++) {
+ *red++ = cval[(i-16)/36];
+ *green++ = cval[((i-16)/6)%6];
+ *blue++ = cval[(i-16)%6];
+ }
+ /* 24 grays */
+ for (i=232 ; i < 256 ; i++) {
+ *red = *green = *blue = gval[i-232];
+ red++;
+ green++;
+ blue++;
+ }
+ return 0;
+}
+
+static struct fb_cmap * mac_get_default_cmap(int bpp)
+{
+ if (bpp == 1)
+ return &default_2_colors;
+ if (bpp == 2)
+ return &default_4_colors;
+ if (bpp == 4)
+ return &default_16_colors;
+ return &default_256_colors;
+}
+
+static void memcpy_fs(int fsfromto, void *to, void *from, int len)
+{
+ switch (fsfromto) {
+ case 0:
+ memcpy(to, from, len);
+ return;
+ case 1:
+ copy_from_user(to, from, len);
+ return;
+ case 2:
+ copy_to_user(to, from, len);
+ return;
+ }
+}
+
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+{
+ int size;
+ int tooff=0, fromoff=0;
+
+ if (to->start > from->start)
+ fromoff=to->start-from->start;
+ else
+ tooff=from->start-to->start;
+ size=to->len-tooff;
+ if (size > from->len-fromoff)
+ size=from->len-fromoff;
+ if (size < 0)
+ return;
+ size*=sizeof(unsigned short);
+ memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
+ memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
+ memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
+ if (from->transp && to->transp)
+ memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
+}
+
static int macfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
@@ -267,6 +405,8 @@ static int macfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
cmap, kspc ? 0 : 2);
#endif
+ copy_cmap(mac_get_default_cmap(fb_display[con].var.bits_per_pixel),
+ cmap, kspc ? 0 : 2);
return 0;
}
@@ -387,11 +527,9 @@ __initfunc(void macfb_init(void))
mac_videosize=mac_xbytes*mac_yres;
mac_videobase=mac_bi_data.videoaddr;
- printk("macfb_init: xres %d yres %d bpp %d addr %x size %d \n",
+ printk("macfb_init: xres %d yres %d bpp %d addr %lx size %ld \n",
mac_xres, mac_yres, mac_depth, mac_videobase, mac_videosize);
- mac_debugging_penguin(4);
-
/*
* Fill in the available video resolution
*/
@@ -421,6 +559,12 @@ __initfunc(void macfb_init(void))
macfb_set_disp(-1);
/*
+ * Fill in the 8 bit color table if required
+ */
+ if (mac_depth == 8)
+ mac_set_cmap256(&default_256_colors);
+
+ /*
* Register the nubus hook
*/
@@ -428,7 +572,6 @@ __initfunc(void macfb_init(void))
if (register_framebuffer(&fb_info) < 0)
{
- mac_boom(6);
return;
}