/*
 * PCM1792A ASoC codec driver
 *
 * Copyright (c) Amarula Solutions B.V. 2013
 *
 *     Michael Trimarchi <michael@amarulasolutions.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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/module.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/spi/spi.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <linux/of_device.h>

#include "pcm1792a.h"

#define PCM1792A_DAC_VOL_LEFT	0x10
#define PCM1792A_DAC_VOL_RIGHT	0x11
#define PCM1792A_FMT_CONTROL	0x12
#define PCM1792A_SOFT_MUTE	PCM1792A_FMT_CONTROL

#define PCM1792A_FMT_MASK	0x70
#define PCM1792A_FMT_SHIFT	4
#define PCM1792A_MUTE_MASK	0x01
#define PCM1792A_MUTE_SHIFT	0
#define PCM1792A_ATLD_ENABLE	(1 << 7)

static const struct reg_default pcm1792a_reg_defaults[] = {
	{ 0x10, 0xff },
	{ 0x11, 0xff },
	{ 0x12, 0x50 },
	{ 0x13, 0x00 },
	{ 0x14, 0x00 },
	{ 0x15, 0x01 },
	{ 0x16, 0x00 },
	{ 0x17, 0x00 },
};

static bool pcm1792a_accessible_reg(struct device *dev, unsigned int reg)
{
	return reg >= 0x10 && reg <= 0x17;
}

static bool pcm1792a_writeable_reg(struct device *dev, unsigned register reg)
{
	bool accessible;

	accessible = pcm1792a_accessible_reg(dev, reg);

	return accessible && reg != 0x16 && reg != 0x17;
}

struct pcm1792a_private {
	struct regmap *regmap;
	unsigned int format;
	unsigned int rate;
};

static int pcm1792a_set_dai_fmt(struct snd_soc_dai *codec_dai,
                             unsigned int format)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);

	priv->format = format;

	return 0;
}

static int pcm1792a_digital_mute(struct snd_soc_dai *dai, int mute)
{
	struct snd_soc_codec *codec = dai->codec;
	struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
	int ret;

	ret = regmap_update_bits(priv->regmap, PCM1792A_SOFT_MUTE,
				 PCM1792A_MUTE_MASK, !!mute);
	if (ret < 0)
		return ret;

	return 0;
}

static int pcm1792a_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params,
			     struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
	int val = 0, ret;
	int pcm_format = params_format(params);

	priv->rate = params_rate(params);

	switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_RIGHT_J:
		if (pcm_format == SNDRV_PCM_FORMAT_S24_LE ||
		    pcm_format == SNDRV_PCM_FORMAT_S32_LE)
			val = 0x02;
		else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
			val = 0x00;
		break;
	case SND_SOC_DAIFMT_I2S:
		if (pcm_format == SNDRV_PCM_FORMAT_S24_LE ||
		    pcm_format == SNDRV_PCM_FORMAT_S32_LE)
			val = 0x05;
		else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
			val = 0x04;
		break;
	default:
		dev_err(codec->dev, "Invalid DAI format\n");
		return -EINVAL;
	}

	val = val << PCM1792A_FMT_SHIFT | PCM1792A_ATLD_ENABLE;

	ret = regmap_update_bits(priv->regmap, PCM1792A_FMT_CONTROL,
				 PCM1792A_FMT_MASK | PCM1792A_ATLD_ENABLE, val);
	if (ret < 0)
		return ret;

	return 0;
}

static const struct snd_soc_dai_ops pcm1792a_dai_ops = {
	.set_fmt	= pcm1792a_set_dai_fmt,
	.hw_params	= pcm1792a_hw_params,
	.digital_mute	= pcm1792a_digital_mute,
};

static const DECLARE_TLV_DB_SCALE(pcm1792a_dac_tlv, -12000, 50, 1);

static const struct snd_kcontrol_new pcm1792a_controls[] = {
	SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1792A_DAC_VOL_LEFT,
			 PCM1792A_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0,
			 pcm1792a_dac_tlv),
};

static const struct snd_soc_dapm_widget pcm1792a_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("IOUTL+"),
SND_SOC_DAPM_OUTPUT("IOUTL-"),
SND_SOC_DAPM_OUTPUT("IOUTR+"),
SND_SOC_DAPM_OUTPUT("IOUTR-"),
};

static const struct snd_soc_dapm_route pcm1792a_dapm_routes[] = {
	{ "IOUTL+", NULL, "Playback" },
	{ "IOUTL-", NULL, "Playback" },
	{ "IOUTR+", NULL, "Playback" },
	{ "IOUTR-", NULL, "Playback" },
};

static struct snd_soc_dai_driver pcm1792a_dai = {
	.name = "pcm1792a-hifi",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = PCM1792A_RATES,
		.formats = PCM1792A_FORMATS, },
	.ops = &pcm1792a_dai_ops,
};

static const struct of_device_id pcm1792a_of_match[] = {
	{ .compatible = "ti,pcm1792a", },
	{ }
};
MODULE_DEVICE_TABLE(of, pcm1792a_of_match);

static const struct regmap_config pcm1792a_regmap = {
	.reg_bits		= 8,
	.val_bits		= 8,
	.max_register		= 23,
	.reg_defaults		= pcm1792a_reg_defaults,
	.num_reg_defaults	= ARRAY_SIZE(pcm1792a_reg_defaults),
	.writeable_reg		= pcm1792a_writeable_reg,
	.readable_reg		= pcm1792a_accessible_reg,
};

static struct snd_soc_codec_driver soc_codec_dev_pcm1792a = {
	.controls		= pcm1792a_controls,
	.num_controls		= ARRAY_SIZE(pcm1792a_controls),
	.dapm_widgets		= pcm1792a_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(pcm1792a_dapm_widgets),
	.dapm_routes		= pcm1792a_dapm_routes,
	.num_dapm_routes	= ARRAY_SIZE(pcm1792a_dapm_routes),
};

static int pcm1792a_spi_probe(struct spi_device *spi)
{
	struct pcm1792a_private *pcm1792a;
	int ret;

	pcm1792a = devm_kzalloc(&spi->dev, sizeof(struct pcm1792a_private),
				GFP_KERNEL);
	if (!pcm1792a)
		return -ENOMEM;

	spi_set_drvdata(spi, pcm1792a);

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

	return snd_soc_register_codec(&spi->dev,
			&soc_codec_dev_pcm1792a, &pcm1792a_dai, 1);
}

static int pcm1792a_spi_remove(struct spi_device *spi)
{
	snd_soc_unregister_codec(&spi->dev);
	return 0;
}

static const struct spi_device_id pcm1792a_spi_ids[] = {
	{ "pcm1792a", 0 },
	{ },
};
MODULE_DEVICE_TABLE(spi, pcm1792a_spi_ids);

static struct spi_driver pcm1792a_codec_driver = {
	.driver = {
		.name = "pcm1792a",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(pcm1792a_of_match),
	},
	.id_table = pcm1792a_spi_ids,
	.probe = pcm1792a_spi_probe,
	.remove = pcm1792a_spi_remove,
};

module_spi_driver(pcm1792a_codec_driver);

MODULE_DESCRIPTION("ASoC PCM1792A driver");
MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
MODULE_LICENSE("GPL");
