/*
 * MFD driver for twl4030 audio submodule, which contains an audio codec, and
 * the vibra control.
 *
 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
 *
 * Copyright:   (C) 2009 Nokia Corporation
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/i2c/twl.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl4030-audio.h>

#define TWL4030_AUDIO_CELLS	2

static struct platform_device *twl4030_audio_dev;

struct twl4030_audio_resource {
	int request_count;
	u8 reg;
	u8 mask;
};

struct twl4030_audio {
	unsigned int audio_mclk;
	struct mutex mutex;
	struct twl4030_audio_resource resource[TWL4030_AUDIO_RES_MAX];
	struct mfd_cell cells[TWL4030_AUDIO_CELLS];
};

/*
 * Modify the resource, the function returns the content of the register
 * after the modification.
 */
static int twl4030_audio_set_resource(enum twl4030_audio_res id, int enable)
{
	struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
	u8 val;

	twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
			audio->resource[id].reg);

	if (enable)
		val |= audio->resource[id].mask;
	else
		val &= ~audio->resource[id].mask;

	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
					val, audio->resource[id].reg);

	return val;
}

static inline int twl4030_audio_get_resource(enum twl4030_audio_res id)
{
	struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
	u8 val;

	twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val,
			audio->resource[id].reg);

	return val;
}

/*
 * Enable the resource.
 * The function returns with error or the content of the register
 */
int twl4030_audio_enable_resource(enum twl4030_audio_res id)
{
	struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
	int val;

	if (id >= TWL4030_AUDIO_RES_MAX) {
		dev_err(&twl4030_audio_dev->dev,
				"Invalid resource ID (%u)\n", id);
		return -EINVAL;
	}

	mutex_lock(&audio->mutex);
	if (!audio->resource[id].request_count)
		/* Resource was disabled, enable it */
		val = twl4030_audio_set_resource(id, 1);
	else
		val = twl4030_audio_get_resource(id);

	audio->resource[id].request_count++;
	mutex_unlock(&audio->mutex);

	return val;
}
EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource);

/*
 * Disable the resource.
 * The function returns with error or the content of the register
 */
int twl4030_audio_disable_resource(unsigned id)
{
	struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
	int val;

	if (id >= TWL4030_AUDIO_RES_MAX) {
		dev_err(&twl4030_audio_dev->dev,
				"Invalid resource ID (%u)\n", id);
		return -EINVAL;
	}

	mutex_lock(&audio->mutex);
	if (!audio->resource[id].request_count) {
		dev_err(&twl4030_audio_dev->dev,
			"Resource has been disabled already (%u)\n", id);
		mutex_unlock(&audio->mutex);
		return -EPERM;
	}
	audio->resource[id].request_count--;

	if (!audio->resource[id].request_count)
		/* Resource can be disabled now */
		val = twl4030_audio_set_resource(id, 0);
	else
		val = twl4030_audio_get_resource(id);

	mutex_unlock(&audio->mutex);

	return val;
}
EXPORT_SYMBOL_GPL(twl4030_audio_disable_resource);

unsigned int twl4030_audio_get_mclk(void)
{
	struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);

	return audio->audio_mclk;
}
EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);

static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata,
			      struct device_node *node)
{
	if (pdata && pdata->codec)
		return true;

	if (of_find_node_by_name(node, "codec"))
		return true;

	return false;
}

static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
			      struct device_node *node)
{
	int vibra;

	if (pdata && pdata->vibra)
		return true;

	if (!of_property_read_u32(node, "ti,enable-vibra", &vibra) && vibra)
		return true;

	return false;
}

static int __devinit twl4030_audio_probe(struct platform_device *pdev)
{
	struct twl4030_audio *audio;
	struct twl4030_audio_data *pdata = pdev->dev.platform_data;
	struct device_node *node = pdev->dev.of_node;
	struct mfd_cell *cell = NULL;
	int ret, childs = 0;
	u8 val;

	if (!pdata && !node) {
		dev_err(&pdev->dev, "Platform data is missing\n");
		return -EINVAL;
	}

	audio = devm_kzalloc(&pdev->dev, sizeof(struct twl4030_audio),
			     GFP_KERNEL);
	if (!audio)
		return -ENOMEM;

	mutex_init(&audio->mutex);
	audio->audio_mclk = twl_get_hfclk_rate();

	/* Configure APLL_INFREQ and disable APLL if enabled */
	switch (audio->audio_mclk) {
	case 19200000:
		val = TWL4030_APLL_INFREQ_19200KHZ;
		break;
	case 26000000:
		val = TWL4030_APLL_INFREQ_26000KHZ;
		break;
	case 38400000:
		val = TWL4030_APLL_INFREQ_38400KHZ;
		break;
	default:
		dev_err(&pdev->dev, "Invalid audio_mclk\n");
		return -EINVAL;
	}
	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, val, TWL4030_REG_APLL_CTL);

	/* Codec power */
	audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
	audio->resource[TWL4030_AUDIO_RES_POWER].mask = TWL4030_CODECPDZ;

	/* PLL */
	audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
	audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN;

	if (twl4030_audio_has_codec(pdata, node)) {
		cell = &audio->cells[childs];
		cell->name = "twl4030-codec";
		if (pdata) {
			cell->platform_data = pdata->codec;
			cell->pdata_size = sizeof(*pdata->codec);
		}
		childs++;
	}
	if (twl4030_audio_has_vibra(pdata, node)) {
		cell = &audio->cells[childs];
		cell->name = "twl4030-vibra";
		if (pdata) {
			cell->platform_data = pdata->vibra;
			cell->pdata_size = sizeof(*pdata->vibra);
		}
		childs++;
	}

	platform_set_drvdata(pdev, audio);
	twl4030_audio_dev = pdev;

	if (childs)
		ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells,
				      childs, NULL, 0, NULL);
	else {
		dev_err(&pdev->dev, "No platform data found for childs\n");
		ret = -ENODEV;
	}

	if (ret) {
		platform_set_drvdata(pdev, NULL);
		twl4030_audio_dev = NULL;
	}

	return ret;
}

static int __devexit twl4030_audio_remove(struct platform_device *pdev)
{
	mfd_remove_devices(&pdev->dev);
	platform_set_drvdata(pdev, NULL);
	twl4030_audio_dev = NULL;

	return 0;
}

static const struct of_device_id twl4030_audio_of_match[] = {
	{.compatible = "ti,twl4030-audio", },
	{ },
};
MODULE_DEVICE_TABLE(of, twl4030_audio_of_match);

static struct platform_driver twl4030_audio_driver = {
	.driver		= {
		.owner	= THIS_MODULE,
		.name	= "twl4030-audio",
		.of_match_table = twl4030_audio_of_match,
	},
	.probe		= twl4030_audio_probe,
	.remove		= __devexit_p(twl4030_audio_remove),
};

module_platform_driver(twl4030_audio_driver);

MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
MODULE_DESCRIPTION("TWL4030 audio block MFD driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:twl4030-audio");
