Creation of Cybook 2416 (actually Gen4) repository

This commit is contained in:
mlt
2009-12-18 17:10:00 +00:00
committed by godzil
commit 76f20f4d40
13791 changed files with 6812321 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
#
# Backlight & LCD drivers configuration
#
menuconfig BACKLIGHT_LCD_SUPPORT
bool "Backlight & LCD device support"
help
Enable this to be able to choose the drivers for controlling the
backlight and the LCD panel on some platforms, for example on PDAs.
config BACKLIGHT_CLASS_DEVICE
tristate "Lowlevel Backlight controls"
depends on BACKLIGHT_LCD_SUPPORT
default m
help
This framework adds support for low-level control of the LCD
backlight. This includes support for brightness and power.
To have support for your specific LCD panel you will have to
select the proper drivers which depend on this option.
config LCD_CLASS_DEVICE
tristate "Lowlevel LCD controls"
depends on BACKLIGHT_LCD_SUPPORT
default m
help
This framework adds support for low-level control of LCD.
Some framebuffer devices connect to platform-specific LCD modules
in order to have a platform-specific way to control the flat panel
(contrast and applying power to the LCD (not to the backlight!)).
To have support for your specific LCD panel you will have to
select the proper drivers which depend on this option.
config BACKLIGHT_CORGI
tristate "Sharp Corgi Backlight Driver (SL Series)"
depends on BACKLIGHT_CLASS_DEVICE && PXA_SHARPSL
default y
help
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_CLASS_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_CLASS_DEVICE && SH_HP6XX
default y
help
If you have a HP Jornada 680, say y to enable the
backlight driver.
config BACKLIGHT_PROGEAR
tristate "Frontpath ProGear Backlight Driver"
depends on BACKLIGHT_CLASS_DEVICE && PCI && X86
default n
help
If you have a Frontpath ProGear say Y to enable the
backlight driver.

View File

@@ -0,0 +1,8 @@
# Backlight & LCD drivers
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_BACKLIGHT_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o

View File

