2006-02-01 14:06:53 +03:00
/*
* Backlight Driver for HP Jornada 680
*
* Copyright ( c ) 2005 Andriy Skulysh
*
* Based on Sharp ' s Corgi Backlight Driver
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
2006-03-31 14:31:50 +04:00
# include <linux/platform_device.h>
2006-02-01 14:06:53 +03:00
# include <linux/spinlock.h>
# include <linux/fb.h>
# include <linux/backlight.h>
2008-07-29 21:16:12 +04:00
# include <cpu/dac.h>
2008-10-20 08:02:48 +04:00
# include <mach/hp6xx.h>
2006-09-27 11:09:59 +04:00
# include <asm/hd64461.h>
2006-02-01 14:06:53 +03:00
# define HP680_MAX_INTENSITY 255
# define HP680_DEFAULT_INTENSITY 10
2006-03-31 14:31:50 +04:00
static int hp680bl_suspended ;
2006-02-01 14:06:53 +03:00
static int current_intensity = 0 ;
2006-06-27 13:53:55 +04:00
static DEFINE_SPINLOCK ( bl_lock ) ;
2006-02-01 14:06:53 +03:00
2006-03-31 14:31:50 +04:00
static void hp680bl_send_intensity ( struct backlight_device * bd )
2006-02-01 14:06:53 +03:00
{
unsigned long flags ;
2006-03-31 14:31:50 +04:00
u16 v ;
2007-02-11 02:07:48 +03:00
int intensity = bd - > props . brightness ;
2006-02-01 14:06:53 +03:00
2007-02-11 02:07:48 +03:00
if ( bd - > props . power ! = FB_BLANK_UNBLANK )
2006-03-31 14:31:50 +04:00
intensity = 0 ;
2007-02-11 02:07:48 +03:00
if ( bd - > props . fb_blank ! = FB_BLANK_UNBLANK )
2006-03-31 14:31:50 +04:00
intensity = 0 ;
if ( hp680bl_suspended )
2006-02-01 14:06:53 +03:00
intensity = 0 ;
spin_lock_irqsave ( & bl_lock , flags ) ;
2006-03-31 14:31:50 +04:00
if ( intensity & & current_intensity = = 0 ) {
sh_dac_enable ( DAC_LCD_BRIGHTNESS ) ;
v = inw ( HD64461_GPBDR ) ;
v & = ~ HD64461_GPBDR_LCDOFF ;
outw ( v , HD64461_GPBDR ) ;
sh_dac_output ( 255 - ( u8 ) intensity , DAC_LCD_BRIGHTNESS ) ;
} else if ( intensity = = 0 & & current_intensity ! = 0 ) {
sh_dac_output ( 255 - ( u8 ) intensity , DAC_LCD_BRIGHTNESS ) ;
sh_dac_disable ( DAC_LCD_BRIGHTNESS ) ;
v = inw ( HD64461_GPBDR ) ;
v | = HD64461_GPBDR_LCDOFF ;
outw ( v , HD64461_GPBDR ) ;
} else if ( intensity ) {
sh_dac_output ( 255 - ( u8 ) intensity , DAC_LCD_BRIGHTNESS ) ;
}
2006-02-01 14:06:53 +03:00
spin_unlock_irqrestore ( & bl_lock , flags ) ;
2006-03-31 14:31:50 +04:00
current_intensity = intensity ;
2006-02-01 14:06:53 +03:00
}
2006-03-31 14:31:50 +04:00
2006-02-01 14:06:53 +03:00
# ifdef CONFIG_PM
2007-02-08 03:33:24 +03:00
static int hp680bl_suspend ( struct platform_device * pdev , pm_message_t state )
2006-02-01 14:06:53 +03:00
{
2007-02-08 03:33:24 +03:00
struct backlight_device * bd = platform_get_drvdata ( pdev ) ;
2006-03-31 14:31:50 +04:00
hp680bl_suspended = 1 ;
2007-02-08 03:33:24 +03:00
hp680bl_send_intensity ( bd ) ;
2006-02-01 14:06:53 +03:00
return 0 ;
}
2007-02-08 03:33:24 +03:00
static int hp680bl_resume ( struct platform_device * pdev )
2006-02-01 14:06:53 +03:00
{
2007-02-08 03:33:24 +03:00
struct backlight_device * bd = platform_get_drvdata ( pdev ) ;
2006-03-31 14:31:50 +04:00
hp680bl_suspended = 0 ;
2007-02-08 03:33:24 +03:00
hp680bl_send_intensity ( bd ) ;
2006-02-01 14:06:53 +03:00
return 0 ;
}
# else
# define hp680bl_suspend NULL
# define hp680bl_resume NULL
# endif
2006-03-31 14:31:50 +04:00
static int hp680bl_set_intensity ( struct backlight_device * bd )
2006-02-01 14:06:53 +03:00
{
2006-03-31 14:31:50 +04:00
hp680bl_send_intensity ( bd ) ;
2006-02-01 14:06:53 +03:00
return 0 ;
}
static int hp680bl_get_intensity ( struct backlight_device * bd )
{
return current_intensity ;
}
2009-12-14 02:58:57 +03:00
static const struct backlight_ops hp680bl_ops = {
2006-02-01 14:06:53 +03:00
. get_brightness = hp680bl_get_intensity ,
2006-03-31 14:31:50 +04:00
. update_status = hp680bl_set_intensity ,
2006-02-01 14:06:53 +03:00
} ;
2009-07-12 00:52:44 +04:00
static int __devinit hp680bl_probe ( struct platform_device * pdev )
2006-02-01 14:06:53 +03:00
{
2010-02-18 00:39:44 +03:00
struct backlight_properties props ;
2007-02-08 03:33:24 +03:00
struct backlight_device * bd ;
2010-02-18 00:39:44 +03:00
memset ( & props , 0 , sizeof ( struct backlight_properties ) ) ;
props . max_brightness = HP680_MAX_INTENSITY ;
bd = backlight_device_register ( " hp680-bl " , & pdev - > dev , NULL ,
& hp680bl_ops , & props ) ;
2007-02-08 03:33:24 +03:00
if ( IS_ERR ( bd ) )
return PTR_ERR ( bd ) ;
2006-02-01 14:06:53 +03:00
2007-02-08 03:33:24 +03:00
platform_set_drvdata ( pdev , bd ) ;
2007-02-11 02:07:48 +03:00
bd - > props . brightness = HP680_DEFAULT_INTENSITY ;
2007-02-08 03:33:24 +03:00
hp680bl_send_intensity ( bd ) ;
2006-02-01 14:06:53 +03:00
return 0 ;
}
2007-02-08 03:33:24 +03:00
static int hp680bl_remove ( struct platform_device * pdev )
2006-02-01 14:06:53 +03:00
{
2007-02-08 03:33:24 +03:00
struct backlight_device * bd = platform_get_drvdata ( pdev ) ;
2007-09-11 07:44:38 +04:00
bd - > props . brightness = 0 ;
bd - > props . power = 0 ;
2007-02-08 03:33:24 +03:00
hp680bl_send_intensity ( bd ) ;
2006-12-08 13:40:49 +03:00
2007-02-08 03:33:24 +03:00
backlight_device_unregister ( bd ) ;
2006-02-01 14:06:53 +03:00
return 0 ;
}
2006-03-31 14:31:50 +04:00
static struct platform_driver hp680bl_driver = {
2006-02-01 14:06:53 +03:00
. probe = hp680bl_probe ,
. remove = hp680bl_remove ,
. suspend = hp680bl_suspend ,
. resume = hp680bl_resume ,
2006-03-31 14:31:50 +04:00
. driver = {
. name = " hp680-bl " ,
} ,
2006-02-01 14:06:53 +03:00
} ;
2006-03-31 14:31:50 +04:00
static struct platform_device * hp680bl_device ;
2006-02-01 14:06:53 +03:00
static int __init hp680bl_init ( void )
{
int ret ;
2006-03-31 14:31:50 +04:00
ret = platform_driver_register ( & hp680bl_driver ) ;
2008-11-17 18:16:20 +03:00
if ( ret )
return ret ;
hp680bl_device = platform_device_register_simple ( " hp680-bl " , - 1 ,
NULL , 0 ) ;
if ( IS_ERR ( hp680bl_device ) ) {
platform_driver_unregister ( & hp680bl_driver ) ;
return PTR_ERR ( hp680bl_device ) ;
2006-02-01 14:06:53 +03:00
}
2008-11-17 18:16:20 +03:00
return 0 ;
2006-02-01 14:06:53 +03:00
}
static void __exit hp680bl_exit ( void )
{
2006-03-31 14:31:50 +04:00
platform_device_unregister ( hp680bl_device ) ;
platform_driver_unregister ( & hp680bl_driver ) ;
2006-02-01 14:06:53 +03:00
}
module_init ( hp680bl_init ) ;
module_exit ( hp680bl_exit ) ;
2006-09-27 11:09:59 +04:00
MODULE_AUTHOR ( " Andriy Skulysh <askulysh@gmail.com> " ) ;
2006-02-01 14:06:53 +03:00
MODULE_DESCRIPTION ( " HP Jornada 680 Backlight Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;