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 struct backlight_properties nvidia_bl_data
;
28 static int nvidia_bl_get_level_brightness(struct nvidia_par
*par
,
31 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
34 /* Get and convert the value */
35 /* No locking of bl_curve since we read a single value */
36 nlevel
= MIN_LEVEL
+ info
->bl_curve
[level
] * LEVEL_STEP
;
40 else if (nlevel
< MIN_LEVEL
)
42 else if (nlevel
> MAX_LEVEL
)
48 static int nvidia_bl_update_status(struct backlight_device
*bd
)
50 struct nvidia_par
*par
= class_get_devdata(&bd
->class_dev
);
51 u32 tmp_pcrt
, tmp_pmc
, fpcontrol
;
57 if (bd
->props
.power
!= FB_BLANK_UNBLANK
||
58 bd
->props
.fb_blank
!= FB_BLANK_UNBLANK
)
61 level
= bd
->props
.brightness
;
63 tmp_pmc
= NV_RD32(par
->PMC
, 0x10F0) & 0x0000FFFF;
64 tmp_pcrt
= NV_RD32(par
->PCRTC0
, 0x081C) & 0xFFFFFFFC;
65 fpcontrol
= NV_RD32(par
->PRAMDAC
, 0x0848) & 0xCFFFFFCC;
69 tmp_pmc
|= (1 << 31); /* backlight bit */
70 tmp_pmc
|= nvidia_bl_get_level_brightness(par
, level
) << 16;
71 fpcontrol
|= par
->fpSyncs
;
73 fpcontrol
|= 0x20000022;
75 NV_WR32(par
->PCRTC0
, 0x081C, tmp_pcrt
);
76 NV_WR32(par
->PMC
, 0x10F0, tmp_pmc
);
77 NV_WR32(par
->PRAMDAC
, 0x848, fpcontrol
);
82 static int nvidia_bl_get_brightness(struct backlight_device
*bd
)
84 return bd
->props
.brightness
;
87 static struct backlight_ops nvidia_bl_ops
= {
88 .get_brightness
= nvidia_bl_get_brightness
,
89 .update_status
= nvidia_bl_update_status
,
92 void nvidia_bl_init(struct nvidia_par
*par
)
94 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
95 struct backlight_device
*bd
;
101 #ifdef CONFIG_PMAC_BACKLIGHT
102 if (!machine_is(powermac
) ||
103 !pmac_has_backlight_type("mnca"))
107 snprintf(name
, sizeof(name
), "nvidiabl%d", info
->node
);
109 bd
= backlight_device_register(name
, info
->dev
, par
, &nvidia_bl_ops
);
112 printk(KERN_WARNING
"nvidia: Backlight registration failed\n");
117 fb_bl_default_curve(info
, 0,
118 0x158 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
,
119 0x534 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
);
121 bd
->props
.max_brightness
= FB_BACKLIGHT_LEVELS
- 1;
122 bd
->props
.brightness
= nvidia_bl_data
.max_brightness
;
123 bd
->props
.power
= FB_BLANK_UNBLANK
;
124 backlight_update_status(bd
);
126 printk("nvidia: Backlight initialized (%s)\n", name
);
134 void nvidia_bl_exit(struct nvidia_par
*par
)
136 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
137 struct backlight_device
*bd
= info
->bl_dev
;
139 backlight_device_unregister(bd
);
140 printk("nvidia: Backlight unloaded\n");