// SPDX-License-Identifier: GPL-2.0-only
/*
 * arizona-spi.c  --  Arizona SPI bus interface
 *
 * Copyright 2012 Wolfson Microelectronics plc
 *
 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
 */

#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/of.h>
#include <uapi/linux/input-event-codes.h>

#include <linux/mfd/arizona/core.h>

#include "arizona.h"

#ifdef CONFIG_ACPI
static const struct acpi_gpio_params reset_gpios = { 1, 0, false };
static const struct acpi_gpio_params ldoena_gpios = { 2, 0, false };

static const struct acpi_gpio_mapping arizona_acpi_gpios[] = {
	{ "reset-gpios", &reset_gpios, 1, },
	{ "wlf,ldoena-gpios", &ldoena_gpios, 1 },
	{ }
};

/*
 * The ACPI resources for the device only describe external GPIO-s. They do
 * not provide mappings for the GPIO-s coming from the Arizona codec itself.
 */
static const struct gpiod_lookup arizona_soc_gpios[] = {
	{ "arizona", 2, "wlf,spkvdd-ena", 0, GPIO_ACTIVE_HIGH },
	{ "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW },
};

/*
 * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
 * Function A Play/Pause:           0 ohm
 * Function D Voice assistant:    135 ohm
 * Function B Volume Up           240 ohm
 * Function C Volume Down         470 ohm
 * Minimum Mic DC resistance     1000 ohm
 * Minimum Ear speaker impedance   16 ohm
 * Note the first max value below must be less then the min. speaker impedance,
 * to allow CTIA/OMTP detection to work. The other max values are the closest
 * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
 */
static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
	{ .max =  11, .key = KEY_PLAYPAUSE },
	{ .max = 186, .key = KEY_VOICECOMMAND },
	{ .max = 348, .key = KEY_VOLUMEUP },
	{ .max = 752, .key = KEY_VOLUMEDOWN },
};

static void arizona_spi_acpi_remove_lookup(void *lookup)
{
	gpiod_remove_lookup_table(lookup);
}

static int arizona_spi_acpi_probe(struct arizona *arizona)
{
	struct gpiod_lookup_table *lookup;
	acpi_status status;
	int ret;

	/* Add mappings for the 2 ACPI declared GPIOs used for reset and ldo-ena */
	devm_acpi_dev_add_driver_gpios(arizona->dev, arizona_acpi_gpios);

	/* Add lookups for the SoCs own GPIOs used for micdet-polarity and spkVDD-enable */
	lookup = devm_kzalloc(arizona->dev,
			      struct_size(lookup, table, ARRAY_SIZE(arizona_soc_gpios) + 1),
			      GFP_KERNEL);
	if (!lookup)
		return -ENOMEM;

	lookup->dev_id = dev_name(arizona->dev);
	memcpy(lookup->table, arizona_soc_gpios, sizeof(arizona_soc_gpios));

	gpiod_add_lookup_table(lookup);
	ret = devm_add_action_or_reset(arizona->dev, arizona_spi_acpi_remove_lookup, lookup);
	if (ret)
		return ret;

	/* Enable 32KHz clock from SoC to codec for jack-detect */
	status = acpi_evaluate_object(ACPI_HANDLE(arizona->dev), "CLKE", NULL, NULL);
	if (ACPI_FAILURE(status))
		dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status);

	/*
	 * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING
	 * The IRQ line will stay low when a new IRQ event happens between reading
	 * the IRQ status flags and acknowledging them. When the IRQ line stays
	 * low like this the IRQ will never trigger again when its type is set
	 * to IRQF_TRIGGER_FALLING. Correct the IRQ trigger-type to fix this.
	 *
	 * Note theoretically it is possible that some boards are not capable
	 * of handling active low level interrupts. In that case setting the
	 * flag to IRQF_TRIGGER_FALLING would not be a bug (and we would need
	 * to work around this) but so far all known usages of IRQF_TRIGGER_FALLING
	 * are a bug in the board's DSDT.
	 */
	arizona->pdata.irq_flags = IRQF_TRIGGER_LOW;

	/* Wait 200 ms after jack insertion */
	arizona->pdata.micd_detect_debounce = 200;

	/* Use standard AOSP values for headset-button mappings */
	arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
	arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);

	return 0;
}

