2019-05-29 17:12:31 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2005-09-07 02:16:45 +04:00
/*
* Backlight control code for Sharp Zaurus SL - 5500
*
* Copyright 2005 John Lenz < lenz @ cs . wisc . edu >
2010-07-18 16:27:13 +04:00
* Maintainer : Pavel Machek < pavel @ ucw . cz > ( unless John wants to : - )
2005-09-07 02:16:45 +04:00
*
* This driver assumes single CPU . That ' s okay , because collie is
2011-03-31 05:57:33 +04:00
* slightly old hardware , and no one is going to retrofit second CPU to
2005-09-07 02:16:45 +04:00
* old PDA .
*/
/* LCD power functions */
# include <linux/module.h>
# include <linux/init.h>
# include <linux/delay.h>
# include <linux/device.h>
# include <linux/interrupt.h>
2006-06-26 11:26:27 +04:00
# include <linux/fb.h>
# include <linux/backlight.h>
2005-09-07 02:16:45 +04:00
# include <asm/hardware/locomo.h>
# include <asm/irq.h>
2006-03-25 14:07:33 +03:00
# include <asm/mach/sharpsl_param.h>
# include <asm/mach-types.h>
2005-09-07 02:16:45 +04:00
2006-03-25 14:07:33 +03:00
# include "../../../arch/arm/mach-sa1100/generic.h"
2005-09-07 02:16:45 +04:00
2006-06-26 11:26:27 +04:00
static struct backlight_device * locomolcd_bl_device ;
2005-09-07 02:16:45 +04:00
static struct locomo_dev * locomolcd_dev ;
2006-06-26 11:26:27 +04:00
static unsigned long locomolcd_flags ;
# define LOCOMOLCD_SUSPENDED 0x01
2005-09-07 02:16:45 +04:00
static void locomolcd_on ( int comadj )
{
2006-09-25 23:11:48 +04:00
locomo_gpio_set_dir ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VSHA_ON , 0 ) ;
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VSHA_ON , 1 ) ;
2005-09-07 02:16:45 +04:00
mdelay ( 2 ) ;
2006-09-25 23:11:48 +04:00
locomo_gpio_set_dir ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VSHD_ON , 0 ) ;
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VSHD_ON , 1 ) ;
2005-09-07 02:16:45 +04:00
mdelay ( 2 ) ;
locomo_m62332_senddata ( locomolcd_dev , comadj , 0 ) ;
mdelay ( 5 ) ;
2006-09-25 23:11:48 +04:00
locomo_gpio_set_dir ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VEE_ON , 0 ) ;
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VEE_ON , 1 ) ;
2005-09-07 02:16:45 +04:00
mdelay ( 10 ) ;
/* TFTCRST | CPSOUT=0 | CPSEN */
locomo_writel ( 0x01 , locomolcd_dev - > mapbase + LOCOMO_TC ) ;
/* Set CPSD */
locomo_writel ( 6 , locomolcd_dev - > mapbase + LOCOMO_CPSD ) ;
/* TFTCRST | CPSOUT=0 | CPSEN */
locomo_writel ( ( 0x04 | 0x01 ) , locomolcd_dev - > mapbase + LOCOMO_TC ) ;
mdelay ( 10 ) ;
2006-09-25 23:11:48 +04:00
locomo_gpio_set_dir ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_MOD , 0 ) ;
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_MOD , 1 ) ;
2005-09-07 02:16:45 +04:00
}
static void locomolcd_off ( int comadj )
{
/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
locomo_writel ( 0x06 , locomolcd_dev - > mapbase + LOCOMO_TC ) ;
mdelay ( 1 ) ;
2006-09-25 23:11:48 +04:00
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VSHA_ON , 0 ) ;
2005-09-07 02:16:45 +04:00
mdelay ( 110 ) ;
2006-09-25 23:11:48 +04:00
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VEE_ON , 0 ) ;
2005-09-07 02:16:45 +04:00
mdelay ( 700 ) ;
/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
locomo_writel ( 0 , locomolcd_dev - > mapbase + LOCOMO_TC ) ;
2006-09-25 23:11:48 +04:00
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_MOD , 0 ) ;
locomo_gpio_write ( locomolcd_dev - > dev . parent , LOCOMO_GPIO_LCD_VSHD_ON , 0 ) ;
2005-09-07 02:16:45 +04:00
}
void locomolcd_power ( int on )
{
2006-03-25 14:07:33 +03:00
int comadj = sharpsl_param . comadj ;
2005-09-07 02:16:45 +04:00
unsigned long flags ;
local_irq_save ( flags ) ;
if ( ! locomolcd_dev ) {
local_irq_restore ( flags ) ;
return ;
}
/* read comadj */
2006-06-26 11:26:27 +04:00
if ( comadj = = - 1 & & machine_is_collie ( ) )
comadj = 128 ;
2005-09-07 02:16:45 +04:00
if ( on )
locomolcd_on ( comadj ) ;
else
locomolcd_off ( comadj ) ;
local_irq_restore ( flags ) ;
}
EXPORT_SYMBOL ( locomolcd_power ) ;
2006-06-26 11:26:27 +04:00
static int current_intensity ;
static int locomolcd_set_intensity ( struct backlight_device * bd )
{
2020-07-19 11:07:41 +03:00
int intensity = backlight_get_brightness ( bd ) ;
2006-06-26 11:26:27 +04:00
if ( locomolcd_flags & LOCOMOLCD_SUSPENDED )
intensity = 0 ;
switch ( intensity ) {
2012-12-19 02:21:18 +04:00
/*
* AC and non - AC are handled differently ,
* but produce same results in sharp code ?
*/
case 0 :
locomo_frontlight_set ( locomolcd_dev , 0 , 0 , 161 ) ;
break ;
case 1 :
locomo_frontlight_set ( locomolcd_dev , 117 , 0 , 161 ) ;
break ;
case 2 :
locomo_frontlight_set ( locomolcd_dev , 163 , 0 , 148 ) ;
break ;
case 3 :
locomo_frontlight_set ( locomolcd_dev , 194 , 0 , 161 ) ;
break ;
case 4 :
locomo_frontlight_set ( locomolcd_dev , 194 , 1 , 161 ) ;
break ;
2006-06-26 11:26:27 +04:00
default :
return - ENODEV ;
}
current_intensity = intensity ;
return 0 ;
}
static int locomolcd_get_intensity ( struct backlight_device * bd )
{
return current_intensity ;
}
2009-12-14 02:58:57 +03:00
static const struct backlight_ops locomobl_data = {
2006-06-26 11:26:27 +04:00
. get_brightness = locomolcd_get_intensity ,
. update_status = locomolcd_set_intensity ,
} ;
2013-04-30 03:17:45 +04:00
# ifdef CONFIG_PM_SLEEP
static int locomolcd_suspend ( struct device * dev )
2006-06-26 11:26:27 +04:00
{
locomolcd_flags | = LOCOMOLCD_SUSPENDED ;
locomolcd_set_intensity ( locomolcd_bl_device ) ;
return 0 ;
}
2013-04-30 03:17:45 +04:00
static int locomolcd_resume ( struct device * dev )
2006-06-26 11:26:27 +04:00
{
locomolcd_flags & = ~ LOCOMOLCD_SUSPENDED ;
locomolcd_set_intensity ( locomolcd_bl_device ) ;
return 0 ;
}
# endif
2013-04-30 03:17:45 +04:00
static SIMPLE_DEV_PM_OPS ( locomolcd_pm_ops , locomolcd_suspend , locomolcd_resume ) ;
2006-09-25 23:11:48 +04:00
static int locomolcd_probe ( struct locomo_dev * ldev )
2005-09-07 02:16:45 +04:00
{
2010-02-18 00:39:44 +03:00
struct backlight_properties props ;
2005-09-07 02:16:45 +04:00
unsigned long flags ;
local_irq_save ( flags ) ;
2006-09-25 23:11:48 +04:00
locomolcd_dev = ldev ;
2005-09-07 02:16:45 +04:00
2006-09-25 23:11:48 +04:00
locomo_gpio_set_dir ( ldev - > dev . parent , LOCOMO_GPIO_FL_VR , 0 ) ;
2006-06-26 11:26:27 +04:00
2005-09-07 02:16:45 +04:00
local_irq_restore ( flags ) ;
2006-06-26 11:26:27 +04:00
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 = 4 ;
locomolcd_bl_device = backlight_device_register ( " locomo-bl " ,
& ldev - > dev , NULL ,
& locomobl_data , & props ) ;
2006-06-26 11:26:27 +04:00
2012-12-19 02:21:18 +04:00
if ( IS_ERR ( locomolcd_bl_device ) )
return PTR_ERR ( locomolcd_bl_device ) ;
2006-06-26 11:26:27 +04:00
/* Set up frontlight so that screen is readable */
2007-02-11 02:07:48 +03:00
locomolcd_bl_device - > props . brightness = 2 ;
2006-06-26 11:26:27 +04:00
locomolcd_set_intensity ( locomolcd_bl_device ) ;
2005-09-07 02:16:45 +04:00
return 0 ;
}
2021-01-14 19:40:06 +03:00
static void locomolcd_remove ( struct locomo_dev * dev )
2005-09-07 02:16:45 +04:00
{
unsigned long flags ;
2006-06-26 11:26:27 +04:00
2007-03-07 02:29:33 +03:00
locomolcd_bl_device - > props . brightness = 0 ;
locomolcd_bl_device - > props . power = 0 ;
2006-12-08 13:40:49 +03:00
locomolcd_set_intensity ( locomolcd_bl_device ) ;
2006-06-26 11:26:27 +04:00
backlight_device_unregister ( locomolcd_bl_device ) ;
2005-09-07 02:16:45 +04:00
local_irq_save ( flags ) ;
locomolcd_dev = NULL ;
local_irq_restore ( flags ) ;
}
static struct locomo_driver poodle_lcd_driver = {
. drv = {
2013-04-30 03:17:45 +04:00
. name = " locomo-backlight " ,
. pm = & locomolcd_pm_ops ,
2005-09-07 02:16:45 +04:00
} ,
. devid = LOCOMO_DEVID_BACKLIGHT ,
2006-06-26 11:26:27 +04:00
. probe = locomolcd_probe ,
. remove = locomolcd_remove ,
2005-09-07 02:16:45 +04:00
} ;
2006-06-26 11:26:27 +04:00
static int __init locomolcd_init ( void )
2005-09-07 02:16:45 +04:00
{
2012-04-03 02:17:17 +04:00
return locomo_driver_register ( & poodle_lcd_driver ) ;
2005-09-07 02:16:45 +04:00
}
2006-06-26 11:26:27 +04:00
static void __exit locomolcd_exit ( void )
{
locomo_driver_unregister ( & poodle_lcd_driver ) ;
}
module_init ( locomolcd_init ) ;
module_exit ( locomolcd_exit ) ;
2010-07-18 16:27:13 +04:00
MODULE_AUTHOR ( " John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz> " ) ;
2006-06-26 11:26:27 +04:00
MODULE_DESCRIPTION ( " Collie LCD driver " ) ;
MODULE_LICENSE ( " GPL " ) ;