/*
 * ASRMicro SLIC driver
 *
 * Copyright (C) 2020 ASR Microelectronic Ltd.
 *
 * Author: Jackie Fan <yuanchunfan@asrmicro.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * 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.
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/regulator/machine.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/edge_wakeup_mmp.h>
#include <linux/mfd/88pm80x.h>

#define SLIC_STATUS_LENS 8

static int g_reset_n_gpio = -1;
static int g_edge_wakeup_gpio = -1;
static int g_vdd_3v3_gpio = -1;

struct microsemi_slic_info {
	struct device *dev;
	char chip_status[SLIC_STATUS_LENS];
	char reset_status[SLIC_STATUS_LENS];
	int reset_n_gpio;
	int edge_wakeup_gpio;
	int vdd_3v3_gpio;
	struct pinctrl *pinctrl;
	struct pinctrl_state *pin_lpm_drv_low;
	struct pinctrl_state *pin_lpm_drv_high;
	struct regulator *vdd_3v3;
};

static void slic_power_on(struct microsemi_slic_info *info)
{
	if (!strncmp(info->chip_status, "on", 2)) {
		dev_info(info->dev, "slic chip already powered on\n");
		return;
	}

	if (info->vdd_3v3 > 0) {
		if (regulator_set_voltage(info->vdd_3v3, 3300000, 3300000))
			pr_err("fail to set regulator wib_3v3 supply 2 to 3.3v\n");
		if (regulator_enable(info->vdd_3v3))
			pr_err("fail to enable regulator vdd_3v3\n");
	}

	if (info->vdd_3v3_gpio >= 0) {
		gpio_direction_output(info->vdd_3v3_gpio, 1);
	}

	usleep_range(65, 70);

	if (info->reset_n_gpio >= 0) {
		gpio_direction_output(info->reset_n_gpio, 1);
		strncpy(info->reset_status, "high", 5);
	}

	strncpy(info->chip_status, "on", 3);

	if (info->vdd_3v3 > 0) {
		buck2_ldo8_sleepmode_control_for_slic(1);
	}

	dev_info(info->dev, "slic chip powered on\n");
}

static void slic_power_off(struct microsemi_slic_info *info)
{
	if (!strncmp(info->chip_status, "off", 3)) {
		dev_info(info->dev, "slic chip already powered off\n");
		return;
	}

	if (info->vdd_3v3 > 0) {
		if (regulator_disable(info->vdd_3v3))
			pr_err("fail to disable regulator vdd_3v3\n");
	}

	if (info->vdd_3v3_gpio >= 0) {
		gpio_direction_output(info->vdd_3v3_gpio, 0);
	}

	if (info->reset_n_gpio >= 0) {
		gpio_direction_output(info->reset_n_gpio, 0);
		strncpy(info->reset_status, "low", 4);
	}

	strncpy(info->chip_status, "off", 4);

	if (info->vdd_3v3 > 0) {
		buck2_ldo8_sleepmode_control_for_slic(0);
	}

	dev_info(info->dev, "slic chip powered off\n");
}

static void slic_reset(struct microsemi_slic_info *info, int flag)
{
	if (info->reset_n_gpio >= 0) {
		gpio_direction_output(info->reset_n_gpio, flag);
		sprintf(info->reset_status, "%s", flag ? "high" : "low");
		dev_info(info->dev, "slic chip reset_n set to %s\n", flag ? "high" : "low");
	}
}

static ssize_t slic_ctrl(struct device *dev,
			struct device_attribute *attr,
			const char *buf, size_t count)
{
	static char msg[64];
	int flag, ret;

	struct microsemi_slic_info *info = dev_get_drvdata(dev);

	count = (count > 64) ? 64 : count;
	memset(msg, 0, count);

	if (!strncmp(buf, "off", 3)) {
		slic_power_off(info);
	} else if (!strncmp(buf, "on", 2)) {
		slic_power_on(info);
	} else if (!strncmp(buf, "reset", 5)) {
		ret = sscanf(buf, "%s %d", msg, &flag);
		if (ret == 2)
			slic_reset(info, flag);
	} else
		dev_info(info->dev, "usage wrong\n");

	return count;
}

static ssize_t slic_status(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct microsemi_slic_info *info = dev_get_drvdata(dev);

	return sprintf(buf, "power: %s, reset_n: %s\n", info->chip_status,
		info->reset_status);
}

static DEVICE_ATTR(ctrl, S_IWUSR, slic_status, slic_ctrl);
static DEVICE_ATTR(status, S_IRUSR, slic_status, NULL);

static const struct attribute *slic_attrs[] = {
	&dev_attr_ctrl.attr,
	&dev_attr_status.attr,
	NULL,
};

static const struct attribute_group slic_attr_group = {
	.attrs = (struct attribute **)slic_attrs,
};

#ifdef CONFIG_OF
static int microsemi_slic_dt_init(struct device_node *np,
			   struct device *dev,
			   struct microsemi_slic_info *info)
{

	struct regulator *vdd_3v3 = NULL;

	info->reset_n_gpio =
		of_get_named_gpio(dev->of_node, "rst-gpio", 0);
	if (info->reset_n_gpio < 0) {
		dev_err(dev, "%s: of_get_named_gpio failed: %d\n", __func__,
		       info->reset_n_gpio);
		info->reset_n_gpio = -1;
	}

	info->edge_wakeup_gpio =
		of_get_named_gpio(dev->of_node, "edge-wakeup-gpio", 0);
	if (info->edge_wakeup_gpio < 0) {
		dev_err(dev, "%s: of_get_named_gpio failed: %d\n", __func__,
		       info->edge_wakeup_gpio);
		info->edge_wakeup_gpio = -1;
		goto out;
	}

	info->vdd_3v3_gpio = of_get_named_gpio(dev->of_node, "vdd-3v3-gpio", 0);
	if (info->vdd_3v3_gpio < 0) {
		dev_err(dev, "%s: of_get_named_gpio failed: %d\n", __func__, info->vdd_3v3_gpio);
		info->vdd_3v3_gpio = -1;
	}

	g_reset_n_gpio = info->reset_n_gpio;
	g_edge_wakeup_gpio = info->edge_wakeup_gpio;
	g_vdd_3v3_gpio = info->vdd_3v3_gpio;

	printk(KERN_INFO"%s: reset_n_gpio=%d, edge_wakeup_gpio=%d, vdd_3v3_gpio=%d, %s.\n",
                         __FUNCTION__, info->reset_n_gpio, info->edge_wakeup_gpio, info->vdd_3v3_gpio, (info->vdd_3v3_gpio < 0)?"ASR1826 Old DKB":"ASR1826 New DKB");

	printk(KERN_INFO"%s: g_reset_n_gpio=%d, g_edge_wakeup_gpio=%d, g_vdd_3v3_gpio=%d.\n",
                         __FUNCTION__, g_reset_n_gpio, g_edge_wakeup_gpio, g_vdd_3v3_gpio);

	vdd_3v3 = regulator_get(dev, "vdd33");
	if (IS_ERR_OR_NULL(vdd_3v3)) {
		if (PTR_ERR(vdd_3v3) < 0) {
			pr_info("%s: the regulator for vdd_3v3 not found\n", __func__);
		}
	} else {
		info->vdd_3v3 = vdd_3v3;
	}

	return 0;
out:
	return -EINVAL;
}
#else
static int microsemi_slic_dt_init(struct device_node *np,
			   struct device *dev,
			   struct microsemi_slic_info *info)
{
	return 0;
}
#endif

/* microsemi_slic_ctrl */
static struct dentry *microsemi_slic_ctrl = NULL;

