/*
 * tegra20_ac97.c - Tegra20 AC97 platform driver
 *
 * Copyright (c) 2012 Lucas Stach <dev@lynxeye.de>
 *
 * Partly based on code copyright/by:
 *
 * Copyright (c) 2011,2012 Toradex Inc.
 *
 * 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.
 *
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>

#include "tegra20_ac97.h"

#define DRV_NAME "tegra20-ac97"

static struct tegra20_ac97 *workdata;

static void tegra20_ac97_codec_reset(struct snd_ac97 *ac97)
{
	u32 readback;
	unsigned long timeout;

	/* reset line is not driven by DAC pad group, have to toggle GPIO */
	gpio_set_value(workdata->reset_gpio, 0);
	udelay(2);

	gpio_set_value(workdata->reset_gpio, 1);
	udelay(2);

	timeout = jiffies + msecs_to_jiffies(100);

	do {
		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
		if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
			break;
		usleep_range(1000, 2000);
	} while (!time_after(jiffies, timeout));
}

static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
{
	u32 readback;
	unsigned long timeout;

	/*
	 * although sync line is driven by the DAC pad group warm reset using
	 * the controller cmd is not working, have to toggle sync line
	 * manually.
	 */
	gpio_request(workdata->sync_gpio, "codec-sync");

	gpio_direction_output(workdata->sync_gpio, 1);

	udelay(2);
	gpio_set_value(workdata->sync_gpio, 0);
	udelay(2);
	gpio_free(workdata->sync_gpio);

	timeout = jiffies + msecs_to_jiffies(100);

	do {
		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
		if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
			break;
		usleep_range(1000, 2000);
	} while (!time_after(jiffies, timeout));
}

static unsigned short tegra20_ac97_codec_read(struct snd_ac97 *ac97_snd,
					      unsigned short reg)
{
	u32 readback;
	unsigned long timeout;

	regmap_write(workdata->regmap, TEGRA20_AC97_CMD,
		     (((reg | 0x80) << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT) &
		      TEGRA20_AC97_CMD_CMD_ADDR_MASK) |
		     TEGRA20_AC97_CMD_BUSY);

	timeout = jiffies + msecs_to_jiffies(100);

	do {
		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
		if (readback & TEGRA20_AC97_STATUS1_STA_VALID1)
			break;
		usleep_range(1000, 2000);
	} while (!time_after(jiffies, timeout));

	return ((readback & TEGRA20_AC97_STATUS1_STA_DATA1_MASK) >>
		TEGRA20_AC97_STATUS1_STA_DATA1_SHIFT);
}

static void tegra20_ac97_codec_write(struct snd_ac97 *ac97_snd,
				     unsigned short reg, unsigned short val)
{
	u32 readback;
	unsigned long timeout;

	regmap_write(workdata->regmap, TEGRA20_AC97_CMD,
		     ((reg << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT) &
		      TEGRA20_AC97_CMD_CMD_ADDR_MASK) |
		     ((val << TEGRA20_AC97_CMD_CMD_DATA_SHIFT) &
		      TEGRA20_AC97_CMD_CMD_DATA_MASK) |
		     TEGRA20_AC97_CMD_BUSY);

	timeout = jiffies + msecs_to_jiffies(100);

	do {
		regmap_read(workdata->regmap, TEGRA20_AC97_CMD, &readback);
		if (!(readback & TEGRA20_AC97_CMD_BUSY))
			break;
		usleep_range(1000, 2000);
	} while (!time_after(jiffies, timeout));
}

static struct snd_ac97_bus_ops tegra20_ac97_ops = {
	.read		= tegra20_ac97_codec_read,
	.write		= tegra20_ac97_codec_write,
	.reset		= tegra20_ac97_codec_reset,
	.warm_reset	= tegra20_ac97_codec_warm_reset,
};

static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)
{
	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
			   TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN,
			   TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN);

	regmap_update_bits(ac97->regmap, TEGRA20_AC97_CTRL,
			   TEGRA20_AC97_CTRL_PCM_DAC_EN |
			   TEGRA20_AC97_CTRL_STM_EN,
			   TEGRA20_AC97_CTRL_PCM_DAC_EN |
			   TEGRA20_AC97_CTRL_STM_EN);
}

static inline void tegra20_ac97_stop_playback(struct tegra20_ac97 *ac97)
{
	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
			   TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN, 0);

	regmap_update_bits(ac97->regmap, TEGRA20_AC97_CTRL,
			   TEGRA20_AC97_CTRL_PCM_DAC_EN, 0);
}

static inline void tegra20_ac97_start_capture(struct tegra20_ac97 *ac97)
{
	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
			   TEGRA20_AC97_FIFO_SCR_REC_FULL_EN,
			   TEGRA20_AC97_FIFO_SCR_REC_FULL_EN);
}

static inline void tegra20_ac97_stop_capture(struct tegra20_ac97 *ac97)
{
	regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
			   TEGRA20_AC97_FIFO_SCR_REC_FULL_EN, 0);
}

