Skip to content

Commit

Permalink
[PATCH] backlight: LOCOMO Backlight Driver updates
Browse files Browse the repository at this point in the history
Add backlight intensity control to the LOCOMO lcd/backlight driver using the
backlight class and add basic power management support.

This is a reimplementation and improvement of patches by John Lenz and Pavel
Machek

Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Richard Purdie authored and Linus Torvalds committed Jun 26, 2006
1 parent f8020dc commit e442378
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 37 deletions.
45 changes: 25 additions & 20 deletions arch/arm/common/locomo.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,21 +629,6 @@ static int locomo_resume(struct platform_device *dev)
#endif


#define LCM_ALC_EN 0x8000

void frontlight_set(struct locomo *lchip, int duty, int vr, int bpwf)
{
unsigned long flags;

spin_lock_irqsave(&lchip->lock, flags);
locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
udelay(100);
locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
locomo_writel(bpwf | LCM_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
spin_unlock_irqrestore(&lchip->lock, flags);
}


/**
* locomo_probe - probe for a single LoCoMo chip.
* @phys_addr: physical address of device.
Expand Down Expand Up @@ -698,14 +683,10 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
, lchip->base + LOCOMO_GPD);
locomo_writel(0, lchip->base + LOCOMO_GIE);

/* FrontLight */
/* Frontlight */
locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);

/* Same constants can be used for collie and poodle
(depending on CONFIG options in original sharp code)? */
frontlight_set(lchip, 163, 0, 148);

/* Longtime timer */
locomo_writel(0, lchip->base + LOCOMO_LTINT);
/* SPI */
Expand Down Expand Up @@ -1062,6 +1043,30 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
spin_unlock_irqrestore(&lchip->lock, flags);
}

/*
* Frontlight control
*/

static struct locomo *locomo_chip_driver(struct locomo_dev *ldev);

void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
{
unsigned long flags;
struct locomo *lchip = locomo_chip_driver(dev);

if (vr)
locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1);
else
locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0);

spin_lock_irqsave(&lchip->lock, flags);
locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
udelay(100);
locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
spin_unlock_irqrestore(&lchip->lock, flags);
}

/*
* LoCoMo "Register Access Bus."
*
Expand Down
8 changes: 8 additions & 0 deletions drivers/video/backlight/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ config BACKLIGHT_CORGI
If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
backlight driver.

config BACKLIGHT_LOCOMO
tristate "Sharp LOCOMO LCD/Backlight Driver"
depends on BACKLIGHT_DEVICE && SHARP_LOCOMO
default y
help
If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
enable the LCD/backlight driver.

config BACKLIGHT_HP680
tristate "HP Jornada 680 Backlight Driver"
depends on BACKLIGHT_DEVICE && SH_HP6XX
Expand Down
2 changes: 1 addition & 1 deletion drivers/video/backlight/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
123 changes: 107 additions & 16 deletions drivers/video/backlight/locomolcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/backlight.h>

#include <asm/hardware/locomo.h>
#include <asm/irq.h>
Expand All @@ -25,7 +27,10 @@

#include "../../../arch/arm/mach-sa1100/generic.h"

static struct backlight_device *locomolcd_bl_device;
static struct locomo_dev *locomolcd_dev;
static unsigned long locomolcd_flags;
#define LOCOMOLCD_SUSPENDED 0x01

static void locomolcd_on(int comadj)
{
Expand Down Expand Up @@ -89,12 +94,10 @@ void locomolcd_power(int on)
}

/* read comadj */
if (comadj == -1) {
if (machine_is_poodle())
comadj = 118;
if (machine_is_collie())
comadj = 128;
}
if (comadj == -1 && machine_is_collie())
comadj = 128;
if (comadj == -1 && machine_is_poodle())
comadj = 118;

if (on)
locomolcd_on(comadj);
Expand All @@ -105,26 +108,100 @@ void locomolcd_power(int on)
}
EXPORT_SYMBOL(locomolcd_power);

