/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 */

#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/module.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/debugfs.h>
#include <linux/mfd/pm8xxx/core.h>
#include <linux/mfd/pm8xxx/spk.h>

#define PM8XXX_SPK_CTL1_REG_OFF		0
#define PM8XXX_SPK_CTL2_REG_OFF		1
#define PM8XXX_SPK_CTL3_REG_OFF		2
#define PM8XXX_SPK_CTL4_REG_OFF		3
#define PM8XXX_SPK_TEST_REG_1_OFF	4
#define PM8XXX_SPK_TEST_REG_2_OFF	5

#define PM8XXX_SPK_BANK_SEL		4
#define PM8XXX_SPK_BANK_WRITE		0x80
#define PM8XXX_SPK_BANK_VAL_MASK	0xF

#define BOOST_6DB_GAIN_EN_MASK		0x8
#define VSEL_LD0_1P1			0x0
#define VSEL_LD0_1P2			0x2
#define VSEL_LD0_1P0			0x4

#define PWM_EN_MASK			0xF
#define PM8XXX_SPK_TEST_REG_1_BANKS	8
#define PM8XXX_SPK_TEST_REG_2_BANKS	2

#define PM8XXX_SPK_GAIN			0x5
#define PM8XXX_ADD_EN			0x1

struct pm8xxx_spk_chip {
	struct list_head                        link;
	struct pm8xxx_spk_platform_data		pdata;
	struct device                           *dev;
	enum pm8xxx_version                     version;
	struct mutex				spk_mutex;
	u16					base;
	u16					end;
};

static struct pm8xxx_spk_chip *the_spk_chip;

static inline bool spk_defined(void)
{
	if (the_spk_chip == NULL || IS_ERR(the_spk_chip))
		return false;
	return true;
}

static int pm8xxx_spk_bank_write(u16 reg, u16 bank, u8 val)
{
	int rc = 0;
	u8 bank_val = PM8XXX_SPK_BANK_WRITE | (bank << PM8XXX_SPK_BANK_SEL);

	bank_val |= (val & PM8XXX_SPK_BANK_VAL_MASK);
	mutex_lock(&the_spk_chip->spk_mutex);
	rc = pm8xxx_writeb(the_spk_chip->dev->parent, reg, bank_val);
	if (rc)
		pr_err("pm8xxx_writeb(): rc=%d\n", rc);
	mutex_unlock(&the_spk_chip->spk_mutex);
	return rc;
}


static int pm8xxx_spk_read(u16 addr)
{
	int rc = 0;
	u8 val = 0;

	mutex_lock(&the_spk_chip->spk_mutex);
	rc = pm8xxx_readb(the_spk_chip->dev->parent,
			the_spk_chip->base + addr, &val);
	if (rc) {
		pr_err("pm8xxx_spk_readb() failed: rc=%d\n", rc);
		val = rc;
	}
	mutex_unlock(&the_spk_chip->spk_mutex);

	return val;
}

static int pm8xxx_spk_write(u16 addr, u8 val)
{
	int rc = 0;

	mutex_lock(&the_spk_chip->spk_mutex);
	rc = pm8xxx_writeb(the_spk_chip->dev->parent,
			the_spk_chip->base + addr, val);
	if (rc)
		pr_err("pm8xxx_writeb() failed: rc=%d\n", rc);
	mutex_unlock(&the_spk_chip->spk_mutex);
	return rc;
}

int pm8xxx_spk_mute(bool mute)
{
	u8 val = 0;
	int ret = 0;
	if (spk_defined() == false) {
		pr_err("Invalid spk handle or no spk_chip\n");
		return -ENODEV;
	}

	val = pm8xxx_spk_read(PM8XXX_SPK_CTL1_REG_OFF);
	val |= mute << 2;
	ret = pm8xxx_spk_write(PM8XXX_SPK_CTL1_REG_OFF, val);
	return ret;
}
EXPORT_SYMBOL_GPL(pm8xxx_spk_mute);

int pm8xxx_spk_gain(u8 gain)
{
	u8 val;
	int ret = 0;

	if (spk_defined() == false) {
		pr_err("Invalid spk handle or no spk_chip\n");
		return -ENODEV;
	}

	val = pm8xxx_spk_read(PM8XXX_SPK_CTL1_REG_OFF);
	val = (gain << 4) | (val & 0xF);
	ret = pm8xxx_spk_write(PM8XXX_SPK_CTL1_REG_OFF, val);
	if (!ret) {
		pm8xxx_spk_bank_write(the_spk_chip->base
			+ PM8XXX_SPK_TEST_REG_1_OFF,
			0, BOOST_6DB_GAIN_EN_MASK | VSEL_LD0_1P2);
	}
	return ret;
}
EXPORT_SYMBOL_GPL(pm8xxx_spk_gain);

