599a52d126
Per device data such as brightness belongs to the indivdual device and should therefore be separate from the the backlight operation function pointers. This patch splits the two types of data and allows simplifcation of some code. Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
153 lines
3.8 KiB
C
153 lines
3.8 KiB
C
/*
|
|
* 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, 0);
|
|
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, 0);
|
|
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");
|