static ssize_t microsemi_slic_ctrl_read(struct file *file, char __user *user_buf,
        size_t count, loff_t *ppos)
{

    printk(KERN_INFO"%s/L%d.\n", __FUNCTION__, __LINE__);

    return 0;
}

/*
 *control command:
 *
 *Disable VDD 3V3: echo 0 > /sys/kernel/debug/microsemi_slic_ctrl
 *Enable VDD 3V3: echo 1 > /sys/kernel/debug/microsemi_slic_ctrl
 *
 *
 */
static char msg[10];

static ssize_t microsemi_slic_ctrl_write(struct file *file,
        const char __user *user_buf,
        size_t count, loff_t *ppos)
{
    int ret = 0;
    size_t tmp_count = 0;

    printk(KERN_INFO"%s/L%d.\n", __FUNCTION__, __LINE__);

    memset(msg, 0x00, sizeof(msg));
    tmp_count = count;

    if (tmp_count >= sizeof(msg)){
        tmp_count = sizeof(msg) - 1;
    }

    /* copy the content from user space to kernel space */
    ret = copy_from_user(msg, user_buf, tmp_count);
    if (ret){
        printk(KERN_ALERT"copy from user fail \n");
        return -EFAULT;
    }

    switch (msg[0]){
        case '0':/* input command# echo 0 > /sys/kernel/debug/microsemi_slic_ctrl */
            printk(KERN_INFO "input %c. \n", msg[0]);
            if (g_vdd_3v3_gpio >= 0) {
                gpio_direction_output(g_vdd_3v3_gpio, 0);
            }
            printk(KERN_INFO "Disable VDD 3V3 for ASR1826 New DKB.\n");
            break;

        case '1':/* input command# echo 1 > /sys/kernel/debug/microsemi_slic_ctrl */
            printk(KERN_INFO "input %c. \n", msg[0]);
            if (g_vdd_3v3_gpio >= 0) {
                gpio_direction_output(g_vdd_3v3_gpio, 1);
            }
            printk(KERN_INFO "Enable VDD 3V3 for ASR1826 New DKB.\n");
            break;

        case '2':/* input command# echo 2 > /sys/kernel/debug/microsemi_slic_ctrl */
            printk(KERN_INFO "input %c. \n", msg[0]);
            break;

        default:/* input command#  */
            printk(KERN_INFO "input invalid. \n");
            break;
    }

    return tmp_count;
}