int pm8xxx_spk_enable(int enable)
{
	int val = 0;
	u16 addr;
	int ret = 0;

	if (spk_defined() == false) {
		pr_err("Invalid spk handle or no spk_chip\n");
		return -ENODEV;
	}

	addr = the_spk_chip->base + PM8XXX_SPK_TEST_REG_1_OFF;
	val = pm8xxx_spk_read(PM8XXX_SPK_CTL1_REG_OFF);
	if (val < 0)
		return val;
	if (enable)
		val |= (1 << 3);
	else
		val &= ~(1 << 3);
	ret = pm8xxx_spk_write(PM8XXX_SPK_CTL1_REG_OFF, val);
	if (!ret)
		ret = pm8xxx_spk_bank_write(addr, 6, PWM_EN_MASK);
	return ret;
}
EXPORT_SYMBOL_GPL(pm8xxx_spk_enable);

static int pm8xxx_spk_config(void)
{
	u16 addr;
	int ret = 0;

	if (spk_defined() == false) {
		pr_err("Invalid spk handle or no spk_chip\n");
		return -ENODEV;
	}

	addr = the_spk_chip->base + PM8XXX_SPK_TEST_REG_1_OFF;
	ret = pm8xxx_spk_bank_write(addr, 6, PWM_EN_MASK & 0);
	if (!ret)
		ret = pm8xxx_spk_gain(PM8XXX_SPK_GAIN);
	return ret;
}

static int pm8xxx_spk_probe(struct platform_device *pdev)
{
	const struct pm8xxx_spk_platform_data *pdata = pdev->dev.platform_data;
	int ret = 0;
	u8 value = 0;

	if (!pdata) {
		pr_err("missing platform data\n");
		return -EINVAL;
	}

	the_spk_chip = kzalloc(sizeof(struct pm8xxx_spk_chip), GFP_KERNEL);
	if (the_spk_chip == NULL) {
		pr_err("kzalloc() failed.\n");
		return -ENOMEM;
	}

	mutex_init(&the_spk_chip->spk_mutex);

	the_spk_chip->dev = &pdev->dev;
	the_spk_chip->version = pm8xxx_get_version(the_spk_chip->dev->parent);
	switch (pm8xxx_get_version(the_spk_chip->dev->parent)) {
	case PM8XXX_VERSION_8038:
		break;
	default:
		ret = -ENODEV;
		goto err_handle;
	}

	memcpy(&(the_spk_chip->pdata), pdata,
			sizeof(struct pm8xxx_spk_platform_data));

	the_spk_chip->base = pdev->resource[0].start;
	the_spk_chip->end = pdev->resource[0].end;

	if (the_spk_chip->pdata.spk_add_enable) {
		int val;
		val = pm8xxx_spk_read(PM8XXX_SPK_CTL1_REG_OFF);
		if (val < 0) {
			ret = val;
			goto err_handle;
		}
		val |= (the_spk_chip->pdata.spk_add_enable & PM8XXX_ADD_EN);
		ret = pm8xxx_spk_write(PM8XXX_SPK_CTL1_REG_OFF, val);
		if (ret < 0)
			goto err_handle;
	}
	value = ((the_spk_chip->pdata.cd_ng_threshold << 5) |
		the_spk_chip->pdata.cd_nf_preamp_bias << 3);
	pr_debug("Setting SPK_CTL2_REG = %02x\n", value);
	pm8xxx_spk_write(PM8XXX_SPK_CTL2_REG_OFF, value);

	value = ((the_spk_chip->pdata.cd_ng_hold << 5) |
		(the_spk_chip->pdata.cd_ng_max_atten << 1) |
		the_spk_chip->pdata.noise_mute);
	pr_debug("Setting SPK_CTL3_REG = %02x\n", value);
	pm8xxx_spk_write(PM8XXX_SPK_CTL3_REG_OFF, value);

	value = ((the_spk_chip->pdata.cd_ng_decay_rate << 5) |
		(the_spk_chip->pdata.cd_ng_attack_rate << 3) |
		the_spk_chip->pdata.cd_delay << 2);
	pr_debug("Setting SPK_CTL4_REG = %02x\n", value);
	pm8xxx_spk_write(PM8XXX_SPK_CTL4_REG_OFF, value);

	return pm8xxx_spk_config();
err_handle:
	pr_err("pm8xxx_spk_probe failed."
			"Audio unavailable on speaker.\n");
	mutex_destroy(&the_spk_chip->spk_mutex);
	kfree(the_spk_chip);
	return ret;
}

static int pm8xxx_spk_remove(struct platform_device *pdev)
{
	if (spk_defined() == false) {
		pr_err("Invalid spk handle or no spk_chip\n");
		return -ENODEV;
	}
	mutex_destroy(&the_spk_chip->spk_mutex);
	kfree(the_spk_chip);
	return 0;
}

static struct platform_driver pm8xxx_spk_driver = {
	.probe		= pm8xxx_spk_probe,
	.remove		= pm8xxx_spk_remove,
	.driver		= {
		.name = PM8XXX_SPK_DEV_NAME,
		.owner = THIS_MODULE,
	},
};

static int __init pm8xxx_spk_init(void)
{
	return platform_driver_register(&pm8xxx_spk_driver);
}
subsys_initcall(pm8xxx_spk_init);

static void __exit pm8xxx_spk_exit(void)
{
	platform_driver_unregister(&pm8xxx_spk_driver);
}
module_exit(pm8xxx_spk_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("PM8XXX SPK driver");
MODULE_ALIAS("platform:" PM8XXX_SPK_DEV_NAME);
