Le lundi 09/27/04 Jens Schmalzing <[EMAIL PROTECTED]> a écrit :
> Once offb has been started, you cannot get rid of it anymore.  In
> order to use rivafb, you must build your own kernel and build rivafb
> into it.  But beware, last time I tried the rivafb driver it crashed
> my machine.

I use a patch to control backlight with offb (attached). 
AFAIK, backlight control with rivafb is not yet included in vanilla
or debian kernels.

-- 
Djoumé SALVETTI
--- linus--steve--2.6.4--base-0/drivers/video/offb.c    2004-06-20 
17:10:15.000000000 +0800
+++ /build/kernel/linux-2.6.4/drivers/video/offb.c      2004-06-08 
03:05:23.000000000 +0800
@@ -28,10 +28,20 @@
 #include <linux/ioport.h>
 #include <asm/io.h>
 #include <asm/prom.h>
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
 #ifdef CONFIG_BOOTX_TEXT
 #include <asm/bootx.h>
 #endif
 
+#ifdef CONFIG_ADB_PMU
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#endif
+
 #include "macmodes.h"
 
 /* Supported palette hacks */
@@ -74,6 +84,23 @@
 extern boot_infos_t *boot_infos;
 #endif
 
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int nv_set_backlight_enable(int on, int level, void *data);
+static int nv_set_backlight_level(int level, void *data)
+{
+       return nv_set_backlight_enable(1, level, data);
+}
+static struct backlight_controller nv_backlight_controller = {
+       nv_set_backlight_enable,
+       nv_set_backlight_level,
+};
+static int nv_set_backlight_init(void);
+static int nv_sleep_notify(struct notifier_block *self, unsigned long, void *);
+static struct notifier_block nv_nb = {
+       nv_sleep_notify, NULL, 0,
+};
+#endif
+
 static void offb_init_nodriver(struct device_node *);
 static void offb_init_fb(const char *name, const char *full_name,
                         int width, int height, int depth, int pitch,
@@ -537,8 +564,81 @@
                return;
        }
 
+#ifdef CONFIG_PMAC_BACKLIGHT
+       if (strncmp(name, "NVDA,", 5) == 0) {
+               nv_set_backlight_init();
+       }
+#endif
+
        printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
               info->node, full_name);
 }
 
+#ifdef CONFIG_PMAC_BACKLIGHT
+#define MMIO_BASE 0x91000000
+#define MMIO_SIZE 0x01000000
+
+static int nv_bk_level;
+
+volatile unsigned int *nv_mmio, *nv_pmc, *nv_pcrt;
+
+static int nv_set_backlight_enable(int on, int level, void *data)
+{
+       unsigned int tmp_pmc, tmp_pcrt;
+
+       tmp_pmc = nv_pmc[0x10F0/4] & 0x0000FFFF;
+       tmp_pcrt = nv_pcrt[0x081C/4];
+       nv_bk_level = level;
+       if (level == 0) { on = 0; }
+       if (on) {
+               tmp_pmc |= (1 << 31); // backlight bit
+               switch(level) {
+                       case 15:
+                               tmp_pmc |= 0x05340000; break;
+                       default:
+                               tmp_pmc |= (341 + (level * 53)) << 16;
+               }
+       } else {
+               tmp_pcrt &= 0xFFFFFFFC;
+       }
+       nv_pmc[0x10F0/4] = tmp_pmc;
+       nv_pcrt[0x081C/4] = tmp_pcrt;
+
+       return (0);
+}
+
+static int nv_set_backlight_init()
+{
+       nv_mmio = (unsigned int *)ioremap(MMIO_BASE, MMIO_SIZE);
+       if (!nv_mmio) {
+               printk("nv_backlight: cannot map memory map io\n");
+               return (-1);
+       }
+       nv_pmc          = nv_mmio + 0x00000000/4;
+       nv_pcrt         = nv_mmio + 0x00600000/4;
+
+       register_backlight_controller(&nv_backlight_controller, NULL, "mnca");
+
+       fb_register_client(&nv_nb);
+
+       return (0);
+}
+
+static int nv_sleep_notify(struct notifier_block *self, 
+                          unsigned long when, void *p)
+{
+       printk("nv_sleep_notify: ");
+       switch(when) {
+       case FB_EVENT_SUSPEND:
+               printk("sleep now\n");
+               break;
+       case FB_EVENT_RESUME:
+               printk("wakeup %d\n", nv_bk_level);
+               nv_set_backlight_enable(1, nv_bk_level, NULL);
+               break;
+       }
+       return PBOOK_SLEEP_OK;
+}
+#endif
+
 MODULE_LICENSE("GPL");

Reply via email to