static int poodle_lcd_probe(struct locomo_dev *dev)

static int current_intensity;

static int locomolcd_set_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 (locomolcd_flags & LOCOMOLCD_SUSPENDED)
intensity = 0;

switch (intensity) {
/* 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;

default:
return -ENODEV;
}
current_intensity = intensity;
return 0;
}

static int locomolcd_get_intensity(struct backlight_device *bd)
{
return current_intensity;
}

static struct backlight_properties locomobl_data = {
.owner = THIS_MODULE,
.get_brightness = locomolcd_get_intensity,
.update_status = locomolcd_set_intensity,
.max_brightness = 4,
};

#ifdef CONFIG_PM
static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state)
{
locomolcd_flags |= LOCOMOLCD_SUSPENDED;
locomolcd_set_intensity(locomolcd_bl_device);
return 0;
}

static int locomolcd_resume(struct locomo_dev *dev)
{
locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
locomolcd_set_intensity(locomolcd_bl_device);
return 0;
}
#else
#define locomolcd_suspend NULL
#define locomolcd_resume NULL
#endif

static int locomolcd_probe(struct locomo_dev *dev)
{
unsigned long flags;

local_irq_save(flags);
locomolcd_dev = dev;

locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0);

/* the poodle_lcd_power function is called for the first time
* from fs_initcall, which is before locomo is activated.
* We need to recall poodle_lcd_power here*/
#ifdef CONFIG_MACH_POODLE
locomolcd_power(1);
#endif
if (machine_is_poodle())
locomolcd_power(1);

local_irq_restore(flags);

locomolcd_bl_device = backlight_device_register("locomo-bl", NULL, &locomobl_data);

if (IS_ERR (locomolcd_bl_device))
return PTR_ERR (locomolcd_bl_device);

/* Set up frontlight so that screen is readable */
locomobl_data.brightness = 2;
locomolcd_set_intensity(locomolcd_bl_device);

return 0;
}

static int poodle_lcd_remove(struct locomo_dev *dev)
static int locomolcd_remove(struct locomo_dev *dev)
{
unsigned long flags;

backlight_device_unregister(locomolcd_bl_device);
local_irq_save(flags);
locomolcd_dev = NULL;
local_irq_restore(flags);
Expand All @@ -136,19 +213,33 @@ static struct locomo_driver poodle_lcd_driver = {
.name = "locomo-backlight",
},
.devid = LOCOMO_DEVID_BACKLIGHT,
.probe = poodle_lcd_probe,
.remove = poodle_lcd_remove,
.probe = locomolcd_probe,
.remove = locomolcd_remove,
.suspend = locomolcd_suspend,
.resume = locomolcd_resume,
};

static int __init poodle_lcd_init(void)

static int __init locomolcd_init(void)
{
int ret = locomo_driver_register(&poodle_lcd_driver);
if (ret) return ret;
if (ret)
return ret;

#ifdef CONFIG_SA1100_COLLIE
sa1100fb_lcd_power = locomolcd_power;
#endif
return 0;
}
device_initcall(poodle_lcd_init);

static void __exit locomolcd_exit(void)
{
locomo_driver_unregister(&poodle_lcd_driver);
}

module_init(locomolcd_init);
module_exit(locomolcd_exit);

MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>");
MODULE_DESCRIPTION("Collie LCD driver");
MODULE_LICENSE("GPL");
5 changes: 5 additions & 0 deletions include/asm-arm/hardware/locomo.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@
#define LOCOMO_ALS 0x00 /* Adjust light cycle */
#define LOCOMO_ALD 0x04 /* Adjust light duty */

#define LOCOMO_ALC_EN 0x8000

/* Backlight controller: TFT signal */
#define LOCOMO_BACKLIGHT 0x38
#define LOCOMO_TC 0x00 /* TFT control signal */
Expand Down Expand Up @@ -203,4 +205,7 @@ void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int
/* M62332 control function */
void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel);

/* Frontlight control */
void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);

#endif

0 comments on commit e442378

Please sign in to comment.