// SPDX-License-Identifier: GPL-2.0
/*
 * Backlight code for via-pmu
 *
 * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi.
 * Copyright (C) 2001-2002 Benjamin Herrenschmidt
 * Copyright (C) 2006      Michael Hanselmann <linux-kernel@hansmi.ch>
 *
 */

#include <asm/ptrace.h>
#include <linux/adb.h>
#include <linux/backlight.h>
#include <linux/pmu.h>
#include <asm/backlight.h>

#define MAX_PMU_LEVEL 0xFF

static const struct backlight_ops pmu_backlight_data;
static DEFINE_SPINLOCK(pmu_backlight_lock);
static int sleeping, uses_pmu_bl;
static u8 bl_curve[FB_BACKLIGHT_LEVELS];

static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
{
	int i, flat, count, range = (max - min);

	bl_curve[0] = off;

	for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
		bl_curve[flat] = min;

	count = FB_BACKLIGHT_LEVELS * 15 / 16;
	for (i = 0; i < count; ++i)
		bl_curve[flat + i] = min + (range * (i + 1) / count);
}

static int pmu_backlight_curve_lookup(int value)
{
	int level = (FB_BACKLIGHT_LEVELS - 1);
	int i, max = 0;

	/* Look for biggest value */
	for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
		max = max((int)bl_curve[i], max);

	/* Look for nearest value */
	for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
		int diff = abs(bl_curve[i] - value);
		if (diff < max) {
			max = diff;
			level = i;
		}
	}
	return level;
}

static int pmu_backlight_get_level_brightness(int level)
{
	int pmulevel;

	/* Get and convert the value */
	pmulevel = bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
	if (pmulevel < 0)
		pmulevel = 0;
	else if (pmulevel > MAX_PMU_LEVEL)
		pmulevel = MAX_PMU_LEVEL;

	return pmulevel;
}

static int __pmu_backlight_update_status(struct backlight_device *bd)
{
	struct adb_request req;
	int level = backlight_get_brightness(bd);

	if (level > 0) {
		int pmulevel = pmu_backlight_get_level_brightness(level);

		pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel);
		pmu_wait_complete(&req);

		pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
			PMU_POW_BACKLIGHT | PMU_POW_ON);
		pmu_wait_complete(&req);
	} else {
		pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
			PMU_POW_BACKLIGHT | PMU_POW_OFF);
		pmu_wait_complete(&req);
	}

	return 0;
}

static int pmu_backlight_update_status(struct backlight_device *bd)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&pmu_backlight_lock, flags);
	/* Don't update brightness when sleeping */
	if (!sleeping)
		rc = __pmu_backlight_update_status(bd);
	spin_unlock_irqrestore(&pmu_backlight_lock, flags);
	return rc;
}


static const struct backlight_ops pmu_backlight_data = {
	.update_status	= pmu_backlight_update_status,

};

#ifdef CONFIG_PM
void pmu_backlight_set_sleep(int sleep)
{
	unsigned long flags;

	spin_lock_irqsave(&pmu_backlight_lock, flags);
	sleeping = sleep;
	if (pmac_backlight && uses_pmu_bl) {
		if (sleep) {
			struct adb_request req;

			pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
				    PMU_POW_BACKLIGHT | PMU_POW_OFF);
			pmu_wait_complete(&req);
		} else
			__pmu_backlight_update_status(pmac_backlight);
	}
	spin_unlock_irqrestore(&pmu_backlight_lock, flags);
}
#endif /* CONFIG_PM */

void __init pmu_backlight_init(void)
{
	struct backlight_properties props;
	struct backlight_device *bd;
	char name[10];
	int level, autosave;

	/* Special case for the old PowerBook since I can't test on it */
	autosave =
		of_machine_is_compatible("AAPL,3400/2400") ||
		of_machine_is_compatible("AAPL,3500");

	if (!autosave &&
	    !pmac_has_backlight_type("pmu") &&
	    !of_machine_is_compatible("AAPL,PowerBook1998") &&
	    !of_machine_is_compatible("PowerBook1,1"))
		return;

	snprintf(name, sizeof(name), "pmubl");

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
	bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data,
				       &props);
	if (IS_ERR(bd)) {
		printk(KERN_ERR "PMU Backlight registration failed\n");
		return;
	}
	uses_pmu_bl = 1;
	pmu_backlight_init_curve(0x7F, 0x46, 0x0E);

	level = bd->props.max_brightness;

	if (autosave) {
		/* read autosaved value if available */
		struct adb_request req;
		pmu_request(&req, NULL, 2, 0xd9, 0);
		pmu_wait_complete(&req);

		level = pmu_backlight_curve_lookup(
				(req.reply[0] >> 4) *
				bd->props.max_brightness / 15);
	}

	bd->props.brightness = level;
	bd->props.power = BACKLIGHT_POWER_ON;
	backlight_update_status(bd);

	printk(KERN_INFO "PMU Backlight initialized (%s)\n", name);
}
