2008-10-21 02:35:40 +04:00
/*
* Backlight Driver for the KB3886 Backlight
*
* Copyright ( c ) 2007 - 2008 Claudio Nieder
*
* Based on corgi_bl . c by Richard Purdie and kb3886 driver by Robert Woerle
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/platform_device.h>
# include <linux/mutex.h>
# include <linux/fb.h>
# include <linux/backlight.h>
# include <linux/delay.h>
# include <linux/dmi.h>
# define KB3886_PARENT 0x64
# define KB3886_IO 0x60
# define KB3886_ADC_DAC_PWM 0xC4
# define KB3886_PWM0_WRITE 0x81
# define KB3886_PWM0_READ 0x41
static DEFINE_MUTEX ( bl_mutex ) ;
static void kb3886_bl_set_intensity ( int intensity )
{
mutex_lock ( & bl_mutex ) ;
intensity = intensity & 0xff ;
outb ( KB3886_ADC_DAC_PWM , KB3886_PARENT ) ;
2012-10-05 04:12:47 +04:00
usleep_range ( 10000 , 11000 ) ;
2008-10-21 02:35:40 +04:00
outb ( KB3886_PWM0_WRITE , KB3886_IO ) ;
2012-10-05 04:12:47 +04:00
usleep_range ( 10000 , 11000 ) ;
2008-10-21 02:35:40 +04:00
outb ( intensity , KB3886_IO ) ;
mutex_unlock ( & bl_mutex ) ;
}
struct kb3886bl_machinfo {
int max_intensity ;
int default_intensity ;
int limit_mask ;
void ( * set_bl_intensity ) ( int intensity ) ;
} ;
static struct kb3886bl_machinfo kb3886_bl_machinfo = {
. max_intensity = 0xff ,
. default_intensity = 0xa0 ,
. limit_mask = 0x7f ,
. set_bl_intensity = kb3886_bl_set_intensity ,
} ;
static struct platform_device kb3886bl_device = {
. name = " kb3886-bl " ,
. dev = {
. platform_data = & kb3886_bl_machinfo ,
} ,
. id = - 1 ,
} ;
static struct platform_device * devices [ ] __initdata = {
& kb3886bl_device ,
} ;
/*
* Back to driver
*/
static int kb3886bl_intensity ;
static struct backlight_device * kb3886_backlight_device ;
static struct kb3886bl_machinfo * bl_machinfo ;
static unsigned long kb3886bl_flags ;
# define KB3886BL_SUSPENDED 0x01
static struct dmi_system_id __initdata kb3886bl_device_table [ ] = {
{
. ident = " Sahara Touch-iT " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " SDV " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " iTouch T201 " ) ,
} ,
} ,
{ }
} ;
static int kb3886bl_send_intensity ( struct backlight_device * bd )
{
int intensity = bd - > props . brightness ;
if ( bd - > props . power ! = FB_BLANK_UNBLANK )
intensity = 0 ;
if ( bd - > props . fb_blank ! = FB_BLANK_UNBLANK )
intensity = 0 ;
if ( kb3886bl_flags & KB3886BL_SUSPENDED )
intensity = 0 ;
bl_machinfo - > set_bl_intensity ( intensity ) ;
kb3886bl_intensity = intensity ;
return 0 ;
}
2013-04-30 03:17:43 +04:00
# ifdef CONFIG_PM_SLEEP
static int kb3886bl_suspend ( struct device * dev )
2008-10-21 02:35:40 +04:00
{
2013-04-30 03:17:43 +04:00
struct backlight_device * bd = dev_get_drvdata ( dev ) ;
2008-10-21 02:35:40 +04:00
kb3886bl_flags | = KB3886BL_SUSPENDED ;
backlight_update_status ( bd ) ;
return 0 ;
}
2013-04-30 03:17:43 +04:00
static int kb3886bl_resume ( struct device * dev )
2008-10-21 02:35:40 +04:00
{
2013-04-30 03:17:43 +04:00
struct backlight_device * bd = dev_get_drvdata ( dev ) ;
2008-10-21 02:35:40 +04:00
kb3886bl_flags & = ~ KB3886BL_SUSPENDED ;
backlight_update_status ( bd ) ;
return 0 ;
}
# endif
2013-04-30 03:17:43 +04:00
static SIMPLE_DEV_PM_OPS ( kb3886bl_pm_ops , kb3886bl_suspend , kb3886bl_resume ) ;
2008-10-21 02:35:40 +04:00
static int kb3886bl_get_intensity ( struct backlight_device * bd )
{
return kb3886bl_intensity ;
}
2009-12-14 02:58:57 +03:00
static const struct backlight_ops kb3886bl_ops = {
2008-10-21 02:35:40 +04:00
. get_brightness = kb3886bl_get_intensity ,
. update_status = kb3886bl_send_intensity ,
} ;
static int kb3886bl_probe ( struct platform_device * pdev )
{
2010-02-18 00:39:44 +03:00
struct backlight_properties props ;
2013-11-13 03:09:04 +04:00
struct kb3886bl_machinfo * machinfo = dev_get_platdata ( & pdev - > dev ) ;
2008-10-21 02:35:40 +04:00
bl_machinfo = machinfo ;
if ( ! machinfo - > limit_mask )
machinfo - > limit_mask = - 1 ;
2010-02-18 00:39:44 +03:00
memset ( & props , 0 , sizeof ( struct backlight_properties ) ) ;
2011-03-23 02:30:21 +03:00
props . type = BACKLIGHT_RAW ;
2010-02-18 00:39:44 +03:00
props . max_brightness = machinfo - > max_intensity ;
2013-11-13 03:09:17 +04:00
kb3886_backlight_device = devm_backlight_device_register ( & pdev - > dev ,
" kb3886-bl " , & pdev - > dev ,
NULL , & kb3886bl_ops ,
& props ) ;
2008-10-21 02:35:40 +04:00
if ( IS_ERR ( kb3886_backlight_device ) )
return PTR_ERR ( kb3886_backlight_device ) ;
platform_set_drvdata ( pdev , kb3886_backlight_device ) ;
kb3886_backlight_device - > props . power = FB_BLANK_UNBLANK ;
kb3886_backlight_device - > props . brightness = machinfo - > default_intensity ;
backlight_update_status ( kb3886_backlight_device ) ;
return 0 ;
}
static struct platform_driver kb3886bl_driver = {
. probe = kb3886bl_probe ,
. driver = {
. name = " kb3886-bl " ,
2013-04-30 03:17:43 +04:00
. pm = & kb3886bl_pm_ops ,
2008-10-21 02:35:40 +04:00
} ,
} ;
static int __init kb3886_init ( void )
{
if ( ! dmi_check_system ( kb3886bl_device_table ) )
return - ENODEV ;
platform_add_devices ( devices , ARRAY_SIZE ( devices ) ) ;
return platform_driver_register ( & kb3886bl_driver ) ;
}
static void __exit kb3886_exit ( void )
{
platform_driver_unregister ( & kb3886bl_driver ) ;
}
module_init ( kb3886_init ) ;
module_exit ( kb3886_exit ) ;
MODULE_AUTHOR ( " Claudio Nieder <private@claudio.ch> " ) ;
MODULE_DESCRIPTION ( " Tabletkiosk Sahara Touch-iT Backlight Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " dmi:*:svnSDV:pniTouchT201:* " ) ;