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); }