I've added support to the atyfb driver for video mirroring, much like
Ben's m3mirror setup he's got going in the aty128fb driver.

I changed the name to ltpromirror.  The code is basically lifted
directly from the aty128fb driver, with changes made to make it work
with the atyfb driver.

2 kernel patches, and a user space utility...here are my observations:

* if I enable/disable anything while in X it doesn't work quite right
  -- the effects seem to be delayed until I exit X.
* if I have ONLY the crt enabled, X won't start...I haven't looked
  into this further.

When I get home, I'm going to take a look to see if the svideo can be
coaxed into working.

apply the two diffs in the drivers/video/aty directory.

oh, I should mention, these diffs are against the 2.4.9-benh0 kernel,
but hopefully will apply to newer kernels as well.

Also, something should be done about the brightness of the LCD panel.
Sometimes it gets enabled, but you need to press the brightness up
button to see picture again.

Oh, and one last thing -- I've been testing this on my laptop, a
lombard g3.

-- 
Josh Huber                                   | [EMAIL PROTECTED] |
--- atyfb.h.orig        Mon Sep 24 11:49:50 2001
+++ atyfb.h     Mon Sep 24 11:52:40 2001
@@ -133,6 +133,7 @@
 #ifdef CONFIG_PMAC_PBOOK
     unsigned char *save_framebuffer;
     unsigned long save_pll[64];
+    int crt_on, lcd_on;
 #endif
 };
 
--- atyfb_base.c        Mon Sep 24 15:03:05 2001
+++ atyfb_base.c.orig   Mon Sep 24 11:46:48 2001
@@ -267,11 +267,6 @@
 #endif
 #endif
 
-#ifdef CONFIG_PMAC_PBOOK
-static int default_crt_on __initdata = 0;
-static int default_lcd_on __initdata = 1;
-#endif
-
 #ifdef CONFIG_ATARI
 static unsigned int mach64_count __initdata = 0;
 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
@@ -728,32 +723,6 @@
     return 0;
 }
 