@@ -0,0 +1,315 @@
/*
* Backlight Lowlevel Control Abstraction
*
* Copyright (C) 2003,2004 Hewlett-Packard Company
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/backlight.h>
#include <linux/notifier.h>
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/fb.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
/* This callback gets called when something important happens inside a
* framebuffer driver. We're looking if that important event is blanking,
* and if it is, we're switching backlight power as well ...
*/
static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data)
{
struct backlight_device *bd;
struct fb_event *evdata = data;
/* If we aren't interested in this event, skip it immediately ... */
if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
return 0;
bd = container_of(self, struct backlight_device, fb_notif);
mutex_lock(&bd->ops_lock);
if (bd->ops)
if (!bd->ops->check_fb ||
bd->ops->check_fb(evdata->info)) {
bd->props.fb_blank = *(int *)evdata->data;
backlight_update_status(bd);
}
mutex_unlock(&bd->ops_lock);
return 0;
}
static int backlight_register_fb(struct backlight_device *bd)
{
memset(&bd->fb_notif, 0, sizeof(bd->fb_notif));
bd->fb_notif.notifier_call = fb_notifier_callback;
return fb_register_client(&bd->fb_notif);
}
static void backlight_unregister_fb(struct backlight_device *bd)
{
fb_unregister_client(&bd->fb_notif);
}
#else
static inline int backlight_register_fb(struct backlight_device *bd)
{
return 0;
}
static inline void backlight_unregister_fb(struct backlight_device *bd)
{
}
#endif /* CONFIG_FB */
static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
{
struct backlight_device *bd = to_backlight_device(cdev);
return sprintf(buf, "%d\n", bd->props.power);
}
static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
{
int rc = -ENXIO;
char *endp;
struct backlight_device *bd = to_backlight_device(cdev);
int power = simple_strtoul(buf, &endp, 0);
size_t size = endp - buf;
if (*endp && isspace(*endp))
size++;
if (size != count)
return -EINVAL;
mutex_lock(&bd->ops_lock);
if (bd->ops) {
pr_debug("backlight: set power to %d\n", power);
bd->props.power = power;
backlight_update_status(bd);
rc = count;
}
mutex_unlock(&bd->ops_lock);
return rc;
}
static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
{
struct backlight_device *bd = to_backlight_device(cdev);
return sprintf(buf, "%d\n", bd->props.brightness);
}
static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
{
int rc = -ENXIO;
char *endp;
struct backlight_device *bd = to_backlight_device(cdev);
int brightness = simple_strtoul(buf, &endp, 0);
size_t size = endp - buf;
if (*endp && isspace(*endp))
size++;
if (size != count)
return -EINVAL;
mutex_lock(&bd->ops_lock);
if (bd->ops) {
if (brightness > bd->props.max_brightness)
rc = -EINVAL;
else {
pr_debug("backlight: set brightness to %d\n",
brightness);
bd->props.brightness = brightness;
backlight_update_status(bd);
rc = count;
}
}
mutex_unlock(&bd->ops_lock);
return rc;
}
static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
{
struct backlight_device *bd = to_backlight_device(cdev);
return sprintf(buf, "%d\n", bd->props.max_brightness);
}
static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
char *buf)
{
int rc = -ENXIO;
struct backlight_device *bd = to_backlight_device(cdev);
mutex_lock(&bd->ops_lock);
if (bd->ops && bd->ops->get_brightness)
rc = sprintf(buf, "%d\n", bd->ops->get_brightness(bd));
mutex_unlock(&bd->ops_lock);
return rc;
}
static void backlight_class_release(struct class_device *dev)
{
struct backlight_device *bd = to_backlight_device(dev);
kfree(bd);
}
static struct class backlight_class = {
.name = "backlight",
.release = backlight_class_release,
};
#define DECLARE_ATTR(_name,_mode,_show,_store) \
{ \
.attr = { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
}
static const struct class_device_attribute bl_class_device_attributes[] = {
DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
DECLARE_ATTR(brightness, 0644, backlight_show_brightness,
backlight_store_brightness),
DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
NULL),
DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
};
/**
* backlight_device_register - create and register a new object of
* backlight_device class.
* @name: the name of the new object(must be the same as the name of the
* respective framebuffer device).
* @devdata: an optional pointer to be stored in the class_device. The
* methods may retrieve it by using class_get_devdata(&bd->class_dev).
* @ops: the backlight operations structure.
*
* Creates and registers new backlight class_device. Returns either an
* ERR_PTR() or a pointer to the newly allocated device.
*/
struct backlight_device *backlight_device_register(const char *name,
struct device *dev,
void *devdata,
struct backlight_ops *ops)
{
int i, rc;
struct backlight_device *new_bd;
pr_debug("backlight_device_alloc: name=%s\n", name);
new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL);
if (!new_bd)
return ERR_PTR(-ENOMEM);
mutex_init(&new_bd->update_lock);
mutex_init(&new_bd->ops_lock);
new_bd->ops = ops;
new_bd->class_dev.class = &backlight_class;
new_bd->class_dev.dev = dev;
strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
class_set_devdata(&new_bd->class_dev, devdata);
rc = class_device_register(&new_bd->class_dev);
if (rc) {
kfree(new_bd);
return ERR_PTR(rc);
}
rc = backlight_register_fb(new_bd);
if (rc) {
class_device_unregister(&new_bd->class_dev);
return ERR_PTR(rc);
}
for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) {
rc = class_device_create_file(&new_bd->class_dev,
&bl_class_device_attributes[i]);
if (rc) {
while (--i >= 0)
class_device_remove_file(&new_bd->class_dev,
&bl_class_device_attributes[i]);
class_device_unregister(&new_bd->class_dev);
/* No need to kfree(new_bd) since release() method was called */
return ERR_PTR(rc);
}
}
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);
if (!pmac_backlight)
pmac_backlight = new_bd;
mutex_unlock(&pmac_backlight_mutex);
#endif
return new_bd;
}
EXPORT_SYMBOL(backlight_device_register);
/**
* backlight_device_unregister - unregisters a backlight device object.
* @bd: the backlight device object to be unregistered and freed.
*
* Unregisters a previously registered via backlight_device_register object.
*/
void backlight_device_unregister(struct backlight_device *bd)
{
int i;
if (!bd)
return;
pr_debug("backlight_device_unregister: name=%s\n", bd->class_dev.class_id);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);
if (pmac_backlight == bd)
pmac_backlight = NULL;
mutex_unlock(&pmac_backlight_mutex);
#endif
for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++)
class_device_remove_file(&bd->class_dev,
&bl_class_device_attributes[i]);
mutex_lock(&bd->ops_lock);
bd->ops = NULL;
mutex_unlock(&bd->ops_lock);
backlight_unregister_fb(bd);
class_device_unregister(&bd->class_dev);
}
EXPORT_SYMBOL(backlight_device_unregister);
static void __exit backlight_class_exit(void)
{
class_unregister(&backlight_class);
}
static int __init backlight_class_init(void)
{
return class_register(&backlight_class);
}
/*
* if this is compiled into the kernel, we need to ensure that the
* class is registered before users of the class try to register lcd's
*/
postcore_initcall(backlight_class_init);
module_exit(backlight_class_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
MODULE_DESCRIPTION("Backlight Lowlevel Control Abstraction");

View File

@@ -0,0 +1,171 @@
/*
* Backlight Driver for Sharp Zaurus Handhelds (various models)
*
* Copyright (c) 2004-2006 Richard Purdie
*
* Based on Sharp's 2.4 Backlight Driver
*
* 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 <asm/arch/sharpsl.h>
#include <asm/hardware/sharpsl_pm.h>
static int corgibl_intensity;
static struct backlight_properties corgibl_data;
static struct backlight_device *corgi_backlight_device;
static struct corgibl_machinfo *bl_machinfo;
static unsigned long corgibl_flags;
#define CORGIBL_SUSPENDED 0x01
#define CORGIBL_BATTLOW 0x02
static int corgibl_send_intensity(struct backlight_device *bd)
{
void (*corgi_kick_batt)(void);
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 (corgibl_flags & CORGIBL_SUSPENDED)
intensity = 0;
if (corgibl_flags & CORGIBL_BATTLOW)
intensity &= bl_machinfo->limit_mask;
bl_machinfo->set_bl_intensity(intensity);
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 platform_device *pdev, pm_message_t state)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
corgibl_flags |= CORGIBL_SUSPENDED;
backlight_update_status(bd);
return 0;
}
static int corgibl_resume(struct platform_device *pdev)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
corgibl_flags &= ~CORGIBL_SUSPENDED;
backlight_update_status(bd);
return 0;
}
#else
#define corgibl_suspend NULL
#define corgibl_resume NULL
#endif
static int corgibl_get_intensity(struct backlight_device *bd)
{
return corgibl_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)
{
if (limit)
corgibl_flags |= CORGIBL_BATTLOW;
else
corgibl_flags &= ~CORGIBL_BATTLOW;
backlight_update_status(corgi_backlight_device);
}
EXPORT_SYMBOL(corgibl_limit_intensity);
static struct backlight_ops corgibl_ops = {
.get_brightness = corgibl_get_intensity,
.update_status = corgibl_send_intensity,
};
static int corgibl_probe(struct platform_device *pdev)
{
struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
bl_machinfo = machinfo;
if (!machinfo->limit_mask)
machinfo->limit_mask = -1;
corgi_backlight_device = backlight_device_register ("corgi-bl",
&pdev->dev, NULL, &corgibl_ops);
if (IS_ERR (corgi_backlight_device))
return PTR_ERR (corgi_backlight_device);
platform_set_drvdata(pdev, corgi_backlight_device);
corgi_backlight_device->props.max_brightness = machinfo->max_intensity;
corgi_backlight_device->props.power = FB_BLANK_UNBLANK;
corgi_backlight_device->props.brightness = machinfo->default_intensity;
backlight_update_status(corgi_backlight_device);
printk("Corgi Backlight Driver Initialized.\n");
return 0;
}
static int corgibl_remove(struct platform_device *pdev)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
corgibl_data.power = 0;
corgibl_data.brightness = 0;
backlight_update_status(bd);
backlight_device_unregister(bd);
printk("Corgi Backlight Driver Unloaded\n");
return 0;
}
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 platform_driver_register(&corgibl_driver);
}
static void __exit corgibl_exit(void)
{
platform_driver_unregister(&corgibl_driver);
}
module_init(corgibl_init);
module_exit(corgibl_exit);
MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
MODULE_DESCRIPTION("Corgi Backlight Driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,180 @@
/*
* 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>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <asm/cpu/dac.h>
#include <asm/hp6xx.h>
#include <asm/hd64461.h>
#define HP680_MAX_INTENSITY 255
#define HP680_DEFAULT_INTENSITY 10
static int hp680bl_suspended;
static int current_intensity = 0;
static DEFINE_SPINLOCK(bl_lock);
static void hp680bl_send_intensity(struct backlight_device *bd)
{
unsigned long flags;
u16 v;
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 (hp680bl_suspended)
intensity = 0;
spin_lock_irqsave(&bl_lock, flags);
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);
}
spin_unlock_irqrestore(&bl_lock, flags);
current_intensity = intensity;
}
#ifdef CONFIG_PM
static int hp680bl_suspend(struct platform_device *pdev, pm_message_t state)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
hp680bl_suspended = 1;
hp680bl_send_intensity(bd);
return 0;
}
static int hp680bl_resume(struct platform_device *pdev)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
hp680bl_suspended = 0;
hp680bl_send_intensity(bd);
return 0;
}
#else
#define hp680bl_suspend NULL
#define hp680bl_resume NULL
#endif
static int hp680bl_set_intensity(struct backlight_device *bd)
{
hp680bl_send_intensity(bd);
return 0;
}
static int hp680bl_get_intensity(struct backlight_device *bd)
{
return current_intensity;
}
static struct backlight_ops hp680bl_ops = {
.get_brightness = hp680bl_get_intensity,
.update_status = hp680bl_set_intensity,
};
static int __init hp680bl_probe(struct platform_device *pdev)
{
struct backlight_device *bd;
bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL,
&hp680bl_ops);
if (IS_ERR(bd))
return PTR_ERR(bd);
platform_set_drvdata(pdev, bd);
bd->props.max_brightness = HP680_MAX_INTENSITY;
bd->props.brightness = HP680_DEFAULT_INTENSITY;
hp680bl_send_intensity(bd);
return 0;
}
static int hp680bl_remove(struct platform_device *pdev)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
hp680bl_data.brightness = 0;
hp680bl_data.power = 0;
hp680bl_send_intensity(bd);
backlight_device_unregister(bd);
return 0;
}
static struct platform_driver hp680bl_driver = {
.probe = hp680bl_probe,
.remove = hp680bl_remove,
.suspend = hp680bl_suspend,
.resume = hp680bl_resume,
.driver = {
.name = "hp680-bl",
},
};
static struct platform_device *hp680bl_device;
static int __init hp680bl_init(void)
{
int ret;
ret = platform_driver_register(&hp680bl_driver);
if (!ret) {
hp680bl_device = platform_device_alloc("hp680-bl", -1);
if (!hp680bl_device)
return -ENOMEM;
ret = platform_device_add(hp680bl_device);
if (ret) {
platform_device_put(hp680bl_device);
platform_driver_unregister(&hp680bl_driver);
}
}
return ret;
}
static void __exit hp680bl_exit(void)
{
platform_device_unregister(hp680bl_device);
platform_driver_unregister(&hp680bl_driver);
}
module_init(hp680bl_init);
module_exit(hp680bl_exit);
MODULE_AUTHOR("Andriy Skulysh <askulysh@gmail.com>");
MODULE_DESCRIPTION("HP Jornada 680 Backlight Driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,276 @@
/*
* LCD Lowlevel Control Abstraction
*
* Copyright (C) 2003,2004 Hewlett-Packard Company
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/lcd.h>
#include <linux/notifier.h>
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/fb.h>
#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
/* This callback gets called when something important happens inside a
* framebuffer driver. We're looking if that important event is blanking,
* and if it is, we're switching lcd power as well ...
*/
static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data)
{
struct lcd_device *ld;
struct fb_event *evdata = data;
/* If we aren't interested in this event, skip it immediately ... */
if (event != FB_EVENT_BLANK)
return 0;
ld = container_of(self, struct lcd_device, fb_notif);
mutex_lock(&ld->ops_lock);
if (ld->ops)
if (!ld->ops->check_fb || ld->ops->check_fb(evdata->info))
ld->ops->set_power(ld, *(int *)evdata->data);
mutex_unlock(&ld->ops_lock);
return 0;
}
static int lcd_register_fb(struct lcd_device *ld)
{
memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif));
ld->fb_notif.notifier_call = fb_notifier_callback;
return fb_register_client(&ld->fb_notif);
}
static void lcd_unregister_fb(struct lcd_device *ld)
{
fb_unregister_client(&ld->fb_notif);
}
#else
static int lcd_register_fb(struct lcd_device *ld)
{
return 0;
}
static inline void lcd_unregister_fb(struct lcd_device *ld)
{
}
#endif /* CONFIG_FB */
static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
{
int rc;
struct lcd_device *ld = to_lcd_device(cdev);
mutex_lock(&ld->ops_lock);
if (ld->ops && ld->ops->get_power)
rc = sprintf(buf, "%d\n", ld->ops->get_power(ld));
else
rc = -ENXIO;
mutex_unlock(&ld->ops_lock);
return rc;
}
static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_t count)
{
int rc = -ENXIO;
char *endp;
struct lcd_device *ld = to_lcd_device(cdev);
int power = simple_strtoul(buf, &endp, 0);
size_t size = endp - buf;
if (*endp && isspace(*endp))
size++;
if (size != count)
return -EINVAL;
mutex_lock(&ld->ops_lock);
if (ld->ops && ld->ops->set_power) {
pr_debug("lcd: set power to %d\n", power);
ld->ops->set_power(ld, power);
rc = count;
}
mutex_unlock(&ld->ops_lock);
return rc;
}
static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
{
int rc = -ENXIO;
struct lcd_device *ld = to_lcd_device(cdev);
mutex_lock(&ld->ops_lock);
if (ld->ops && ld->ops->get_contrast)
rc = sprintf(buf, "%d\n", ld->ops->get_contrast(ld));
mutex_unlock(&ld->ops_lock);
return rc;
}
static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, size_t count)
{
int rc = -ENXIO;
char *endp;
struct lcd_device *ld = to_lcd_device(cdev);
int contrast = simple_strtoul(buf, &endp, 0);
size_t size = endp - buf;
if (*endp && isspace(*endp))
size++;
if (size != count)
return -EINVAL;
mutex_lock(&ld->ops_lock);
if (ld->ops && ld->ops->set_contrast) {
pr_debug("lcd: set contrast to %d\n", contrast);
ld->ops->set_contrast(ld, contrast);
rc = count;
}
mutex_unlock(&ld->ops_lock);
return rc;
}
static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf)
{
struct lcd_device *ld = to_lcd_device(cdev);
return sprintf(buf, "%d\n", ld->props.max_contrast);
}
static void lcd_class_release(struct class_device *dev)
{
struct lcd_device *ld = to_lcd_device(dev);
kfree(ld);
}
static struct class lcd_class = {
.name = "lcd",
.release = lcd_class_release,
};
#define DECLARE_ATTR(_name,_mode,_show,_store) \
{ \
.attr = { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
}
static const struct class_device_attribute lcd_class_device_attributes[] = {
DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power),
DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
};
/**
* lcd_device_register - register a new object of lcd_device class.
* @name: the name of the new object(must be the same as the name of the
* respective framebuffer device).
* @devdata: an optional pointer to be stored in the class_device. The
* methods may retrieve it by using class_get_devdata(ld->class_dev).
* @ops: the lcd operations structure.
*
* Creates and registers a new lcd class_device. Returns either an ERR_PTR()
* or a pointer to the newly allocated device.
*/
struct lcd_device *lcd_device_register(const char *name, void *devdata,
struct lcd_ops *ops)
{
int i, rc;
struct lcd_device *new_ld;
pr_debug("lcd_device_register: name=%s\n", name);
new_ld = kzalloc(sizeof(struct lcd_device), GFP_KERNEL);
if (!new_ld)
return ERR_PTR(-ENOMEM);
mutex_init(&new_ld->ops_lock);
mutex_init(&new_ld->update_lock);
new_ld->ops = ops;
new_ld->class_dev.class = &lcd_class;
strlcpy(new_ld->class_dev.class_id, name, KOBJ_NAME_LEN);
class_set_devdata(&new_ld->class_dev, devdata);
rc = class_device_register(&new_ld->class_dev);
if (rc) {
kfree(new_ld);
return ERR_PTR(rc);
}
rc = lcd_register_fb(new_ld);
if (rc) {
class_device_unregister(&new_ld->class_dev);
return ERR_PTR(rc);
}
for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) {
rc = class_device_create_file(&new_ld->class_dev,
&lcd_class_device_attributes[i]);
if (rc) {
while (--i >= 0)
class_device_remove_file(&new_ld->class_dev,
&lcd_class_device_attributes[i]);
class_device_unregister(&new_ld->class_dev);
/* No need to kfree(new_ld) since release() method was called */
return ERR_PTR(rc);
}
}
return new_ld;
}
EXPORT_SYMBOL(lcd_device_register);
/**
* lcd_device_unregister - unregisters a object of lcd_device class.
* @ld: the lcd device object to be unregistered and freed.
*
* Unregisters a previously registered via lcd_device_register object.
*/
void lcd_device_unregister(struct lcd_device *ld)
{
int i;
if (!ld)
return;
pr_debug("lcd_device_unregister: name=%s\n", ld->class_dev.class_id);
for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++)
class_device_remove_file(&ld->class_dev,
&lcd_class_device_attributes[i]);
mutex_lock(&ld->ops_lock);
ld->ops = NULL;
mutex_unlock(&ld->ops_lock);
lcd_unregister_fb(ld);
class_device_unregister(&ld->class_dev);
}
EXPORT_SYMBOL(lcd_device_unregister);
static void __exit lcd_class_exit(void)
{
class_unregister(&lcd_class);
}
static int __init lcd_class_init(void)
{
return class_register(&lcd_class);
}
/*
* if this is compiled into the kernel, we need to ensure that the
* class is registered before users of the class try to register lcd's
*/
postcore_initcall(lcd_class_init);
module_exit(lcd_class_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
MODULE_DESCRIPTION("LCD Lowlevel Control Abstraction");

View File

@@ -0,0 +1,247 @@
/*
* Backlight control code for Sharp Zaurus SL-5500
*
* Copyright 2005 John Lenz <lenz@cs.wisc.edu>
* Maintainer: Pavel Machek <pavel@suse.cz> (unless John wants to :-)
* GPL v2
*
* This driver assumes single CPU. That's okay, because collie is
* slightly old hardware, and noone is going to retrofit second CPU to
* 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>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <asm/hardware/locomo.h>
#include <asm/irq.h>
#include <asm/mach/sharpsl_param.h>
#include <asm/mach-types.h>
#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)
{
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);
mdelay(2);
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);
mdelay(2);
locomo_m62332_senddata(locomolcd_dev, comadj, 0);
mdelay(5);
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);
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);
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);
}
static void locomolcd_off(int comadj)
{
/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
mdelay(1);
locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
mdelay(110);
locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
mdelay(700);
/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
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);
}
void locomolcd_power(int on)
{
int comadj = sharpsl_param.comadj;
unsigned long flags;
local_irq_save(flags);
if (!locomolcd_dev) {
local_irq_restore(flags);
return;
}
/* read comadj */
if (comadj == -1 && machine_is_collie())
comadj = 128;
if (comadj == -1 && machine_is_poodle())
comadj = 118;
if (on)
locomolcd_on(comadj);
else
locomolcd_off(comadj);
local_irq_restore(flags);
}
EXPORT_SYMBOL(locomolcd_power);
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_ops locomobl_data = {
.get_brightness = locomolcd_get_intensity,
.update_status = locomolcd_set_intensity,
};
#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 *ldev)
{
unsigned long flags;
local_irq_save(flags);
locomolcd_dev = ldev;
locomo_gpio_set_dir(ldev->dev.parent, 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*/
if (machine_is_poodle())
locomolcd_power(1);
local_irq_restore(flags);
locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data);
if (IS_ERR (locomolcd_bl_device))
return PTR_ERR (locomolcd_bl_device);
/* Set up frontlight so that screen is readable */
locomolcd_bl_device->props.max_brightness = 4,
locomolcd_bl_device->props.brightness = 2;
locomolcd_set_intensity(locomolcd_bl_device);
return 0;
}
static int locomolcd_remove(struct locomo_dev *dev)
{
unsigned long flags;
locomolcd_bl_device->props.brightness = 0;
locomolcd_bl_device->props.power = 0;
locomolcd_set_intensity(locomolcd_bl_device);
backlight_device_unregister(locomolcd_bl_device);
local_irq_save(flags);
locomolcd_dev = NULL;
local_irq_restore(flags);
return 0;
}
static struct locomo_driver poodle_lcd_driver = {
.drv = {
.name = "locomo-backlight",
},
.devid = LOCOMO_DEVID_BACKLIGHT,
.probe = locomolcd_probe,
.remove = locomolcd_remove,
.suspend = locomolcd_suspend,
.resume = locomolcd_resume,
};
static int __init locomolcd_init(void)
{
int ret = locomo_driver_register(&poodle_lcd_driver);
if (ret)
return ret;
#ifdef CONFIG_SA1100_COLLIE
sa1100fb_lcd_power = locomolcd_power;
#endif
return 0;
}
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");

