/**
 * sec-detect-conn.c
 *
 * Copyright (C) 2017 Samsung Electronics
 *
 * 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.
 *
 */

#define DEBUG_FOR_SECDETECT
#include <linux/sec-detect-conn.h>

static int detect_conn_enabled;
struct detect_conn_info *gpinfo;

#define SEC_CONN_PRINT(format, ...) pr_info("[SEC_Detect_Conn] " format, ##__VA_ARGS__)

#if defined(CONFIG_SEC_FACTORY)
#ifdef CONFIG_OF
static const struct of_device_id sec_detect_conn_dt_match[] = {
	{ .compatible = "samsung,sec_detect_conn" },
	{ }
};
#endif

static int sec_detect_conn_pm_suspend(struct device *dev)
{
	return 0;
}

static int sec_detect_conn_pm_resume(struct device *dev)
{
	return 0;
}

static int sec_detect_conn_remove(struct platform_device *pdev)
{
	return 0;
}

static const struct dev_pm_ops sec_detect_conn_pm = {
	.suspend = sec_detect_conn_pm_suspend,
	.resume = sec_detect_conn_pm_resume,
};

/**
 * Send uevent from irq handler.
 */
void send_uevent_irq(int irq, struct detect_conn_info *pinfo, int type)
{
	char *uevent_conn_str[3] = {"", "", NULL};
	char uevent_dev_str[UEVENT_CONN_MAX_DEV_NAME];
	char uevent_dev_type_str[UEVENT_CONN_MAX_DEV_NAME];
	int i;

	/*Send Uevent Data*/
	for (i = 0; i < pinfo->pdata->gpio_cnt; i++) {
		if (irq == pinfo->pdata->irq_number[i]) {
			if (gpio_get_value(pinfo->pdata->irq_gpio[i])) {
				SEC_CONN_PRINT("%s status changed.\n", pinfo->pdata->name[i]);

				sprintf(uevent_dev_str, "CONNECTOR_NAME=%s", pinfo->pdata->name[i]);
				if (type == IRQ_TYPE_EDGE_RISING) {
					sprintf(uevent_dev_type_str, "CONNECTOR_TYPE=RISING_EDGE");
					SEC_CONN_PRINT("send uevent irq[%d]:CONNECTOR_NAME=%s,CONNECTOR_TYPE=RISING_EDGE.\n"
						, irq, pinfo->pdata->name[i]);
				} else if (type == IRQ_TYPE_EDGE_FALLING) {
					sprintf(uevent_dev_type_str, "CONNECTOR_TYPE=FALLING_EDGE");
					SEC_CONN_PRINT("send uevent irq[%d]:CONNECTOR_NAME=%s,CONNECTOR_TYPE=FALLING_EDGE.\n"
						, irq, pinfo->pdata->name[i]);
				} else if (type == IRQ_TYPE_EDGE_BOTH) {
					sprintf(uevent_dev_type_str, "CONNECTOR_TYPE=EDGE_BOTH");
					SEC_CONN_PRINT("send uevent irq[%d]:CONNECTOR_NAME=%s,CONNECTOR_TYPE=ALL_EDGE.\n"
						, irq, pinfo->pdata->name[i]);
				} else {
					SEC_CONN_PRINT("Err:Unknown type irq : irq[%d]:CONNECTOR_NAME=%s,CONNECTOR_TYPE=%d.\n"
						, irq, pinfo->pdata->name[i], type);
					return;
				}
				uevent_conn_str[0] = uevent_dev_str;
				uevent_conn_str[1] = uevent_dev_type_str;

				kobject_uevent_env(&pinfo->dev->kobj, KOBJ_CHANGE, uevent_conn_str);
			}
		}
	}
}

/**
 * Send an uevent about given gpio pin number.
 */
void send_uevent_by_num(int num, struct detect_conn_info *pinfo, int level)
{
	char *uevent_conn_str[3] = {"", "", NULL};
	char uevent_dev_str[UEVENT_CONN_MAX_DEV_NAME];
	char uevent_dev_type_str[UEVENT_CONN_MAX_DEV_NAME];

	/*Send Uevent Data*/
	sprintf(uevent_dev_str, "CONNECTOR_NAME=%s", pinfo->pdata->name[num]);
	uevent_conn_str[0] = uevent_dev_str;
	if (level == 1)
		sprintf(uevent_dev_type_str, "CONNECTOR_TYPE=HIGH_LEVEL");
	else if (level == 0)
		sprintf(uevent_dev_type_str, "CONNECTOR_TYPE=LOW_LEVEL");

	uevent_conn_str[1] = uevent_dev_type_str;

	kobject_uevent_env(&pinfo->dev->kobj, KOBJ_CHANGE, uevent_conn_str);

	if (level == 1)
		SEC_CONN_PRINT("send uevent pin[%d]:CONNECTOR_NAME=%s,CONNECTOR_TYPE=HIGH_LEVEL.\n"
			, num, pinfo->pdata->name[num]);
	else if (level == 0)
		SEC_CONN_PRINT("send uevent pin[%d]:CONNECTOR_NAME=%s,CONNECTOR_TYPE=LOW_LEVEL.\n"
			, num, pinfo->pdata->name[num]);
}

