/*
 * Extended support for CS35L41 Amp
 *
 * Copyright 2017 Cirrus Logic
 *
 * Author:      David Rhodes    <david.rhodes@cirrus.com>
 *
 * 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/device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/mfd/cs35l41/registers.h>
#include <linux/mfd/cs35l41/calibration.h>
#include <linux/mfd/cs35l41/big_data.h>
#include <linux/mfd/cs35l41/power.h>

#define CIRRUS_AMP_CLASS_NAME "cirrus"

struct class *cirrus_amp_class;

static int cirrus_amp_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *amp_node;
	const char **mfd_suffixes;
	const char **bd_suffixes;
	int ret, num_amps, i, j;

	if (np) {
		ret = of_property_read_u32(np, "cirrus,num-amps", &num_amps);

		if (ret < 0) {
			dev_err(&pdev->dev,
				"cirrus_amp: failed to parse num-amps\n");
			return -EINVAL;
		}

		mfd_suffixes = kzalloc(num_amps * sizeof(char *), GFP_KERNEL);
		if (mfd_suffixes == NULL) {
			dev_err(&pdev->dev,
				"Failed to allocate\n");
			return -ENOMEM;
		}

		bd_suffixes = kzalloc(num_amps * sizeof(char *), GFP_KERNEL);
		if (bd_suffixes == NULL) {
			dev_err(&pdev->dev,
				"Failed to allocate\n");
			return -ENOMEM;
		}

		for (i = 0; i < num_amps; i++) {
			amp_node = of_parse_phandle(np, "cirrus,amps", i);
			dev_dbg(&pdev->dev, "Found linked amp: %s\n",
					amp_node->full_name);

			ret = of_property_read_string(amp_node,
						"cirrus,mfd-suffix",
						&mfd_suffixes[i]);
			if (ret < 0)
				dev_err(&pdev->dev,
					"No MFD suffix found for amp: %s\n",
					amp_node->full_name);

			ret = of_property_read_string(amp_node,
						"cirrus,bd-suffix",
						&bd_suffixes[i]);
			if (ret < 0)
				dev_dbg(&pdev->dev,
					"No BD suffix found for amp: %s\n",
					amp_node->full_name);

			of_node_put(amp_node);
		}

		for (i = 0; i < num_amps; i++) {
			for (j = 0; j < num_amps; j++) {
				if (mfd_suffixes[i] == NULL ||
						mfd_suffixes[j] == NULL) {
					dev_err(&pdev->dev,
					  "MFD suffixes incomplete\n");
					kfree(mfd_suffixes);
					return -EINVAL;
				}

				if (strcmp(mfd_suffixes[i],
						mfd_suffixes[j]) == 0 &&
					i != j) {
					dev_err(&pdev->dev,
					  "MFD suffixes must be unique\n");
					dev_err(&pdev->dev,
					  "Found duplicate suffix: %s\n",
					  mfd_suffixes[i]);
					kfree(mfd_suffixes);
					return -EINVAL;
				}

				/*bd_suffixes can be empty but must be unique*/
				if (bd_suffixes[i] && bd_suffixes[j]) {
					if (strcmp(bd_suffixes[i],
							bd_suffixes[j]) == 0 &&
								i != j) {
						dev_err(&pdev->dev,
						"BD suffixes must be unique\n");
						dev_err(&pdev->dev,
						  "Found duplicate suffix: %s\n",
						  bd_suffixes[i]);
						kfree(bd_suffixes);
						kfree(mfd_suffixes);
						return -EINVAL;
					}
				}
			}

			dev_info(&pdev->dev,
				"Found MFD suffix: %s\n", mfd_suffixes[i]);
			if (bd_suffixes[i])
				dev_info(&pdev->dev,
				"Found BD suffix: %s\n", bd_suffixes[i]);
		}
	} else {
		dev_err(&pdev->dev,
			"cirrus_amp: failed to parse cirrus-amp DT\n");
		return -EINVAL;
	}

	cirrus_amp_class = class_create(THIS_MODULE,
						CIRRUS_AMP_CLASS_NAME);
        if (IS_ERR(cirrus_amp_class)) {
                dev_err(&pdev->dev, "Failed to register cirrus amp class\n");
                return -EINVAL;
        }

	cirrus_cal_init(cirrus_amp_class, num_amps, mfd_suffixes);
	cirrus_bd_init(cirrus_amp_class, num_amps, mfd_suffixes, bd_suffixes);
	cirrus_pwr_init(cirrus_amp_class, num_amps, mfd_suffixes);

	kfree(mfd_suffixes);
	return 0;
}

static int cirrus_amp_remove(struct platform_device *pdev)
{
	cirrus_cal_exit();
	cirrus_bd_exit();
	cirrus_pwr_exit();

	return 0;
}

static const struct of_device_id simple_of_match[] = {
	{ .compatible = "cirrus-amp", },
	{},
};
MODULE_DEVICE_TABLE(of, simple_of_match);

static struct platform_driver cirrus_amp = {
	.driver = {
		.name = "cirrus-amp",
		.of_match_table = simple_of_match,
	},
	.probe = cirrus_amp_probe,
	.remove = cirrus_amp_remove,
};

module_platform_driver(cirrus_amp);

MODULE_AUTHOR("David Rhodes <David.Rhodes@cirrus.com>");
MODULE_DESCRIPTION("Cirrus Amp driver");
MODULE_LICENSE("GPL");

