2 * Backlight code for nVidia based graphic cards
4 * Copyright 2004 Antonino Daplas <adaplas@pol.net>
5 * Copyright (c) 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/backlight.h>
14 #include <linux/pci.h>
19 /* We do not have any information about which values are allowed, thus
20 * we used safe values.
22 #define MIN_LEVEL 0x158
23 #define MAX_LEVEL 0x534
24 #define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
26 static int nvidia_bl_get_level_brightness(struct nvidia_par
*par
,
29 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
32 /* Get and convert the value */
33 /* No locking of bl_curve since we read a single value */
34 nlevel
= MIN_LEVEL
+ info
->bl_curve
[level
] * LEVEL_STEP
;
38 else if (nlevel
< MIN_LEVEL
)
40 else if (nlevel
> MAX_LEVEL
)
46 static int nvidia_bl_update_status(struct backlight_device
*bd
)
48 struct nvidia_par
*par
= class_get_devdata(&bd
->class_dev
);
49 u32 tmp_pcrt
, tmp_pmc
, fpcontrol
;
55 if (bd
->props
.power
!= FB_BLANK_UNBLANK
||
56 bd
->props
.fb_blank
!= FB_BLANK_UNBLANK
)
59 level
= bd
->props
.brightness
;
61 tmp_pmc
= NV_RD32(par
->PMC
, 0x10F0) & 0x0000FFFF;
62 tmp_pcrt
= NV_RD32(par
->PCRTC0
, 0x081C) & 0xFFFFFFFC;
63 fpcontrol
= NV_RD32(par
->PRAMDAC
, 0x0848) & 0xCFFFFFCC;
67 tmp_pmc
|= (1 << 31); /* backlight bit */
68 tmp_pmc
|= nvidia_bl_get_level_brightness(par
, level
) << 16;
69 fpcontrol
|= par
->fpSyncs
;
71 fpcontrol
|= 0x20000022;
73 NV_WR32(par
->PCRTC0
, 0x081C, tmp_pcrt
);
74 NV_WR32(par
->PMC
, 0x10F0, tmp_pmc
);
75 NV_WR32(par
->PRAMDAC
, 0x848, fpcontrol
);
80 static int nvidia_bl_get_brightness(struct backlight_device
*bd
)
82 return bd
->props
.brightness
;
85 static struct backlight_ops nvidia_bl_ops
= {
86 .get_brightness
= nvidia_bl_get_brightness
,
87 .update_status
= nvidia_bl_update_status
,
90 void nvidia_bl_init(struct nvidia_par
*par
)
92 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
93 struct backlight_device
*bd
;
99 #ifdef CONFIG_PMAC_BACKLIGHT
100 if (!machine_is(powermac
) ||
101 !pmac_has_backlight_type("mnca"))
105 snprintf(name
, sizeof(name
), "nvidiabl%d", info
->node
);
107 bd
= backlight_device_register(name
, info
->dev
, par
, &nvidia_bl_ops
);
110 printk(KERN_WARNING
"nvidia: Backlight registration failed\n");
115 fb_bl_default_curve(info
, 0,
116 0x158 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
,
117 0x534 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
);
119 bd
->props
.max_brightness
= FB_BACKLIGHT_LEVELS
- 1;
120 bd
->props
.brightness
= bd
->props
.max_brightness
;
121 bd
->props
.power
= FB_BLANK_UNBLANK
;
122 backlight_update_status(bd
);
124 printk("nvidia: Backlight initialized (%s)\n", name
);
132 void nvidia_bl_exit(struct nvidia_par
*par
)
134 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
135 struct backlight_device
*bd
= info
->bl_dev
;
137 backlight_device_unregister(bd
);
138 printk("nvidia: Backlight unloaded\n");