static int tegra20_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
				struct snd_soc_dai *dai)
{
	struct tegra20_ac97 *ac97 = snd_soc_dai_get_drvdata(dai);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_RESUME:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			tegra20_ac97_start_playback(ac97);
		else
			tegra20_ac97_start_capture(ac97);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			tegra20_ac97_stop_playback(ac97);
		else
			tegra20_ac97_stop_capture(ac97);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static const struct snd_soc_dai_ops tegra20_ac97_dai_ops = {
	.trigger	= tegra20_ac97_trigger,
};

static int tegra20_ac97_probe(struct snd_soc_dai *dai)
{
	struct tegra20_ac97 *ac97 = snd_soc_dai_get_drvdata(dai);

	dai->capture_dma_data = &ac97->capture_dma_data;
	dai->playback_dma_data = &ac97->playback_dma_data;

	return 0;
}

static struct snd_soc_dai_driver tegra20_ac97_dai = {
	.name = "tegra-ac97-pcm",
	.bus_control = true,
	.probe = tegra20_ac97_probe,
	.playback = {
		.stream_name = "PCM Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,
	},
	.capture = {
		.stream_name = "PCM Capture",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,
	},
	.ops = &tegra20_ac97_dai_ops,
};

static const struct snd_soc_component_driver tegra20_ac97_component = {
	.name		= DRV_NAME,
};

static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case TEGRA20_AC97_CTRL:
	case TEGRA20_AC97_CMD:
	case TEGRA20_AC97_STATUS1:
	case TEGRA20_AC97_FIFO1_SCR:
	case TEGRA20_AC97_FIFO_TX1:
	case TEGRA20_AC97_FIFO_RX1:
		return true;
	default:
		break;
	}

	return false;
}

static bool tegra20_ac97_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case TEGRA20_AC97_STATUS1:
	case TEGRA20_AC97_FIFO1_SCR:
	case TEGRA20_AC97_FIFO_TX1:
	case TEGRA20_AC97_FIFO_RX1:
		return true;
	default:
		break;
	}

	return false;
}

static bool tegra20_ac97_precious_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case TEGRA20_AC97_FIFO_TX1:
	case TEGRA20_AC97_FIFO_RX1:
		return true;
	default:
		break;
	}

	return false;
}

static const struct regmap_config tegra20_ac97_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.max_register = TEGRA20_AC97_FIFO_RX1,
	.writeable_reg = tegra20_ac97_wr_rd_reg,
	.readable_reg = tegra20_ac97_wr_rd_reg,
	.volatile_reg = tegra20_ac97_volatile_reg,
	.precious_reg = tegra20_ac97_precious_reg,
	.cache_type = REGCACHE_FLAT,
};

static int tegra20_ac97_platform_probe(struct platform_device *pdev)
{
	struct tegra20_ac97 *ac97;
	struct resource *mem;
	void __iomem *regs;
	int ret = 0;

	ac97 = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_ac97),
			    GFP_KERNEL);
	if (!ac97) {
		dev_err(&pdev->dev, "Can't allocate tegra20_ac97\n");
		ret = -ENOMEM;
		goto err;
	}
	dev_set_drvdata(&pdev->dev, ac97);

	ac97->clk_ac97 = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(ac97->clk_ac97)) {
		dev_err(&pdev->dev, "Can't retrieve ac97 clock\n");
		ret = PTR_ERR(ac97->clk_ac97);
		goto err;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	regs = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(regs)) {
		ret = PTR_ERR(regs);
		goto err_clk_put;
	}

	ac97->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
					    &tegra20_ac97_regmap_config);
	if (IS_ERR(ac97->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		ret = PTR_ERR(ac97->regmap);
		goto err_clk_put;
	}

	ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
					     "nvidia,codec-reset-gpio", 0);
	if (gpio_is_valid(ac97->reset_gpio)) {
		ret = devm_gpio_request_one(&pdev->dev, ac97->reset_gpio,
					    GPIOF_OUT_INIT_HIGH, "codec-reset");
		if (ret) {
			dev_err(&pdev->dev, "could not get codec-reset GPIO\n");
			goto err_clk_put;
		}
	} else {
		dev_err(&pdev->dev, "no codec-reset GPIO supplied\n");
		goto err_clk_put;
	}

	ac97->sync_gpio = of_get_named_gpio(pdev->dev.of_node,
					    "nvidia,codec-sync-gpio", 0);
	if (!gpio_is_valid(ac97->sync_gpio)) {
		dev_err(&pdev->dev, "no codec-sync GPIO supplied\n");
		goto err_clk_put;
	}

	ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
	ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	ac97->capture_dma_data.maxburst = 4;

	ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
	ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	ac97->playback_dma_data.maxburst = 4;

	ret = clk_prepare_enable(ac97->clk_ac97);
	if (ret) {
		dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
		goto err;
	}

	ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
		goto err_clk_disable_unprepare;
	}

	ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
					 &tegra20_ac97_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_clk_disable_unprepare;
	}

	ret = tegra_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_unregister_component;
	}

	/* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */
	workdata = ac97;

	return 0;

err_unregister_component:
	snd_soc_unregister_component(&pdev->dev);
err_clk_disable_unprepare:
	clk_disable_unprepare(ac97->clk_ac97);
err_clk_put:
err:
	snd_soc_set_ac97_ops(NULL);
	return ret;
}

static int tegra20_ac97_platform_remove(struct platform_device *pdev)
{
	struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev);

	tegra_pcm_platform_unregister(&pdev->dev);
	snd_soc_unregister_component(&pdev->dev);

	clk_disable_unprepare(ac97->clk_ac97);

	snd_soc_set_ac97_ops(NULL);

	return 0;
}

static const struct of_device_id tegra20_ac97_of_match[] = {
	{ .compatible = "nvidia,tegra20-ac97", },
	{},
};

static struct platform_driver tegra20_ac97_driver = {
	.driver = {
		.name = DRV_NAME,
		.of_match_table = tegra20_ac97_of_match,
	},
	.probe = tegra20_ac97_platform_probe,
	.remove = tegra20_ac97_platform_remove,
};
module_platform_driver(tegra20_ac97_driver);

MODULE_AUTHOR("Lucas Stach");
MODULE_DESCRIPTION("Tegra20 AC97 ASoC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);
MODULE_DEVICE_TABLE(of, tegra20_ac97_of_match);
