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>
16 #ifdef CONFIG_PMAC_BACKLIGHT
17 #include <asm/backlight.h>
24 /* We do not have any information about which values are allowed, thus
25 * we used safe values.
27 #define MIN_LEVEL 0x158
28 #define MAX_LEVEL 0x534
29 #define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
31 static int nvidia_bl_get_level_brightness(struct nvidia_par
*par
,
34 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
37 /* Get and convert the value */
38 /* No locking of bl_curve since we read a single value */
39 nlevel
= MIN_LEVEL
+ info
->bl_curve
[level
] * LEVEL_STEP
;
43 else if (nlevel
< MIN_LEVEL
)
45 else if (nlevel
> MAX_LEVEL
)
51 static int nvidia_bl_update_status(struct backlight_device
*bd
)
53 struct nvidia_par
*par
= bl_get_data(bd
);
54 u32 tmp_pcrt
, tmp_pmc
, fpcontrol
;
60 if (bd
->props
.power
!= FB_BLANK_UNBLANK
||
61 bd
->props
.fb_blank
!= FB_BLANK_UNBLANK
)
64 level
= bd
->props
.brightness
;
66 tmp_pmc
= NV_RD32(par
->PMC
, 0x10F0) & 0x0000FFFF;
67 tmp_pcrt
= NV_RD32(par
->PCRTC0
, 0x081C) & 0xFFFFFFFC;
68 fpcontrol
= NV_RD32(par
->PRAMDAC
, 0x0848) & 0xCFFFFFCC;
72 tmp_pmc
|= (1 << 31); /* backlight bit */
73 tmp_pmc
|= nvidia_bl_get_level_brightness(par
, level
) << 16;
74 fpcontrol
|= par
->fpSyncs
;
76 fpcontrol
|= 0x20000022;
78 NV_WR32(par
->PCRTC0
, 0x081C, tmp_pcrt
);
79 NV_WR32(par
->PMC
, 0x10F0, tmp_pmc
);
80 NV_WR32(par
->PRAMDAC
, 0x848, fpcontrol
);
85 static int nvidia_bl_get_brightness(struct backlight_device
*bd
)
87 return bd
->props
.brightness
;
90 static const struct backlight_ops nvidia_bl_ops
= {
91 .get_brightness
= nvidia_bl_get_brightness
,
92 .update_status
= nvidia_bl_update_status
,
95 void nvidia_bl_init(struct nvidia_par
*par
)
97 struct backlight_properties props
;
98 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
99 struct backlight_device
*bd
;
105 #ifdef CONFIG_PMAC_BACKLIGHT
106 if (!machine_is(powermac
) ||
107 !pmac_has_backlight_type("mnca"))
111 snprintf(name
, sizeof(name
), "nvidiabl%d", info
->node
);
113 memset(&props
, 0, sizeof(struct backlight_properties
));
114 props
.type
= BACKLIGHT_RAW
;
115 props
.max_brightness
= FB_BACKLIGHT_LEVELS
- 1;
116 bd
= backlight_device_register(name
, info
->dev
, par
, &nvidia_bl_ops
,
120 printk(KERN_WARNING
"nvidia: Backlight registration failed\n");
125 fb_bl_default_curve(info
, 0,
126 0x158 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
,
127 0x534 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
);
129 bd
->props
.brightness
= bd
->props
.max_brightness
;
130 bd
->props
.power
= FB_BLANK_UNBLANK
;
131 backlight_update_status(bd
);
133 printk("nvidia: Backlight initialized (%s)\n", name
);
141 void nvidia_bl_exit(struct nvidia_par
*par
)
143 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
144 struct backlight_device
*bd
= info
->bl_dev
;
146 backlight_device_unregister(bd
);
147 printk("nvidia: Backlight unloaded\n");