/*
 * 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_MODE_CONTROL	0x13
#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),
	SOC_SINGLE("DAC Invert Output Switch", PCM1792A_MODE_CONTROL, 7, 1, 0),
	SOC_SINGLE("DAC Rolloff Filter Switch", PCM1792A_MODE_CONTROL, 1, 1, 0),
};

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");