/**
 * Called when the connector pin state changes.
 */
static irqreturn_t detect_conn_interrupt_handler(int irq, void *handle)
{
	int type;
	struct detect_conn_info *pinfo = handle;

	if (detect_conn_enabled != 0) {
		SEC_CONN_PRINT("%s\n", __func__);

		type = irq_get_trigger_type(irq);
		send_uevent_irq(irq, pinfo, type);
	}

	return IRQ_HANDLED;
}

/**
 * Enable all gpio pin IRQ which is from Device Tree.
 */
int detect_conn_irq_enable(struct detect_conn_info *pinfo, bool enable, int pin)
{
	int retval = 0;
	int i;

	if (enable) {
		/*enable IRQ*/
		enable_irq(pinfo->pdata->irq_number[pin]);
		pinfo->irq_enabled[pin] = true;
	} else {
		for (i = 0; i < pinfo->pdata->gpio_cnt; i++) {
			if (pinfo->irq_enabled[i]) {
				disable_irq(pinfo->pdata->irq_number[i]);
				pinfo->irq_enabled[i] = false;
			}
		}
	}

	return retval;
}

/**
 * Triggered when "enabled" node is set.
 * When enabling this node, check and send an uevent if the pin level is high.
 * And then gpio pin interrupt is enabled.
 */
static ssize_t store_detect_conn_enabled(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct detect_conn_info *pinfo;
	struct sec_det_conn_p_data *pdata;
	int ret;
	int i;
	int bufLength;
	int pinNameLength;

	if (gpinfo == 0)
		return -1;

	pinfo = gpinfo;
	pdata = pinfo->pdata;

	bufLength = strlen(buf);
#if defined(DEBUG_FOR_SECDETECT)
	SEC_CONN_PRINT("buf = %s\n", buf);
	SEC_CONN_PRINT("bufLength = %d\n", bufLength);
#endif

	/*Disable irq when "enabled" value set to 0*/
	if (!strncmp(buf, "0", 1)) {
		SEC_CONN_PRINT("SEC Detect connector driver disable.\n");
		detect_conn_enabled = 0;

		ret = detect_conn_irq_enable(pinfo, false, 0);

		if (ret) {
			SEC_CONN_PRINT("Interrupt not disabled.\n");
			return ret;
		}

	} else {
		for (i = 0; i < pdata->gpio_cnt; i++) {
			pinNameLength = strlen(pdata->name[i]);
#if defined(DEBUG_FOR_SECDETECT)
			SEC_CONN_PRINT("pinName = %s\n", pdata->name[i]);
			SEC_CONN_PRINT("pinNameLength = %d\n", pinNameLength);
#endif
			if (pinNameLength == bufLength) {
				if (!strncmp(buf, pdata->name[i], bufLength)) {
					SEC_CONN_PRINT("%s driver enabled.\n", buf);
					detect_conn_enabled |= (1 << i);

#if defined(DEBUG_FOR_SECDETECT)
					SEC_CONN_PRINT("gpio level [%d] = %d\n", pdata->irq_gpio[i],
						gpio_get_value(pdata->irq_gpio[i]));
#endif
					/*get level value of the gpio pin.*/
					/*if there's gpio low pin, send uevent*/
					if (gpio_get_value(pdata->irq_gpio[i]))
						send_uevent_by_num(i, pinfo, 1);
					else
						send_uevent_by_num(i, pinfo, 0);

					/*Enable interrupt.*/
					ret = detect_conn_irq_enable(pinfo, true, i);

					if (ret < 0) {
						SEC_CONN_PRINT("%s Interrupt not enabled.\n", buf);
						return ret;
					}
				}
			}

			/* For ALL_CONNECT input, enable all nodes except already enabled node. */
			if (bufLength == 11) {
				if (!strncmp(buf, "ALL_CONNECT", bufLength)) {
					if (!(detect_conn_enabled & (1 << i))) {
						SEC_CONN_PRINT("%s driver enabled.\n", buf);
						detect_conn_enabled |= (1 << i);

#if defined(DEBUG_FOR_SECDETECT)
						SEC_CONN_PRINT("gpio level [%d] = %d\n", pdata->irq_gpio[i],
							gpio_get_value(pdata->irq_gpio[i]));
#endif
						/*get level value of the gpio pin.*/
						/*if there's gpio low pin, send uevent*/
						if (gpio_get_value(pdata->irq_gpio[i]))
							send_uevent_by_num(i, pinfo, 1);
						else
							send_uevent_by_num(i, pinfo, 0);

						/*Enable interrupt.*/
						ret = detect_conn_irq_enable(pinfo, true, i);

						if (ret < 0) {
							SEC_CONN_PRINT("%s Interrupt not enabled.\n", buf);
							return ret;
						}
					}
				}
			}
		}
	}

	return count;
}