static const struct acpi_device_id arizona_acpi_match[] = {
	{
		.id = "WM510204",
		.driver_data = WM5102,
	},
	{
		.id = "WM510205",
		.driver_data = WM5102,
	},
	{ }
};
MODULE_DEVICE_TABLE(acpi, arizona_acpi_match);
#else
static int arizona_spi_acpi_probe(struct arizona *arizona)
{
	return -ENODEV;
}
#endif

static int arizona_spi_probe(struct spi_device *spi)
{
	const struct spi_device_id *id = spi_get_device_id(spi);
	const void *match_data;
	struct arizona *arizona;
	const struct regmap_config *regmap_config = NULL;
	unsigned long type = 0;
	int ret;

	match_data = device_get_match_data(&spi->dev);
	if (match_data)
		type = (unsigned long)match_data;
	else if (id)
		type = id->driver_data;

	switch (type) {
	case WM5102:
		if (IS_ENABLED(CONFIG_MFD_WM5102))
			regmap_config = &wm5102_spi_regmap;
		break;
	case WM5110:
	case WM8280:
		if (IS_ENABLED(CONFIG_MFD_WM5110))
			regmap_config = &wm5110_spi_regmap;
		break;
	case WM1831:
	case CS47L24:
		if (IS_ENABLED(CONFIG_MFD_CS47L24))
			regmap_config = &cs47l24_spi_regmap;
		break;
	default:
		dev_err(&spi->dev, "Unknown device type %ld\n", type);
		return -EINVAL;
	}

	if (!regmap_config) {
		dev_err(&spi->dev,
			"No kernel support for device type %ld\n", type);
		return -EINVAL;
	}

	arizona = devm_kzalloc(&spi->dev, sizeof(*arizona), GFP_KERNEL);
	if (arizona == NULL)
		return -ENOMEM;

	arizona->regmap = devm_regmap_init_spi(spi, regmap_config);
	if (IS_ERR(arizona->regmap)) {
		ret = PTR_ERR(arizona->regmap);
		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
			ret);
		return ret;
	}

	arizona->type = type;
	arizona->dev = &spi->dev;
	arizona->irq = spi->irq;

	if (has_acpi_companion(&spi->dev)) {
		ret = arizona_spi_acpi_probe(arizona);
		if (ret)
			return ret;
	}

	return arizona_dev_init(arizona);
}

static int arizona_spi_remove(struct spi_device *spi)
{
	struct arizona *arizona = spi_get_drvdata(spi);

	arizona_dev_exit(arizona);

	return 0;
}

static const struct spi_device_id arizona_spi_ids[] = {
	{ "wm5102", WM5102 },
	{ "wm5110", WM5110 },
	{ "wm8280", WM8280 },
	{ "wm1831", WM1831 },
	{ "cs47l24", CS47L24 },
	{ },
};
MODULE_DEVICE_TABLE(spi, arizona_spi_ids);

static struct spi_driver arizona_spi_driver = {
	.driver = {
		.name	= "arizona",
		.pm	= &arizona_pm_ops,
		.of_match_table	= of_match_ptr(arizona_of_match),
		.acpi_match_table = ACPI_PTR(arizona_acpi_match),
	},
	.probe		= arizona_spi_probe,
	.remove		= arizona_spi_remove,
	.id_table	= arizona_spi_ids,
};

module_spi_driver(arizona_spi_driver);

MODULE_SOFTDEP("pre: arizona_ldo1");
MODULE_DESCRIPTION("Arizona SPI bus interface");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
