X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fbacklight%2Fcorgi_bl.c;h=2ebbfd95145fd34587cbd715b2d59048c283abfb;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=353cb3f73cf2f6267dbaf2a8a625d261742828ce;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 353cb3f73..2ebbfd951 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c @@ -1,7 +1,7 @@ /* - * Backlight Driver for Sharp Corgi + * Backlight Driver for Sharp Zaurus Handhelds (various models) * - * Copyright (c) 2004-2005 Richard Purdie + * Copyright (c) 2004-2006 Richard Purdie * * Based on Sharp's 2.4 Backlight Driver * @@ -14,84 +14,64 @@ #include #include #include -#include -#include +#include +#include #include #include +#include +#include -#include -#include - -#define CORGI_MAX_INTENSITY 0x3e -#define CORGI_DEFAULT_INTENSITY 0x1f -#define CORGI_LIMIT_MASK 0x0b +static int corgibl_intensity; +static DEFINE_MUTEX(bl_mutex); +static struct backlight_properties corgibl_data; +static struct backlight_device *corgi_backlight_device; +static struct corgibl_machinfo *bl_machinfo; -static int corgibl_powermode = FB_BLANK_UNBLANK; -static int current_intensity = 0; -static int corgibl_limit = 0; -static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static unsigned long corgibl_flags; +#define CORGIBL_SUSPENDED 0x01 +#define CORGIBL_BATTLOW 0x02 -static void corgibl_send_intensity(int intensity) +static int corgibl_send_intensity(struct backlight_device *bd) { - unsigned long flags; void (*corgi_kick_batt)(void); + int intensity = bd->props->brightness; - if (corgibl_powermode != FB_BLANK_UNBLANK) { + if (bd->props->power != FB_BLANK_UNBLANK) intensity = 0; - } else { - if (corgibl_limit) - intensity &= CORGI_LIMIT_MASK; - } - - /* Skip 0x20 as it will blank the display */ - if (intensity >= 0x20) - intensity++; - - spin_lock_irqsave(&bl_lock, flags); - /* Bits 0-4 are accessed via the SSP interface */ - corgi_ssp_blduty_set(intensity & 0x1f); - /* Bit 5 is via SCOOP */ - if (intensity & 0x0020) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT); - spin_unlock_irqrestore(&bl_lock, flags); -} + if (bd->props->fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + if (corgibl_flags & CORGIBL_SUSPENDED) + intensity = 0; + if (corgibl_flags & CORGIBL_BATTLOW) + intensity &= bl_machinfo->limit_mask; -static void corgibl_blank(int blank) -{ - switch(blank) { - - case FB_BLANK_NORMAL: - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_POWERDOWN: - if (corgibl_powermode == FB_BLANK_UNBLANK) { - corgibl_send_intensity(0); - corgibl_powermode = blank; - } - break; - case FB_BLANK_UNBLANK: - if (corgibl_powermode != FB_BLANK_UNBLANK) { - corgibl_powermode = blank; - corgibl_send_intensity(current_intensity); - } - break; - } + mutex_lock(&bl_mutex); + bl_machinfo->set_bl_intensity(intensity); + mutex_unlock(&bl_mutex); + + corgibl_intensity = intensity; + + corgi_kick_batt = symbol_get(sharpsl_battery_kick); + if (corgi_kick_batt) { + corgi_kick_batt(); + symbol_put(sharpsl_battery_kick); + } + + return 0; } #ifdef CONFIG_PM -static int corgibl_suspend(struct device *dev, pm_message_t state, u32 level) +static int corgibl_suspend(struct platform_device *dev, pm_message_t state) { - if (level == SUSPEND_POWER_DOWN) - corgibl_blank(FB_BLANK_POWERDOWN); + corgibl_flags |= CORGIBL_SUSPENDED; + corgibl_send_intensity(corgi_backlight_device); return 0; } -static int corgibl_resume(struct device *dev, u32 level) +static int corgibl_resume(struct platform_device *dev) { - if (level == RESUME_POWER_ON) - corgibl_blank(FB_BLANK_UNBLANK); + corgibl_flags &= ~CORGIBL_SUSPENDED; + corgibl_send_intensity(corgi_backlight_device); return 0; } #else @@ -99,95 +79,86 @@ static int corgibl_resume(struct device *dev, u32 level) #define corgibl_resume NULL #endif - -static int corgibl_set_power(struct backlight_device *bd, int state) -{ - corgibl_blank(state); - return 0; -} - -static int corgibl_get_power(struct backlight_device *bd) +static int corgibl_get_intensity(struct backlight_device *bd) { - return corgibl_powermode; + return corgibl_intensity; } -static int corgibl_set_intensity(struct backlight_device *bd, int intensity) +static int corgibl_set_intensity(struct backlight_device *bd) { - if (intensity > CORGI_MAX_INTENSITY) - intensity = CORGI_MAX_INTENSITY; - corgibl_send_intensity(intensity); - current_intensity=intensity; + corgibl_send_intensity(corgi_backlight_device); return 0; } -static int corgibl_get_intensity(struct backlight_device *bd) -{ - return current_intensity; -} - /* * Called when the battery is low to limit the backlight intensity. * If limit==0 clear any limit, otherwise limit the intensity */ void corgibl_limit_intensity(int limit) { - corgibl_limit = (limit ? 1 : 0); - corgibl_send_intensity(current_intensity); + if (limit) + corgibl_flags |= CORGIBL_BATTLOW; + else + corgibl_flags &= ~CORGIBL_BATTLOW; + corgibl_send_intensity(corgi_backlight_device); } EXPORT_SYMBOL(corgibl_limit_intensity); static struct backlight_properties corgibl_data = { - .owner = THIS_MODULE, - .get_power = corgibl_get_power, - .set_power = corgibl_set_power, - .max_brightness = CORGI_MAX_INTENSITY, + .owner = THIS_MODULE, .get_brightness = corgibl_get_intensity, - .set_brightness = corgibl_set_intensity, + .update_status = corgibl_set_intensity, }; -static struct backlight_device *corgi_backlight_device; - -static int __init corgibl_probe(struct device *dev) +static int __init corgibl_probe(struct platform_device *pdev) { + struct corgibl_machinfo *machinfo = pdev->dev.platform_data; + + bl_machinfo = machinfo; + corgibl_data.max_brightness = machinfo->max_intensity; + if (!machinfo->limit_mask) + machinfo->limit_mask = -1; + corgi_backlight_device = backlight_device_register ("corgi-bl", NULL, &corgibl_data); if (IS_ERR (corgi_backlight_device)) return PTR_ERR (corgi_backlight_device); - corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); + corgibl_data.power = FB_BLANK_UNBLANK; + corgibl_data.brightness = machinfo->default_intensity; + corgibl_send_intensity(corgi_backlight_device); printk("Corgi Backlight Driver Initialized.\n"); return 0; } -static int corgibl_remove(struct device *dev) +static int corgibl_remove(struct platform_device *dev) { backlight_device_unregister(corgi_backlight_device); - corgibl_set_intensity(NULL, 0); - printk("Corgi Backlight Driver Unloaded\n"); return 0; } -static struct device_driver corgibl_driver = { - .name = "corgi-bl", - .bus = &platform_bus_type, +static struct platform_driver corgibl_driver = { .probe = corgibl_probe, .remove = corgibl_remove, .suspend = corgibl_suspend, .resume = corgibl_resume, + .driver = { + .name = "corgi-bl", + }, }; static int __init corgibl_init(void) { - return driver_register(&corgibl_driver); + return platform_driver_register(&corgibl_driver); } static void __exit corgibl_exit(void) { - driver_unregister(&corgibl_driver); + platform_driver_unregister(&corgibl_driver); } module_init(corgibl_init);