-/* bit 0 of LCD_GEN_CTRL is crt on/off */
-static void
-aty_set_crt_enable(struct fb_info_aty *info, int on)
-{
-    if (on) {
-           aty_st_lcd(LCD_GEN_CTRL,
-                      aty_ld_lcd(LCD_GEN_CTRL, info) | 0x1, info);
-    } else {
-           aty_st_lcd(LCD_GEN_CTRL,
-                      aty_ld_lcd(LCD_GEN_CTRL, info) & ~0x1, info);
-    }
-}
-
-/* bit 1 of LCD_GEN_CTRL is lcd on/off */
-static void
-aty_set_lcd_enable(struct fb_info_aty *info, int on)
-{
-    if (on) {
-           aty_st_lcd(LCD_GEN_CTRL,
-                      aty_ld_lcd(LCD_GEN_CTRL, info) | 0x2, info);
-    } else {
-           aty_st_lcd(LCD_GEN_CTRL,
-                      aty_ld_lcd(LCD_GEN_CTRL, info) & ~0x2, info);
-    }
-}
-
 /* ------------------------------------------------------------------------- */
 
 static void atyfb_set_par(const struct atyfb_par *par,
@@ -833,13 +802,6 @@
     if (par->accel_flags & FB_ACCELF_TEXT)
        aty_init_engine(par, info);
 
-#ifdef CONFIG_PMAC_PBOOK
-    if (M64_HAS(G3_PB_1_1)) {
-       aty_set_crt_enable(info, info->crt_on);
-       aty_set_lcd_enable(info, info->lcd_on);
-    }
-#endif
-
 #ifdef CONFIG_FB_COMPAT_XPMAC
     if (!console_fb_info || console_fb_info == &info->fb_info) {
        struct fb_var_screeninfo var;
@@ -1289,14 +1251,10 @@
 #define ATYIO_FEATW            0x41545903      /* ATY\03 */
 #endif
 
-#define FBIO_ATY_GET_MIRROR    _IOR('#', 1, sizeof(__u32*))
-#define FBIO_ATY_SET_MIRROR    _IOW('#', 2, sizeof(__u32*))
-
 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                       u_long arg, int con, struct fb_info *info2)
 {
-#if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT)) \
-    || defined(CONFIG_PMAC_PBOOK)
+#if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
     struct fb_info_aty *info = (struct fb_info_aty *)info2;
 #endif /* __sparc__ || DEBUG */
 #ifdef __sparc__
@@ -1308,31 +1266,8 @@
     else
         disp = info2->disp;
 #endif
-#if defined(CONFIG_PMAC_PBOOK)
-    u32 value, rc;
-#endif
 
     switch (cmd) {
-#ifdef CONFIG_PMAC_PBOOK
-    case FBIO_ATY_SET_MIRROR:
-       if (! M64_HAS(G3_PB_1_1))
-               return -EINVAL;
-       rc = get_user(value, (__u32*)arg);
-       if (rc)
-               return rc;
-       info->lcd_on = (value & 0x01) != 0;
-       info->crt_on = (value & 0x02) != 0;
-       if (!info->crt_on && !info->lcd_on)
-               info->lcd_on = 1;
-       aty_set_crt_enable(info, info->crt_on); 
-       aty_set_lcd_enable(info, info->lcd_on); 
-       break;
-    case FBIO_ATY_GET_MIRROR:
-       if (! M64_HAS(G3_PB_1_1))
-               return -EINVAL;
-       value = (info->crt_on << 1) | info->lcd_on;
-       return put_user(value, (__u32*)arg);
-#endif
 #ifdef __sparc__
     case FBIOGTYPE:
        fbtyp.fb_type = FBTYPE_PCI_GENERIC;
@@ -2081,11 +2016,6 @@
        register_backlight_controller(&aty_backlight_controller, info, "ati");
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
-#ifdef CONFIG_PMAC_PBOOK
-    info->lcd_on = default_lcd_on;
-    info->crt_on = default_crt_on;
-#endif
-
 #ifdef MODULE
     var = default_var;
 #else /* !MODULE */
@@ -2617,12 +2547,6 @@
                curblink = 0;
        } else if (!strncmp(this_opt, "noaccel", 7)) {
                noaccel = 1;
-#ifdef CONFIG_PMAC_PBOOK
-        } else if (!strncmp(this_opt, "lcd:", 4)) {
-            default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
-        } else if (!strncmp(this_opt, "crt:", 4)) {
-            default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
-#endif
        } else if (!strncmp(this_opt, "vram:", 5))
                default_vram = simple_strtoul(this_opt+5, NULL, 0);
        else if (!strncmp(this_opt, "pll:", 4))
/* VERY similar to the m3mirror by benh, just hacked to support the
 * rage lt pro
 *  - Josh <[EMAIL PROTECTED]> */

#include <stdio.h>
#include <errno.h>
#include <linux/ioctl.h>

#define ATY_MIRROR_LCD_ON	0x00000001
#define ATY_MIRROR_CRT_ON	0x00000002

#define __u32 unsigned int

#define FBIO_ATY_GET_MIRROR	_IOR('#', 1, sizeof(__u32*))
#define FBIO_ATY_SET_MIRROR	_IOW('#', 2, sizeof(__u32*))

static void
usage(void)
{
	printf("syntax: ltpromirror [crt:0|1] [lcd:0|1]\n");
}

main(int ac, char **av)
{
	int fd, rc, i;
	unsigned long value, orig;

	printf("ATI Rage LT Pro mirror tool, v0.1\n");
	fd = open("/dev/fb0", 0);
	if (fd < 0) {
		perror("open /dev/fb0");
		exit(1);
	}
	rc = ioctl(fd, FBIO_ATY_GET_MIRROR, &value);
	if (rc != 0) {
		printf("error %d getting mirror value\n");
		goto bail;
	}
	printf("Mirror is currently: lcd: %s, crt: %s\n",
		(value & ATY_MIRROR_LCD_ON) ? "on" : "off",
		(value & ATY_MIRROR_CRT_ON) ? "on" : "off");
	orig = value;
	for(i=1; i<ac; i++) {
		if (!strncmp(av[i], "lcd:", 4)) {
			if (atoi((av[i])+4))
				value |= ATY_MIRROR_LCD_ON;
			else
				value &= ~ATY_MIRROR_LCD_ON;
		} else if (!strncmp(av[i], "crt:", 4)) {
			if (atoi((av[i])+4))
				value |= ATY_MIRROR_CRT_ON;
			else
				value &= ~ATY_MIRROR_CRT_ON;
		} else {
			usage();
			rc = -EINVAL;
			goto bail;
		}
	}
	if (orig != value) {
		rc = ioctl(fd, FBIO_ATY_SET_MIRROR, &value);
		if (rc != 0) {
			printf("error %d setting mirror value\n");
			exit(rc);
		}
		printf("Mirror is now: lcd: %s, crt: %s\n",
			(value & ATY_MIRROR_LCD_ON) ? "on" : "off",
			(value & ATY_MIRROR_CRT_ON) ? "on" : "off");
	}
bail:
	close(fd);	
	exit(rc);
}

Reply via email to