/*
 * 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.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;

	priv->rate = params_rate(params);

	switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_RIGHT_J:
		switch (params_width(params)) {
		case 24:
		case 32:
			val = 2;
			break;
		case 16:
			val = 0;
			break;
		default:
			return -EINVAL;
		}
		break;
	case SND_SOC_DAIFMT_I2S:
		switch (params_width(params)) {
		case 24:
		case 32:
			val = 5;
			break;
		case 16:
			val = 4;
			break;
		default:
			return -EINVAL;
		}
		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");