View File

@@ -0,0 +1,153 @@
/*
* Backlight Driver for Frontpath ProGear HX1050+
*
* Copyright (c) 2006 Marcin Juszkiewicz
*
* Based on Progear LCD driver by M Schacht
* <mschacht at alumni dot washington dot edu>
*
* Based on Sharp's Corgi Backlight Driver
* Based on Backlight Driver for HP Jornada 680
*
* 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/pci.h>
#include <asm/uaccess.h>
#define PMU_LPCR 0xB0
#define SB_MPS1 0x61
#define HW_LEVEL_MAX 0x77
#define HW_LEVEL_MIN 0x4f
static struct pci_dev *pmu_dev = NULL;
static struct pci_dev *sb_dev = NULL;
static int progearbl_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;
pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN);
return 0;
}
static int progearbl_get_intensity(struct backlight_device *bd)
{
u8 intensity;
pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity);
return intensity - HW_LEVEL_MIN;
}
static struct backlight_ops progearbl_ops = {
.get_brightness = progearbl_get_intensity,
.update_status = progearbl_set_intensity,
};
static int progearbl_probe(struct platform_device *pdev)
{
u8 temp;
struct backlight_device *progear_backlight_device;
pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
if (!pmu_dev) {
printk("ALI M7101 PMU not found.\n");
return -ENODEV;
}
sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
if (!sb_dev) {
printk("ALI 1533 SB not found.\n");
pci_dev_put(pmu_dev);
return -ENODEV;
}
/* Set SB_MPS1 to enable brightness control. */
pci_read_config_byte(sb_dev, SB_MPS1, &temp);
pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
progear_backlight_device = backlight_device_register("progear-bl",
&pdev->dev, NULL,
&progearbl_ops);
if (IS_ERR(progear_backlight_device))
return PTR_ERR(progear_backlight_device);
platform_set_drvdata(pdev, progear_backlight_device);
progear_backlight_device->props.power = FB_BLANK_UNBLANK;
progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
progearbl_set_intensity(progear_backlight_device);
return 0;
}
static int progearbl_remove(struct platform_device *pdev)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
backlight_device_unregister(bd);
return 0;
}
static struct platform_driver progearbl_driver = {
.probe = progearbl_probe,
.remove = progearbl_remove,
.driver = {
.name = "progear-bl",
},
};
static struct platform_device *progearbl_device;
static int __init progearbl_init(void)
{
int ret = platform_driver_register(&progearbl_driver);
if (!ret) {
progearbl_device = platform_device_alloc("progear-bl", -1);
if (!progearbl_device)
return -ENOMEM;
ret = platform_device_add(progearbl_device);
if (ret) {
platform_device_put(progearbl_device);
platform_driver_unregister(&progearbl_driver);
}
}
return ret;
}
static void __exit progearbl_exit(void)
{
pci_dev_put(pmu_dev);
pci_dev_put(sb_dev);
platform_device_unregister(progearbl_device);
platform_driver_unregister(&progearbl_driver);
}
module_init(progearbl_init);
module_exit(progearbl_exit);
MODULE_AUTHOR("Marcin Juszkiewicz <linux@hrw.one.pl>");
MODULE_DESCRIPTION("ProGear Backlight Driver");
MODULE_LICENSE("GPL");