/*
 *  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");