static ssize_t show_detect_conn_enabled(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return sprintf(buf, "%d\n", detect_conn_enabled);
}

static DEVICE_ATTR(enabled, 0644, show_detect_conn_enabled, store_detect_conn_enabled);

static ssize_t show_detect_conn_available_pins(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return sprintf(buf, "%s\n", sec_detect_available_pins_string);
}

static DEVICE_ATTR(available_pins, 0444, show_detect_conn_available_pins, NULL);

#ifdef CONFIG_OF
/**
 * Parse the device tree and get gpio number, irq type.
 * Request gpio
 */
static int detect_conn_parse_dt(struct device *dev)
{
	struct sec_det_conn_p_data *pdata = dev->platform_data;
	struct device_node *np = dev->of_node;
	int i;

	pdata->gpio_cnt = of_gpio_named_count(np, "sec,det_conn_gpios");

	for (i = 0; i < pdata->gpio_cnt; i++) {
		/*Get connector name*/
		of_property_read_string_index(np, "sec,det_conn_name", i, &(pdata->name[i]));

		/*Get connector gpio number*/
		pdata->irq_gpio[i] = of_get_named_gpio(np, "sec,det_conn_gpios", i);

		if (gpio_is_valid(pdata->irq_gpio[i])) {
#if defined(DEBUG_FOR_SECDETECT)
			SEC_CONN_PRINT("i = [%d] gpio level [%d] = %d\n", i, pdata->irq_gpio[i],
				gpio_get_value(pdata->irq_gpio[i]));
			SEC_CONN_PRINT("gpio irq gpio = [%d], irq = [%d]\n", pdata->irq_gpio[i],
			gpio_to_irq(pdata->irq_gpio[i]));
#endif
			/*Filling the irq_number from this gpio.*/
			pdata->irq_number[i] = gpio_to_irq(pdata->irq_gpio[i]);

		} else {
			dev_err(dev, "%s: Failed to get irq gpio.\n", __func__);
			return -EINVAL;
		}
	}

	/*Get type of gpio irq*/
	if (of_property_read_u32_array(np, "sec,det_conn_irq_type", pdata->irq_type, pdata->gpio_cnt)) {
		dev_err(dev, "%s, Failed to get irq_type property.\n", __func__);
		return -EINVAL;
	}

	return 0;
}
#endif

static int detect_conn_init_irq(void)
{
	struct detect_conn_info *pinfo;
	struct sec_det_conn_p_data *pdata;
	int retval = 0;
	int i;

	if (gpinfo == 0)
		return -1;

	pinfo = gpinfo;
	pdata = pinfo->pdata;


	for (i = 0; i < pinfo->pdata->gpio_cnt; i++) {
		retval = request_threaded_irq(pinfo->pdata->irq_number[i], NULL,
				detect_conn_interrupt_handler,
				pinfo->pdata->irq_type[i] | IRQF_ONESHOT,
				pinfo->pdata->name[i], pinfo);
			if (retval) {
				SEC_CONN_PRINT("%s: Failed to request threaded irq %d.\n",
						__func__, retval);
				return retval;
			}

#if defined(DEBUG_FOR_SECDETECT)
			SEC_CONN_PRINT("%s: Succeeded to request threaded irq %d: irq_num[%d], type[%x],name[%s].\n",
						__func__, retval, pinfo->pdata->irq_number[i],
						pinfo->pdata->irq_type[i], pinfo->pdata->name[i]);
#endif
		/*disable irq init*/
		disable_irq(pinfo->pdata->irq_number[i]);
	}

	return 0;

}
static int sec_detect_conn_item_make(void)
{
	struct detect_conn_info *pinfo;
	struct sec_det_conn_p_data *pdata;
	int i = 0;

	pinfo = gpinfo;
	pdata = pinfo->pdata;

	for (i = 0; i < pdata->gpio_cnt; i++) {
		strcat(sec_detect_available_pins_string,pdata->name[i]);
		strcat(sec_detect_available_pins_string, "/");
	}
	sec_detect_available_pins_string[strlen(sec_detect_available_pins_string)-1] = '\0';

	return 0;
}