static const struct file_operations microsemi_slic_ctrl_ops = {
    .owner      = THIS_MODULE,
    .open       = simple_open,
    .read       = microsemi_slic_ctrl_read,
    .write      = microsemi_slic_ctrl_write,
};

static inline int microsemi_slic_ctrl_debugfs_init(void)
{

    microsemi_slic_ctrl = debugfs_create_file("microsemi_slic_ctrl", S_IRUGO | S_IFREG,
            NULL, NULL, &microsemi_slic_ctrl_ops);

    if (microsemi_slic_ctrl == NULL) {
        pr_err("create microsemi_slic_ctrl debugfs error!\n");
        return -ENOENT;
    } else if (microsemi_slic_ctrl == ERR_PTR(-ENODEV)) {
        pr_err("CONFIG_DEBUG_FS is not enabled!\n");
        return -ENOENT;
    }

    return 0;
}

static void microsemi_slic_ctrl_debugfs_remove(void)
{
    if (NULL != microsemi_slic_ctrl){
        debugfs_remove_recursive(microsemi_slic_ctrl);
    }

    return;
}

static int microsemi_slic_probe(struct platform_device *pdev)
{
	struct microsemi_slic_info *info;

	struct device_node *np = pdev->dev.of_node;
	int ret;

	printk(KERN_INFO "enter %s. \n", __FUNCTION__);

	info = devm_kzalloc(&pdev->dev, sizeof(struct microsemi_slic_info),
						GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	memset(info, 0x00, sizeof(struct microsemi_slic_info));
	info->reset_n_gpio = -1;
	info->edge_wakeup_gpio = -1;
	info->vdd_3v3_gpio = -1;

	if (IS_ENABLED(CONFIG_OF)) {
		ret = microsemi_slic_dt_init(np, &pdev->dev, info);
		if (ret) {
			dev_err(&pdev->dev, "SLIC probe failed!\n");
			return ret;
		}
	} else {
		dev_err(&pdev->dev, "SLIC Not support DT, exit!\n");
		return -EINVAL;
	}

	info->dev = &pdev->dev;

	if (info->reset_n_gpio >= 0) {
		ret = devm_gpio_request(info->dev,
				info->reset_n_gpio, "slic_rst");
		if (ret) {
			dev_err(info->dev,
				"request gpio %d failed\n", info->reset_n_gpio);
			return ret;
		}
	}

	/* use microsemi-slic as wakeup source */
	device_init_wakeup(&pdev->dev, 1);

	if (info->edge_wakeup_gpio >= 0) {
		ret = request_mfp_edge_wakeup(info->edge_wakeup_gpio,
					      NULL, info, info->dev);
		if (ret) {
			dev_err(info->dev, "failed to request edge wakeup.\n");
			remove_mfp_edge_wakeup(info->edge_wakeup_gpio);
			return ret;
		}
	}

	if (info->vdd_3v3_gpio >= 0) {
		ret = devm_gpio_request(info->dev, info->vdd_3v3_gpio, "vdd_3v3");
		if (ret) {
			dev_err(info->dev, "request gpio %d failed\n", info->vdd_3v3_gpio);
			return ret;
		}
	}

	slic_power_on(info);
	strncpy(info->chip_status, "on", 3);

	platform_set_drvdata(pdev, info);

	ret = sysfs_create_group(&pdev->dev.kobj, &slic_attr_group);
	if (ret) {
		dev_err(&pdev->dev, "SLIC create sysfs fail!\n");
		return ret;
	}

	/* init debug tool */
	microsemi_slic_ctrl_debugfs_init();
	return 0;
}

static int microsemi_slic_remove(struct platform_device *pdev)
{
	printk(KERN_INFO "enter %s. \n", __FUNCTION__);

	sysfs_remove_group(&pdev->dev.kobj, &slic_attr_group);

	microsemi_slic_ctrl_debugfs_remove();
	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id microsemi_slic_dt_match[] = {
	{ .compatible = "asr,microsemi-slic", },
	{},
};
#endif

static struct platform_driver microsemi_slic_driver = {
	.driver		= {
		.name	= "microsemi-slic",
		.owner	= THIS_MODULE,
#ifdef CONFIG_OF
		.of_match_table = of_match_ptr(microsemi_slic_dt_match),
#endif
	},
	.probe		= microsemi_slic_probe,
	.remove		= microsemi_slic_remove,
};

static int microsemi_slic_init(void)
{
	return platform_driver_register(&microsemi_slic_driver);
}

static void microsemi_slic_exit(void)
{
	platform_driver_unregister(&microsemi_slic_driver);
}
module_init(microsemi_slic_init);
module_exit(microsemi_slic_exit);

MODULE_AUTHOR("Jackie Fan<yuanchunfan@asrmicro.com>");
MODULE_DESCRIPTION("driver for Microsemi SLIC solution");
MODULE_LICENSE("GPL v2");
