[PATCH] powermac: Combined fixes for backlight code
This patch fixes several problems: - pmac_backlight_key() is called under interrupt context, and therefore can't use mutexes or semaphores, so defer the backlight level for later, as it's not critical (original code by Aristeu S. Rozanski F. <aris@valeta.org>). - Add exports for functions that might be called from modules - Fix Kconfig depdencies on PMAC_BACKLIGHT. - Fix locking issues on calls from inside the driver (reported by Aristeu S. Rozanski F., too) - Fix wrong calculation of backlight values in some of the drivers - Replace pmac_backlight_key_up/down by inline functions [akpm@osdl.org: fix function prototypes] Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch> Acked-by: Aristeu S. Rozanski F. <aris@valeta.org> Acked-by: Rene Nussbaumer <linux-kernel@killerfox.forkbomb.ch> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
58d383a622
commit
e01af0384f
10 changed files with 162 additions and 97 deletions
|
@ -15,6 +15,15 @@
|
||||||
|
|
||||||
#define OLD_BACKLIGHT_MAX 15
|
#define OLD_BACKLIGHT_MAX 15
|
||||||
|
|
||||||
|
static void pmac_backlight_key_worker(void *data);
|
||||||
|
static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL);
|
||||||
|
|
||||||
|
/* Although this variable is used in interrupt context, it makes no sense to
|
||||||
|
* protect it. No user is able to produce enough key events per second and
|
||||||
|
* notice the errors that might happen.
|
||||||
|
*/
|
||||||
|
static int pmac_backlight_key_queued;
|
||||||
|
|
||||||
/* Protect the pmac_backlight variable */
|
/* Protect the pmac_backlight variable */
|
||||||
DEFINE_MUTEX(pmac_backlight_mutex);
|
DEFINE_MUTEX(pmac_backlight_mutex);
|
||||||
|
|
||||||
|
@ -71,7 +80,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value)
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmac_backlight_key(int direction)
|
static void pmac_backlight_key_worker(void *data)
|
||||||
{
|
{
|
||||||
mutex_lock(&pmac_backlight_mutex);
|
mutex_lock(&pmac_backlight_mutex);
|
||||||
if (pmac_backlight) {
|
if (pmac_backlight) {
|
||||||
|
@ -82,7 +91,8 @@ static void pmac_backlight_key(int direction)
|
||||||
props = pmac_backlight->props;
|
props = pmac_backlight->props;
|
||||||
|
|
||||||
brightness = props->brightness +
|
brightness = props->brightness +
|
||||||
((direction?-1:1) * (props->max_brightness / 15));
|
((pmac_backlight_key_queued?-1:1) *
|
||||||
|
(props->max_brightness / 15));
|
||||||
|
|
||||||
if (brightness < 0)
|
if (brightness < 0)
|
||||||
brightness = 0;
|
brightness = 0;
|
||||||
|
@ -97,14 +107,13 @@ static void pmac_backlight_key(int direction)
|
||||||
mutex_unlock(&pmac_backlight_mutex);
|
mutex_unlock(&pmac_backlight_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pmac_backlight_key_up()
|
void pmac_backlight_key(int direction)
|
||||||
{
|
{
|
||||||
pmac_backlight_key(0);
|
/* we can receive multiple interrupts here, but the scheduled work
|
||||||
}
|
* will run only once, with the last value
|
||||||
|
*/
|
||||||
void pmac_backlight_key_down()
|
pmac_backlight_key_queued = direction;
|
||||||
{
|
schedule_work(&pmac_backlight_key_work);
|
||||||
pmac_backlight_key(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pmac_backlight_set_legacy_brightness(int brightness)
|
int pmac_backlight_set_legacy_brightness(int brightness)
|
||||||
|
@ -157,3 +166,7 @@ int pmac_backlight_get_legacy_brightness()
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL_GPL(pmac_backlight);
|
||||||
|
EXPORT_SYMBOL_GPL(pmac_backlight_mutex);
|
||||||
|
EXPORT_SYMBOL_GPL(pmac_has_backlight_type);
|
||||||
|
|
|
@ -113,7 +113,10 @@ config PMAC_MEDIABAY
|
||||||
|
|
||||||
config PMAC_BACKLIGHT
|
config PMAC_BACKLIGHT
|
||||||
bool "Backlight control for LCD screens"
|
bool "Backlight control for LCD screens"
|
||||||
depends on ADB_PMU && (BROKEN || !PPC64)
|
depends on ADB_PMU && FB = y && (BROKEN || !PPC64)
|
||||||
|
select FB_BACKLIGHT
|
||||||
|
select BACKLIGHT_CLASS_DEVICE
|
||||||
|
select BACKLIGHT_LCD_SUPPORT
|
||||||
help
|
help
|
||||||
Say Y here to enable Macintosh specific extensions of the generic
|
Say Y here to enable Macintosh specific extensions of the generic
|
||||||
backlight code. With this enabled, the brightness keys on older
|
backlight code. With this enabled, the brightness keys on older
|
||||||
|
|
|
@ -455,6 +455,7 @@ static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
|
||||||
static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
|
static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
|
||||||
static void wait_for_idle(struct aty128fb_par *par);
|
static void wait_for_idle(struct aty128fb_par *par);
|
||||||
static u32 depth_to_dst(u32 depth);
|
static u32 depth_to_dst(u32 depth);
|
||||||
|
static void aty128_bl_set_power(struct fb_info *info, int power);
|
||||||
|
|
||||||
#define BIOS_IN8(v) (readb(bios + (v)))
|
#define BIOS_IN8(v) (readb(bios + (v)))
|
||||||
#define BIOS_IN16(v) (readb(bios + (v)) | \
|
#define BIOS_IN16(v) (readb(bios + (v)) | \
|
||||||
|
@ -1257,25 +1258,11 @@ static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
|
||||||
reg &= ~LVDS_DISPLAY_DIS;
|
reg &= ~LVDS_DISPLAY_DIS;
|
||||||
aty_st_le32(LVDS_GEN_CNTL, reg);
|
aty_st_le32(LVDS_GEN_CNTL, reg);
|
||||||
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
||||||
mutex_lock(&info->bl_mutex);
|
aty128_bl_set_power(info, FB_BLANK_UNBLANK);
|
||||||
if (info->bl_dev) {
|
|
||||||
down(&info->bl_dev->sem);
|
|
||||||
info->bl_dev->props->update_status(info->bl_dev);
|
|
||||||
up(&info->bl_dev->sem);
|
|
||||||
}
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
||||||
mutex_lock(&info->bl_mutex);
|
aty128_bl_set_power(info, FB_BLANK_POWERDOWN);
|
||||||
if (info->bl_dev) {
|
|
||||||
down(&info->bl_dev->sem);
|
|
||||||
info->bl_dev->props->brightness = 0;
|
|
||||||
info->bl_dev->props->power = FB_BLANK_POWERDOWN;
|
|
||||||
info->bl_dev->props->update_status(info->bl_dev);
|
|
||||||
up(&info->bl_dev->sem);
|
|
||||||
}
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
#endif
|
#endif
|
||||||
reg = aty_ld_le32(LVDS_GEN_CNTL);
|
reg = aty_ld_le32(LVDS_GEN_CNTL);
|
||||||
reg |= LVDS_DISPLAY_DIS;
|
reg |= LVDS_DISPLAY_DIS;
|
||||||
|
@ -1702,6 +1689,7 @@ static int __devinit aty128fb_setup(char *options)
|
||||||
|
|
||||||
static struct backlight_properties aty128_bl_data;
|
static struct backlight_properties aty128_bl_data;
|
||||||
|
|
||||||
|
/* Call with fb_info->bl_mutex held */
|
||||||
static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
|
static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
|
@ -1709,10 +1697,8 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
|
||||||
int atylevel;
|
int atylevel;
|
||||||
|
|
||||||
/* Get and convert the value */
|
/* Get and convert the value */
|
||||||
mutex_lock(&info->bl_mutex);
|
|
||||||
atylevel = MAX_LEVEL -
|
atylevel = MAX_LEVEL -
|
||||||
(info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
|
(info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
|
|
||||||
if (atylevel < 0)
|
if (atylevel < 0)
|
||||||
atylevel = 0;
|
atylevel = 0;
|
||||||
|
@ -1730,7 +1716,8 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
|
||||||
/* That one prevents proper CRT output with LCD off */
|
/* That one prevents proper CRT output with LCD off */
|
||||||
#undef BACKLIGHT_DAC_OFF
|
#undef BACKLIGHT_DAC_OFF
|
||||||
|
|
||||||
static int aty128_bl_update_status(struct backlight_device *bd)
|
/* Call with fb_info->bl_mutex held */
|
||||||
|
static int __aty128_bl_update_status(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
|
struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
|
||||||
unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
|
unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
|
||||||
|
@ -1783,6 +1770,19 @@ static int aty128_bl_update_status(struct backlight_device *bd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int aty128_bl_update_status(struct backlight_device *bd)
|
||||||
|
{
|
||||||
|
struct aty128fb_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 = __aty128_bl_update_status(bd);
|
||||||
|
mutex_unlock(&info->bl_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int aty128_bl_get_brightness(struct backlight_device *bd)
|
static int aty128_bl_get_brightness(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
return bd->props->brightness;
|
return bd->props->brightness;
|
||||||
|
@ -1795,6 +1795,16 @@ static struct backlight_properties aty128_bl_data = {
|
||||||
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void aty128_bl_set_power(struct fb_info *info, int power)
|
||||||
|
{
|
||||||
|
mutex_lock(&info->bl_mutex);
|
||||||
|
up(&info->bl_dev->sem);
|
||||||
|
info->bl_dev->props->power = power;
|
||||||
|
__aty128_bl_update_status(info->bl_dev);
|
||||||
|
down(&info->bl_dev->sem);
|
||||||
|
mutex_unlock(&info->bl_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static void aty128_bl_init(struct aty128fb_par *par)
|
static void aty128_bl_init(struct aty128fb_par *par)
|
||||||
{
|
{
|
||||||
struct fb_info *info = pci_get_drvdata(par->pdev);
|
struct fb_info *info = pci_get_drvdata(par->pdev);
|
||||||
|
@ -2197,12 +2207,8 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
||||||
if (machine_is(powermac) && blank) {
|
if (machine_is(powermac) && blank)
|
||||||
down(&fb->bl_dev->sem);
|
aty128_bl_set_power(fb, FB_BLANK_POWERDOWN);
|
||||||
fb->bl_dev->props->power = FB_BLANK_POWERDOWN;
|
|
||||||
fb->bl_dev->props->update_status(fb->bl_dev);
|
|
||||||
up(&fb->bl_dev->sem);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (blank & FB_BLANK_VSYNC_SUSPEND)
|
if (blank & FB_BLANK_VSYNC_SUSPEND)
|
||||||
|
@ -2218,14 +2224,12 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
|
||||||
aty128_set_crt_enable(par, par->crt_on && !blank);
|
aty128_set_crt_enable(par, par->crt_on && !blank);
|
||||||
aty128_set_lcd_enable(par, par->lcd_on && !blank);
|
aty128_set_lcd_enable(par, par->lcd_on && !blank);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
||||||
if (machine_is(powermac) && !blank) {
|
if (machine_is(powermac) && !blank)
|
||||||
down(&fb->bl_dev->sem);
|
aty128_bl_set_power(fb, FB_BLANK_UNBLANK);
|
||||||
fb->bl_dev->props->power = FB_BLANK_UNBLANK;
|
|
||||||
fb->bl_dev->props->update_status(fb->bl_dev);
|
|
||||||
up(&fb->bl_dev->sem);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2129,15 +2129,14 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
|
||||||
|
|
||||||
static struct backlight_properties aty_bl_data;
|
static struct backlight_properties aty_bl_data;
|
||||||
|
|
||||||
|
/* Call with fb_info->bl_mutex held */
|
||||||
static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
|
static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
|
||||||
{
|
{
|
||||||
struct fb_info *info = pci_get_drvdata(par->pdev);
|
struct fb_info *info = pci_get_drvdata(par->pdev);
|
||||||
int atylevel;
|
int atylevel;
|
||||||
|
|
||||||
/* Get and convert the value */
|
/* Get and convert the value */
|
||||||
mutex_lock(&info->bl_mutex);
|
|
||||||
atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
|
atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
|
|
||||||
if (atylevel < 0)
|
if (atylevel < 0)
|
||||||
atylevel = 0;
|
atylevel = 0;
|
||||||
|
@ -2147,7 +2146,8 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
|
||||||
return atylevel;
|
return atylevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aty_bl_update_status(struct backlight_device *bd)
|
/* Call with fb_info->bl_mutex held */
|
||||||
|
static int __aty_bl_update_status(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
struct atyfb_par *par = class_get_devdata(&bd->class_dev);
|
struct atyfb_par *par = class_get_devdata(&bd->class_dev);
|
||||||
unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
|
unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
|
||||||
|
@ -2172,6 +2172,19 @@ static int aty_bl_update_status(struct backlight_device *bd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int aty_bl_update_status(struct backlight_device *bd)
|
||||||
|
{
|
||||||
|
struct atyfb_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 = __aty_bl_update_status(bd);
|
||||||
|
mutex_unlock(&info->bl_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int aty_bl_get_brightness(struct backlight_device *bd)
|
static int aty_bl_get_brightness(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
return bd->props->brightness;
|
return bd->props->brightness;
|
||||||
|
@ -2184,6 +2197,16 @@ static struct backlight_properties aty_bl_data = {
|
||||||
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void aty_bl_set_power(struct fb_info *info, int power)
|
||||||
|
{
|
||||||
|
mutex_lock(&info->bl_mutex);
|
||||||
|
up(&info->bl_dev->sem);
|
||||||
|
info->bl_dev->props->power = power;
|
||||||
|
__aty_bl_update_status(info->bl_dev);
|
||||||
|
down(&info->bl_dev->sem);
|
||||||
|
mutex_unlock(&info->bl_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static void aty_bl_init(struct atyfb_par *par)
|
static void aty_bl_init(struct atyfb_par *par)
|
||||||
{
|
{
|
||||||
struct fb_info *info = pci_get_drvdata(par->pdev);
|
struct fb_info *info = pci_get_drvdata(par->pdev);
|
||||||
|
@ -2790,16 +2813,8 @@ static int atyfb_blank(int blank, struct fb_info *info)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_PMAC_BACKLIGHT
|
#ifdef CONFIG_PMAC_BACKLIGHT
|
||||||
if (machine_is(powermac) && blank > FB_BLANK_NORMAL) {
|
if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
|
||||||
mutex_lock(&info->bl_mutex);
|
aty_bl_set_power(info, FB_BLANK_POWERDOWN);
|
||||||
if (info->bl_dev) {
|
|
||||||
down(&info->bl_dev->sem);
|
|
||||||
info->bl_dev->props->power = FB_BLANK_POWERDOWN;
|
|
||||||
info->bl_dev->props->update_status(info->bl_dev);
|
|
||||||
up(&info->bl_dev->sem);
|
|
||||||
}
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
}
|
|
||||||
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
|
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
|
||||||
if (par->lcd_table && blank > FB_BLANK_NORMAL &&
|
if (par->lcd_table && blank > FB_BLANK_NORMAL &&
|
||||||
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
|
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
|
||||||
|
@ -2830,16 +2845,8 @@ static int atyfb_blank(int blank, struct fb_info *info)
|
||||||
aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
|
aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
|
||||||
|
|
||||||
#ifdef CONFIG_PMAC_BACKLIGHT
|
#ifdef CONFIG_PMAC_BACKLIGHT
|
||||||
if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) {
|
if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
|
||||||
mutex_lock(&info->bl_mutex);
|
aty_bl_set_power(info, FB_BLANK_UNBLANK);
|
||||||
if (info->bl_dev) {
|
|
||||||
down(&info->bl_dev->sem);
|
|
||||||
info->bl_dev->props->power = FB_BLANK_UNBLANK;
|
|
||||||
info->bl_dev->props->update_status(info->bl_dev);
|
|
||||||
up(&info->bl_dev->sem);
|
|
||||||
}
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
}
|
|
||||||
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
|
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
|
||||||
if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
|
if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
|
||||||
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
|
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
|
||||||
|
|
|
@ -149,12 +149,11 @@ static int chipsfb_blank(int blank, struct fb_info *info)
|
||||||
mutex_lock(&pmac_backlight_mutex);
|
mutex_lock(&pmac_backlight_mutex);
|
||||||
|
|
||||||
if (pmac_backlight) {
|
if (pmac_backlight) {
|
||||||
down(&pmac_backlight->sem);
|
|
||||||
|
|
||||||
/* used to disable backlight only for blank > 1, but it seems
|
/* used to disable backlight only for blank > 1, but it seems
|
||||||
* useful at blank = 1 too (saves battery, extends backlight
|
* useful at blank = 1 too (saves battery, extends backlight
|
||||||
* life)
|
* life)
|
||||||
*/
|
*/
|
||||||
|
down(&pmac_backlight->sem);
|
||||||
if (blank)
|
if (blank)
|
||||||
pmac_backlight->props->power = FB_BLANK_POWERDOWN;
|
pmac_backlight->props->power = FB_BLANK_POWERDOWN;
|
||||||
else
|
else
|
||||||
|
|
|
@ -26,9 +26,11 @@
|
||||||
*/
|
*/
|
||||||
#define MIN_LEVEL 0x158
|
#define MIN_LEVEL 0x158
|
||||||
#define MAX_LEVEL 0x534
|
#define MAX_LEVEL 0x534
|
||||||
|
#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
|
||||||
|
|
||||||
static struct backlight_properties nvidia_bl_data;
|
static struct backlight_properties nvidia_bl_data;
|
||||||
|
|
||||||
|
/* Call with fb_info->bl_mutex held */
|
||||||
static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
|
static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
|
@ -36,9 +38,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
|
||||||
int nlevel;
|
int nlevel;
|
||||||
|
|
||||||
/* Get and convert the value */
|
/* Get and convert the value */
|
||||||
mutex_lock(&info->bl_mutex);
|
nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
|
||||||
nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
|
|
||||||
if (nlevel < 0)
|
if (nlevel < 0)
|
||||||
nlevel = 0;
|
nlevel = 0;
|
||||||
|
@ -50,7 +50,8 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
|
||||||
return nlevel;
|
return nlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nvidia_bl_update_status(struct backlight_device *bd)
|
/* Call with fb_info->bl_mutex held */
|
||||||
|
static int __nvidia_bl_update_status(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
struct nvidia_par *par = class_get_devdata(&bd->class_dev);
|
struct nvidia_par *par = class_get_devdata(&bd->class_dev);
|
||||||
u32 tmp_pcrt, tmp_pmc, fpcontrol;
|
u32 tmp_pcrt, tmp_pmc, fpcontrol;
|
||||||
|
@ -84,6 +85,19 @@ static int nvidia_bl_update_status(struct backlight_device *bd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nvidia_bl_update_status(struct backlight_device *bd)
|
||||||
|
{
|
||||||
|
struct nvidia_par *par = class_get_devdata(&bd->class_dev);
|
||||||
|
struct fb_info *info = pci_get_drvdata(par->pci_dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&info->bl_mutex);
|
||||||
|
ret = __nvidia_bl_update_status(bd);
|
||||||
|
mutex_unlock(&info->bl_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int nvidia_bl_get_brightness(struct backlight_device *bd)
|
static int nvidia_bl_get_brightness(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
return bd->props->brightness;
|
return bd->props->brightness;
|
||||||
|
@ -96,6 +110,16 @@ static struct backlight_properties nvidia_bl_data = {
|
||||||
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void nvidia_bl_set_power(struct fb_info *info, int power)
|
||||||
|
{
|
||||||
|
mutex_lock(&info->bl_mutex);
|
||||||
|
up(&info->bl_dev->sem);
|
||||||
|
info->bl_dev->props->power = power;
|
||||||
|
__nvidia_bl_update_status(info->bl_dev);
|
||||||
|
down(&info->bl_dev->sem);
|
||||||
|
mutex_unlock(&info->bl_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
void nvidia_bl_init(struct nvidia_par *par)
|
void nvidia_bl_init(struct nvidia_par *par)
|
||||||
{
|
{
|
||||||
struct fb_info *info = pci_get_drvdata(par->pci_dev);
|
struct fb_info *info = pci_get_drvdata(par->pci_dev);
|
||||||
|
|
|
@ -68,9 +68,11 @@ extern u8 byte_rev[256];
|
||||||
#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
|
#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
|
||||||
extern void nvidia_bl_init(struct nvidia_par *par);
|
extern void nvidia_bl_init(struct nvidia_par *par);
|
||||||
extern void nvidia_bl_exit(struct nvidia_par *par);
|
extern void nvidia_bl_exit(struct nvidia_par *par);
|
||||||
|
extern void nvidia_bl_set_power(struct fb_info *info, int power);
|
||||||
#else
|
#else
|
||||||
static inline void nvidia_bl_init(struct nvidia_par *par) {}
|
static inline void nvidia_bl_init(struct nvidia_par *par) {}
|
||||||
static inline void nvidia_bl_exit(struct nvidia_par *par) {}
|
static inline void nvidia_bl_exit(struct nvidia_par *par) {}
|
||||||
|
static inline void nvidia_bl_set_power(struct fb_info *info, int power) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __NV_PROTO_H__ */
|
#endif /* __NV_PROTO_H__ */
|
||||||
|
|
|
@ -932,16 +932,7 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
|
||||||
NVWriteSeq(par, 0x01, tmp);
|
NVWriteSeq(par, 0x01, tmp);
|
||||||
NVWriteCrtc(par, 0x1a, vesa);
|
NVWriteCrtc(par, 0x1a, vesa);
|
||||||
|
|
||||||
#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
|
nvidia_bl_set_power(info, blank);
|
||||||
mutex_lock(&info->bl_mutex);
|
|
||||||
if (info->bl_dev) {
|
|
||||||
down(&info->bl_dev->sem);
|
|
||||||
info->bl_dev->props->power = blank;
|
|
||||||
info->bl_dev->props->update_status(info->bl_dev);
|
|
||||||
up(&info->bl_dev->sem);
|
|
||||||
}
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NVTRACE_LEAVE();
|
NVTRACE_LEAVE();
|
||||||
|
|
||||||
|
|
|
@ -277,9 +277,11 @@ static const struct riva_regs reg_template = {
|
||||||
*/
|
*/
|
||||||
#define MIN_LEVEL 0x158
|
#define MIN_LEVEL 0x158
|
||||||
#define MAX_LEVEL 0x534
|
#define MAX_LEVEL 0x534
|
||||||
|
#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
|
||||||
|
|
||||||
static struct backlight_properties riva_bl_data;
|
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,
|
static int riva_bl_get_level_brightness(struct riva_par *par,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
|
@ -287,9 +289,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
|
||||||
int nlevel;
|
int nlevel;
|
||||||
|
|
||||||
/* Get and convert the value */
|
/* Get and convert the value */
|
||||||
mutex_lock(&info->bl_mutex);
|
nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
|
||||||
nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
|
|
||||||
if (nlevel < 0)
|
if (nlevel < 0)
|
||||||
nlevel = 0;
|
nlevel = 0;
|
||||||
|
@ -301,7 +301,8 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
|
||||||
return nlevel;
|
return nlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int riva_bl_update_status(struct backlight_device *bd)
|
/* 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);
|
struct riva_par *par = class_get_devdata(&bd->class_dev);
|
||||||
U032 tmp_pcrt, tmp_pmc;
|
U032 tmp_pcrt, tmp_pmc;
|
||||||
|
@ -326,6 +327,19 @@ static int riva_bl_update_status(struct backlight_device *bd)
|
||||||
return 0;
|
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)
|
static int riva_bl_get_brightness(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
return bd->props->brightness;
|
return bd->props->brightness;
|
||||||
|
@ -338,6 +352,16 @@ static struct backlight_properties riva_bl_data = {
|
||||||
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void riva_bl_set_power(struct fb_info *info, int power)
|
||||||
|
{
|
||||||
|
mutex_lock(&info->bl_mutex);
|
||||||
|
up(&info->bl_dev->sem);
|
||||||
|
info->bl_dev->props->power = power;
|
||||||
|
__riva_bl_update_status(info->bl_dev);
|
||||||
|
down(&info->bl_dev->sem);
|
||||||
|
mutex_unlock(&info->bl_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static void riva_bl_init(struct riva_par *par)
|
static void riva_bl_init(struct riva_par *par)
|
||||||
{
|
{
|
||||||
struct fb_info *info = pci_get_drvdata(par->pdev);
|
struct fb_info *info = pci_get_drvdata(par->pdev);
|
||||||
|
@ -418,6 +442,7 @@ static void riva_bl_exit(struct riva_par *par)
|
||||||
#else
|
#else
|
||||||
static inline void riva_bl_init(struct riva_par *par) {}
|
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_exit(struct riva_par *par) {}
|
||||||
|
static inline void riva_bl_set_power(struct fb_info *info, int power) {}
|
||||||
#endif /* CONFIG_FB_RIVA_BACKLIGHT */
|
#endif /* CONFIG_FB_RIVA_BACKLIGHT */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- *
|
/* ------------------------------------------------------------------------- *
|
||||||
|
@ -1336,16 +1361,7 @@ static int rivafb_blank(int blank, struct fb_info *info)
|
||||||
SEQout(par, 0x01, tmp);
|
SEQout(par, 0x01, tmp);
|
||||||
CRTCout(par, 0x1a, vesa);
|
CRTCout(par, 0x1a, vesa);
|
||||||
|
|
||||||
#ifdef CONFIG_FB_RIVA_BACKLIGHT
|
riva_bl_set_power(info, blank);
|
||||||
mutex_lock(&info->bl_mutex);
|
|
||||||
if (info->bl_dev) {
|
|
||||||
down(&info->bl_dev->sem);
|
|
||||||
info->bl_dev->props->power = blank;
|
|
||||||
info->bl_dev->props->update_status(info->bl_dev);
|
|
||||||
up(&info->bl_dev->sem);
|
|
||||||
}
|
|
||||||
mutex_unlock(&info->bl_mutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NVTRACE_LEAVE();
|
NVTRACE_LEAVE();
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,19 @@
|
||||||
extern struct backlight_device *pmac_backlight;
|
extern struct backlight_device *pmac_backlight;
|
||||||
extern struct mutex pmac_backlight_mutex;
|
extern struct mutex pmac_backlight_mutex;
|
||||||
|
|
||||||
extern void pmac_backlight_calc_curve(struct fb_info*);
|
|
||||||
extern int pmac_backlight_curve_lookup(struct fb_info *info, int value);
|
extern int pmac_backlight_curve_lookup(struct fb_info *info, int value);
|
||||||
|
|
||||||
extern int pmac_has_backlight_type(const char *type);
|
extern int pmac_has_backlight_type(const char *type);
|
||||||
|
|
||||||
extern void pmac_backlight_key_up(void);
|
extern void pmac_backlight_key(int direction);
|
||||||
extern void pmac_backlight_key_down(void);
|
static inline void pmac_backlight_key_up(void)
|
||||||
|
{
|
||||||
|
pmac_backlight_key(0);
|
||||||
|
}
|
||||||
|
static inline void pmac_backlight_key_down(void)
|
||||||
|
{
|
||||||
|
pmac_backlight_key(1);
|
||||||
|
}
|
||||||
|
|
||||||
extern int pmac_backlight_set_legacy_brightness(int brightness);
|
extern int pmac_backlight_set_legacy_brightness(int brightness);
|
||||||
extern int pmac_backlight_get_legacy_brightness(void);
|
extern int pmac_backlight_get_legacy_brightness(void);
|
||||||
|
|
Loading…
Reference in a new issue