/*
 * Backlight control code for Sharp Zaurus SL-5500
 *
 * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
 * Maintainer: Pavel Machek <pavel@ucw.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 const 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)
{
	struct backlight_properties props;
	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);

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = 4;
	locomolcd_bl_device = backlight_device_register("locomo-bl",
							&ldev->dev, NULL,
							&locomobl_data, &props);

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

	/* Set up frontlight so that screen is readable */
	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@ucw.cz>");
MODULE_DESCRIPTION("Collie LCD driver");
MODULE_LICENSE("GPL");
