/* 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 __devinit 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 __devexit 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		= __devexit_p(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);
