X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fvideo%2Friva%2Ffbdev.c;fp=drivers%2Fvideo%2Friva%2Ffbdev.c;h=6c19ab6afb015f8dc371689c1c91f7d1b0f4ba73;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=8ddb47a56b07a23cf9429d2f21f68814c34070ee;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 8ddb47a56..6c19ab6af 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -29,17 +29,18 @@ * doublescan modes are broken */ +#include #include #include #include #include #include +#include #include #include #include #include #include -#include #ifdef CONFIG_MTRR #include #endif @@ -48,7 +49,6 @@ #include #endif #ifdef CONFIG_PMAC_BACKLIGHT -#include #include #endif @@ -271,183 +271,34 @@ static const struct riva_regs reg_template = { /* * Backlight control */ -#ifdef CONFIG_FB_RIVA_BACKLIGHT -/* We do not have any information about which values are allowed, thus - * we used safe values. - */ -#define MIN_LEVEL 0x158 -#define MAX_LEVEL 0x534 -#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX) - -static struct backlight_properties riva_bl_data; - -/* Call with fb_info->bl_mutex held */ -static int riva_bl_get_level_brightness(struct riva_par *par, - int level) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - int nlevel; - - /* Get and convert the value */ - nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; - - if (nlevel < 0) - nlevel = 0; - else if (nlevel < MIN_LEVEL) - nlevel = MIN_LEVEL; - else if (nlevel > MAX_LEVEL) - nlevel = MAX_LEVEL; - - return nlevel; -} - -/* Call with fb_info->bl_mutex held */ -static int __riva_bl_update_status(struct backlight_device *bd) -{ - struct riva_par *par = class_get_devdata(&bd->class_dev); - U032 tmp_pcrt, tmp_pmc; - int level; - - if (bd->props->power != FB_BLANK_UNBLANK || - bd->props->fb_blank != FB_BLANK_UNBLANK) - level = 0; - else - level = bd->props->brightness; - - tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; - tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC; - if(level > 0) { - tmp_pcrt |= 0x1; - tmp_pmc |= (1 << 31); /* backlight bit */ - tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */ - } - par->riva.PCRTC0[0x081C/4] = tmp_pcrt; - par->riva.PMC[0x10F0/4] = tmp_pmc; - - return 0; -} - -static int riva_bl_update_status(struct backlight_device *bd) -{ - struct riva_par *par = class_get_devdata(&bd->class_dev); - struct fb_info *info = pci_get_drvdata(par->pdev); - int ret; - - mutex_lock(&info->bl_mutex); - ret = __riva_bl_update_status(bd); - mutex_unlock(&info->bl_mutex); - - return ret; -} - -static int riva_bl_get_brightness(struct backlight_device *bd) -{ - return bd->props->brightness; -} - -static struct backlight_properties riva_bl_data = { - .owner = THIS_MODULE, - .get_brightness = riva_bl_get_brightness, - .update_status = riva_bl_update_status, - .max_brightness = (FB_BACKLIGHT_LEVELS - 1), -}; - -static void riva_bl_set_power(struct fb_info *info, int power) -{ - mutex_lock(&info->bl_mutex); - - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->power = power; - __riva_bl_update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - - mutex_unlock(&info->bl_mutex); -} - -static void riva_bl_init(struct riva_par *par) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - struct backlight_device *bd; - char name[12]; - - if (!par->FlatPanel) - return; - #ifdef CONFIG_PMAC_BACKLIGHT - if (!machine_is(powermac) || - !pmac_has_backlight_type("mnca")) - return; -#endif - - snprintf(name, sizeof(name), "rivabl%d", info->node); - bd = backlight_device_register(name, par, &riva_bl_data); - if (IS_ERR(bd)) { - info->bl_dev = NULL; - printk(KERN_WARNING "riva: Backlight registration failed\n"); - goto error; - } - - mutex_lock(&info->bl_mutex); - info->bl_dev = bd; - fb_bl_default_curve(info, 0, - 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, - 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); - mutex_unlock(&info->bl_mutex); - - down(&bd->sem); - bd->props->brightness = riva_bl_data.max_brightness; - bd->props->power = FB_BLANK_UNBLANK; - bd->props->update_status(bd); - up(&bd->sem); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); - if (!pmac_backlight) - pmac_backlight = bd; - mutex_unlock(&pmac_backlight_mutex); -#endif - - printk("riva: Backlight initialized (%s)\n", name); - - return; - -error: - return; -} - -static void riva_bl_exit(struct riva_par *par) -{ - struct fb_info *info = pci_get_drvdata(par->pdev); - -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_lock(&pmac_backlight_mutex); -#endif - - mutex_lock(&info->bl_mutex); - if (info->bl_dev) { -#ifdef CONFIG_PMAC_BACKLIGHT - if (pmac_backlight == info->bl_dev) - pmac_backlight = NULL; -#endif - - backlight_device_unregister(info->bl_dev); - - printk("riva: Backlight unloaded\n"); - } - mutex_unlock(&info->bl_mutex); +static int riva_backlight_levels[] = { + 0x158, + 0x192, + 0x1c6, + 0x200, + 0x234, + 0x268, + 0x2a2, + 0x2d6, + 0x310, + 0x344, + 0x378, + 0x3b2, + 0x3e6, + 0x41a, + 0x454, + 0x534, +}; -#ifdef CONFIG_PMAC_BACKLIGHT - mutex_unlock(&pmac_backlight_mutex); -#endif -} -#else -static inline void riva_bl_init(struct riva_par *par) {} -static inline void riva_bl_exit(struct riva_par *par) {} -static inline void riva_bl_set_power(struct fb_info *info, int power) {} -#endif /* CONFIG_FB_RIVA_BACKLIGHT */ +static int riva_set_backlight_enable(int on, int level, void *data); +static int riva_set_backlight_level(int level, void *data); +static struct backlight_controller riva_backlight_controller = { + riva_set_backlight_enable, + riva_set_backlight_level +}; +#endif /* CONFIG_PMAC_BACKLIGHT */ /* ------------------------------------------------------------------------- * * @@ -1119,6 +970,36 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var) return rc; } +/* ------------------------------------------------------------------------- * + * + * Backlight operations + * + * ------------------------------------------------------------------------- */ + +#ifdef CONFIG_PMAC_BACKLIGHT +static int riva_set_backlight_enable(int on, int level, void *data) +{ + struct riva_par *par = data; + U032 tmp_pcrt, tmp_pmc; + + tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; + tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC; + if(on && (level > BACKLIGHT_OFF)) { + tmp_pcrt |= 0x1; + tmp_pmc |= (1 << 31); // backlight bit + tmp_pmc |= riva_backlight_levels[level-1] << 16; // level + } + par->riva.PCRTC0[0x081C/4] = tmp_pcrt; + par->riva.PMC[0x10F0/4] = tmp_pmc; + return 0; +} + +static int riva_set_backlight_level(int level, void *data) +{ + return riva_set_backlight_enable(1, level, data); +} +#endif /* CONFIG_PMAC_BACKLIGHT */ + /* ------------------------------------------------------------------------- * * * framebuffer operations @@ -1365,7 +1246,11 @@ static int rivafb_blank(int blank, struct fb_info *info) SEQout(par, 0x01, tmp); CRTCout(par, 0x1a, vesa); - riva_bl_set_power(info, blank); +#ifdef CONFIG_PMAC_BACKLIGHT + if ( par->FlatPanel && _machine == _MACH_Pmac) { + set_backlight_enable(!blank); + } +#endif NVTRACE_LEAVE(); @@ -2136,9 +2021,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd, fb_destroy_modedb(info->monspecs.modedb); info->monspecs.modedb = NULL; - - pci_set_drvdata(pd, info); - riva_bl_init(info->par); ret = register_framebuffer(info); if (ret < 0) { printk(KERN_ERR PFX @@ -2146,13 +2028,19 @@ static int __devinit rivafb_probe(struct pci_dev *pd, goto err_iounmap_screen_base; } + pci_set_drvdata(pd, info); + printk(KERN_INFO PFX "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n", info->fix.id, RIVAFB_VERSION, info->fix.smem_len / (1024 * 1024), info->fix.smem_start); - +#ifdef CONFIG_PMAC_BACKLIGHT + if (default_par->FlatPanel && _machine == _MACH_Pmac) + register_backlight_controller(&riva_backlight_controller, + default_par, "mnca"); +#endif NVTRACE_LEAVE(); return 0; @@ -2169,6 +2057,7 @@ err_iounmap_ctrl_base: err_release_region: pci_release_regions(pd); err_disable_device: + pci_disable_device(pd); err_free_pixmap: kfree(info->pixmap.addr); err_framebuffer_release: @@ -2183,8 +2072,8 @@ static void __exit rivafb_remove(struct pci_dev *pd) struct riva_par *par = info->par; NVTRACE_ENTER(); - - riva_bl_exit(par); + if (!info) + return; #ifdef CONFIG_FB_RIVA_I2C riva_delete_i2c_busses(par); @@ -2203,6 +2092,7 @@ static void __exit rivafb_remove(struct pci_dev *pd) if (par->riva.Architecture == NV_ARCH_03) iounmap(par->riva.PRAMIN); pci_release_regions(pd); + pci_disable_device(pd); kfree(info->pixmap.addr); framebuffer_release(info); pci_set_drvdata(pd, NULL);