/*
 * Miscellaneous procedures for dealing with the PowerMac hardware.
 * Contains support for the backlight.
 *
 *   Copyright (C) 2000 Benjamin Herrenschmidt
 *
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/reboot.h>
#include <linux/nvram.h>
#include <linux/console.h>
#include <asm/sections.h>
#include <asm/ptrace.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/nvram.h>
#include <asm/backlight.h>

#include <linux/adb.h>
#include <linux/pmu.h>

static struct backlight_controller *backlighter;
static void* backlighter_data;
static int backlight_autosave;
static int backlight_level = BACKLIGHT_MAX;
static int backlight_enabled = 1;
static int backlight_req_level = -1;
static int backlight_req_enable = -1;

static void backlight_callback(void *);
static DECLARE_WORK(backlight_work, backlight_callback, NULL);

void __pmac register_backlight_controller(struct backlight_controller *ctrler,
					  void *data, char *type)
{
	struct device_node* bk_node;
	char *prop;
	int valid = 0;

	/* There's already a matching controller, bail out */
	if (backlighter != NULL)
		return;

	bk_node = find_devices("backlight");

#ifdef CONFIG_ADB_PMU
	/* Special case for the old PowerBook since I can't test on it */
	backlight_autosave = machine_is_compatible("AAPL,3400/2400")
		|| machine_is_compatible("AAPL,3500");
	if ((backlight_autosave
	     || machine_is_compatible("AAPL,PowerBook1998")
	     || machine_is_compatible("PowerBook1,1"))
	    && !strcmp(type, "pmu"))
		valid = 1;
#endif
	if (bk_node) {
		prop = get_property(bk_node, "backlight-control", NULL);
		if (prop && !strncmp(prop, type, strlen(type)))
			valid = 1;
	}
	if (!valid)
		return;
	backlighter = ctrler;
	backlighter_data = data;

	if (bk_node && !backlight_autosave)
		prop = get_property(bk_node, "bklt", NULL);
	else
		prop = NULL;
	if (prop) {
		backlight_level = ((*prop)+1) >> 1;
		if (backlight_level > BACKLIGHT_MAX)
			backlight_level = BACKLIGHT_MAX;
	}

#ifdef CONFIG_ADB_PMU
	if (backlight_autosave) {
		struct adb_request req;
		pmu_request(&req, NULL, 2, 0xd9, 0);
		while (!req.complete)
			pmu_poll();
		backlight_level = req.reply[0] >> 4;
	}
#endif
	acquire_console_sem();
	if (!backlighter->set_enable(1, backlight_level, data))
		backlight_enabled = 1;
	release_console_sem();

	printk(KERN_INFO "Registered \"%s\" backlight controller,"
	       "level: %d/15\n", type, backlight_level);
}
EXPORT_SYMBOL(register_backlight_controller);

void __pmac unregister_backlight_controller(struct backlight_controller
					    *ctrler, void *data)
{
	/* We keep the current backlight level (for now) */
	if (ctrler == backlighter && data == backlighter_data)
		backlighter = NULL;
}
EXPORT_SYMBOL(unregister_backlight_controller);

static int __pmac __set_backlight_enable(int enable)
{
	int rc;

	if (!backlighter)
		return -ENODEV;
	acquire_console_sem();
	rc = backlighter->set_enable(enable, backlight_level,
				     backlighter_data);
	if (!rc)
		backlight_enabled = enable;
	release_console_sem();
	return rc;
}
int __pmac set_backlight_enable(int enable)
{
	if (!backlighter)
		return -ENODEV;
	backlight_req_enable = enable;
	schedule_work(&backlight_work);
	return 0;
}

EXPORT_SYMBOL(set_backlight_enable);

int __pmac get_backlight_enable(void)
{
	if (!backlighter)
		return -ENODEV;
	return backlight_enabled;
}
EXPORT_SYMBOL(get_backlight_enable);

static int __pmac __set_backlight_level(int level)
{
	int rc = 0;

	if (!backlighter)
		return -ENODEV;
	if (level < BACKLIGHT_MIN)
		level = BACKLIGHT_OFF;
	if (level > BACKLIGHT_MAX)
		level = BACKLIGHT_MAX;
	acquire_console_sem();
	if (backlight_enabled)
		rc = backlighter->set_level(level, backlighter_data);
	if (!rc)
		backlight_level = level;
	release_console_sem();
	if (!rc && !backlight_autosave) {
		level <<=1;
		if (level & 0x10)
			level |= 0x01;
		// -- todo: save to property "bklt"
	}
	return rc;
}
int __pmac set_backlight_level(int level)
{
	if (!backlighter)
		return -ENODEV;
	backlight_req_level = level;
	schedule_work(&backlight_work);
	return 0;
}

EXPORT_SYMBOL(set_backlight_level);

int __pmac get_backlight_level(void)
{
	if (!backlighter)
		return -ENODEV;
	return backlight_level;
}
EXPORT_SYMBOL(get_backlight_level);

static void backlight_callback(void *dummy)
{
	int level, enable;

	do {
		level = backlight_req_level;
		enable = backlight_req_enable;
		mb();

		if (level >= 0)
			__set_backlight_level(level);
		if (enable >= 0)
			__set_backlight_enable(enable);
	} while(cmpxchg(&backlight_req_level, level, -1) != level ||
		cmpxchg(&backlight_req_enable, enable, -1) != enable);
}