static int sec_detect_conn_probe(struct platform_device *pdev)
{
	struct sec_det_conn_p_data *pdata;
	struct detect_conn_info *pinfo;
	int ret;

	SEC_CONN_PRINT("%s\n", __func__);

	/* First Get the GPIO pins; if it fails, we'll defer the probe. */
	if (pdev->dev.of_node) {
		pdata = devm_kzalloc(&pdev->dev,
				sizeof(struct sec_det_conn_p_data), GFP_KERNEL);

		if (!pdata) {
			dev_err(&pdev->dev, "Failed to allocate platform data.\n");
			return -ENOMEM;
		}

		pdev->dev.platform_data = pdata;
#if CONFIG_OF
		ret = detect_conn_parse_dt(&pdev->dev);
#else
		ret = 0;
#endif
		if (ret) {
			dev_err(&pdev->dev, "Failed to parse dt data.\n");
			kfree(pdata);
			return ret;
		}

		pr_info("%s: parse dt done.\n", __func__);
	} else {
		pdata = pdev->dev.platform_data;
	}

	if (!pdata) {
		dev_err(&pdev->dev, "There are no platform data.\n");
		return -EINVAL;
	}

	pinfo = devm_kzalloc(&pdev->dev, sizeof(struct detect_conn_info), GFP_KERNEL);

	if (!pinfo) {
		SEC_CONN_PRINT("pinfo : failed to allocate pinfo.\n");
		kfree(pdata);
		return -ENOMEM;
	}

	/* Create sys device /sys/class/sec/sec_detect_conn */
	pinfo->dev = sec_device_create(pinfo, "sec_detect_conn");

	if (unlikely(IS_ERR(pinfo->dev))) {
		pr_err("%s Failed to create device(sec_detect_conn).\n", __func__);
		ret = -ENODEV;
		goto out;
	}

	/* Create sys node /sys/class/sec/sec_detect_conn/enabled */
	ret = device_create_file(pinfo->dev, &dev_attr_enabled);

	if (ret) {
		dev_err(&pdev->dev, "%s: Failed to create device file.\n", __func__);
		goto err_create_detect_conn_sysfs;
	}

	/* Create sys node /sys/class/sec/sec_detect_conn/available_pins */
	ret = device_create_file(pinfo->dev, &dev_attr_available_pins);

	if (ret) {
		dev_err(&pdev->dev, "%s: Failed to create device file.\n", __func__);
		goto err_create_detect_conn_sysfs;
	}

	/*save pinfo data to pdata to interrupt enable*/
	pdata->pinfo = pinfo;

	/*save pdata data to pinfo for enable node*/
	pinfo->pdata = pdata;

	/* save pinfo to gpinfo to enabled node*/
	gpinfo = pinfo;

	/* detect_conn_init_irq thread create*/
	ret = detect_conn_init_irq();

	/* make sec_detect_conn item*/
	ret = sec_detect_conn_item_make();

	return ret;

err_create_detect_conn_sysfs:
	sec_device_destroy(pinfo->dev->devt);

out:
	gpinfo = 0;
	kfree(pinfo);
	kfree(pdata);

	return ret;
}

static struct platform_driver sec_detect_conn_driver = {
	.probe = sec_detect_conn_probe,
	.remove = sec_detect_conn_remove,
	.driver = {
		.name = "sec_detect_conn",
		.owner = THIS_MODULE,
#if defined(CONFIG_PM)
		.pm	= &sec_detect_conn_pm,
#endif
#if CONFIG_OF
		.of_match_table = of_match_ptr(sec_detect_conn_dt_match),
#endif
	},
};
#endif

static int __init sec_detect_conn_init(void)
{
#if defined(CONFIG_SEC_FACTORY)
	SEC_CONN_PRINT("%s\n", __func__);

	return platform_driver_register(&sec_detect_conn_driver);
#else
	SEC_CONN_PRINT("Not support Sec_Detect_Conn.\n");
	return 0;
#endif
}

static void __exit sec_detect_conn_exit(void)
{
#if defined(CONFIG_SEC_FACTORY)
	return platform_driver_unregister(&sec_detect_conn_driver);
#endif
}

module_init(sec_detect_conn_init);
module_exit(sec_detect_conn_exit);

MODULE_DESCRIPTION("Samsung Detecting Connector Driver");
MODULE_AUTHOR("Samsung Electronics");
MODULE_LICENSE("GPL");
