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 #ifdef CONFIG_PMAC_BACKLIGHT
20 #include <asm/backlight.h>
21 #include <asm/machdep.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
30 static struct backlight_properties nvidia_bl_data
;
32 static int nvidia_bl_get_level_brightness(struct nvidia_par
*par
,
35 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
38 /* Get and convert the value */
39 mutex_lock(&info
->bl_mutex
);
40 nlevel
= info
->bl_curve
[level
] * FB_BACKLIGHT_MAX
/ MAX_LEVEL
;
41 mutex_unlock(&info
->bl_mutex
);
45 else if (nlevel
< MIN_LEVEL
)
47 else if (nlevel
> MAX_LEVEL
)
53 static int nvidia_bl_update_status(struct backlight_device
*bd
)
55 struct nvidia_par
*par
= class_get_devdata(&bd
->class_dev
);
56 u32 tmp_pcrt
, tmp_pmc
, fpcontrol
;
62 if (bd
->props
->power
!= FB_BLANK_UNBLANK
||
63 bd
->props
->fb_blank
!= FB_BLANK_UNBLANK
)
66 level
= bd
->props
->brightness
;
68 tmp_pmc
= NV_RD32(par
->PMC
, 0x10F0) & 0x0000FFFF;
69 tmp_pcrt
= NV_RD32(par
->PCRTC0
, 0x081C) & 0xFFFFFFFC;
70 fpcontrol
= NV_RD32(par
->PRAMDAC
, 0x0848) & 0xCFFFFFCC;
74 tmp_pmc
|= (1 << 31); /* backlight bit */
75 tmp_pmc
|= nvidia_bl_get_level_brightness(par
, level
) << 16;
76 fpcontrol
|= par
->fpSyncs
;
78 fpcontrol
|= 0x20000022;
80 NV_WR32(par
->PCRTC0
, 0x081C, tmp_pcrt
);
81 NV_WR32(par
->PMC
, 0x10F0, tmp_pmc
);
82 NV_WR32(par
->PRAMDAC
, 0x848, fpcontrol
);
87 static int nvidia_bl_get_brightness(struct backlight_device
*bd
)
89 return bd
->props
->brightness
;
92 static struct backlight_properties nvidia_bl_data
= {
94 .get_brightness
= nvidia_bl_get_brightness
,
95 .update_status
= nvidia_bl_update_status
,
96 .max_brightness
= (FB_BACKLIGHT_LEVELS
- 1),
99 void nvidia_bl_init(struct nvidia_par
*par
)
101 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
102 struct backlight_device
*bd
;
108 #ifdef CONFIG_PMAC_BACKLIGHT
109 if (!machine_is(powermac
) ||
110 !pmac_has_backlight_type("mnca"))
114 snprintf(name
, sizeof(name
), "nvidiabl%d", info
->node
);
116 bd
= backlight_device_register(name
, par
, &nvidia_bl_data
);
119 printk("nvidia: Backlight registration failed\n");
123 mutex_lock(&info
->bl_mutex
);
125 fb_bl_default_curve(info
, 0,
126 0x158 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
,
127 0x534 * FB_BACKLIGHT_MAX
/ MAX_LEVEL
);
128 mutex_unlock(&info
->bl_mutex
);
131 bd
->props
->brightness
= nvidia_bl_data
.max_brightness
;
132 bd
->props
->power
= FB_BLANK_UNBLANK
;
133 bd
->props
->update_status(bd
);
136 #ifdef CONFIG_PMAC_BACKLIGHT
137 mutex_lock(&pmac_backlight_mutex
);
140 mutex_unlock(&pmac_backlight_mutex
);
143 printk("nvidia: Backlight initialized (%s)\n", name
);
151 void nvidia_bl_exit(struct nvidia_par
*par
)
153 struct fb_info
*info
= pci_get_drvdata(par
->pci_dev
);
155 #ifdef CONFIG_PMAC_BACKLIGHT
156 mutex_lock(&pmac_backlight_mutex
);
159 mutex_lock(&info
->bl_mutex
);
161 #ifdef CONFIG_PMAC_BACKLIGHT
162 if (pmac_backlight
== info
->bl_dev
)
163 pmac_backlight
= NULL
;
166 backlight_device_unregister(info
->bl_dev
);
168 printk("nvidia: Backlight unloaded\n");
170 mutex_unlock(&info
->bl_mutex
);
172 #ifdef CONFIG_PMAC_BACKLIGHT
173 mutex_unlock(&pmac_backlight_mutex
);