/* Copyright (c) 2018, 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)	"[msm-hdcp] %s: " fmt, __func__

#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/uaccess.h>
#include <linux/cdev.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/msm_hdcp.h>
#include <linux/of.h>

#define CLASS_NAME "hdcp"
#define DRIVER_NAME "msm_hdcp"

struct msm_hdcp {
	struct platform_device *pdev;
	dev_t dev_num;
	struct cdev cdev;
	struct class *class;
	struct device *device;
	struct HDCP_V2V1_MSG_TOPOLOGY cached_tp;
	u32 tp_msgid;
	void *client_ctx;
	void (*cb)(void *ctx, int data);
};

void msm_hdcp_register_cb(struct device *dev, void *ctx,
		void (*cb)(void *ctx, int data))
{
	struct msm_hdcp *hdcp = NULL;

	if (!dev) {
		pr_err("invalid device pointer\n");
		return;
	}

	hdcp = dev_get_drvdata(dev);
	if (!hdcp) {
		pr_err("invalid driver pointer\n");
		return;
	}

	hdcp->cb = cb;
	hdcp->client_ctx = ctx;
}

void msm_hdcp_notify_topology(struct device *dev)
{
	char *envp[4];
	char tp[SZ_16];
	char ver[SZ_16];
	struct msm_hdcp *hdcp = NULL;

	if (!dev) {
		pr_err("invalid device pointer\n");
		return;
	}

	hdcp = dev_get_drvdata(dev);
	if (!hdcp) {
		pr_err("invalid driver pointer\n");
		return;
	}

	snprintf(tp, SZ_16, "%d", DOWN_CHECK_TOPOLOGY);
	snprintf(ver, SZ_16, "%d", HDCP_V1_TX);

	envp[0] = "HDCP_MGR_EVENT=MSG_READY";
	envp[1] = tp;
	envp[2] = ver;
	envp[3] = NULL;

	kobject_uevent_env(&hdcp->device->kobj, KOBJ_CHANGE, envp);
}

void msm_hdcp_cache_repeater_topology(struct device *dev,
			struct HDCP_V2V1_MSG_TOPOLOGY *tp)
{
	struct msm_hdcp *hdcp = NULL;

	if (!dev || !tp) {
		pr_err("invalid input\n");
		return;
	}

	hdcp = dev_get_drvdata(dev);
	if (!hdcp) {
		pr_err("invalid driver pointer\n");
		return;
	}

	memcpy(&hdcp->cached_tp, tp,
		   sizeof(struct HDCP_V2V1_MSG_TOPOLOGY));
}

static ssize_t msm_hdcp_1x_sysfs_rda_tp(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	ssize_t ret = 0;
	struct msm_hdcp *hdcp = NULL;

	if (!dev) {
		pr_err("invalid device pointer\n");
		return -ENODEV;
	}

	hdcp = dev_get_drvdata(dev);
	if (!hdcp) {
		pr_err("invalid driver pointer\n");
		return -ENODEV;
	}

	switch (hdcp->tp_msgid) {
	case DOWN_CHECK_TOPOLOGY:
	case DOWN_REQUEST_TOPOLOGY:
		buf[MSG_ID_IDX]   = hdcp->tp_msgid;
		buf[RET_CODE_IDX] = HDCP_AUTHED;
		ret = HEADER_LEN;

		memcpy(buf + HEADER_LEN, &hdcp->cached_tp,
			   sizeof(struct HDCP_V2V1_MSG_TOPOLOGY));

		ret += sizeof(struct HDCP_V2V1_MSG_TOPOLOGY);

		/* clear the flag once data is read back to user space*/
		hdcp->tp_msgid = -1;
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}

static ssize_t msm_hdcp_1x_sysfs_wta_tp(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	int msgid = 0;
	ssize_t ret = count;
	struct msm_hdcp *hdcp = NULL;

	if (!dev) {
		pr_err("invalid device pointer\n");
		return -ENODEV;
	}

	hdcp = dev_get_drvdata(dev);
	if (!hdcp) {
		pr_err("invalid driver pointer\n");
		return -ENODEV;
	}

	msgid = buf[0];

	switch (msgid) {
	case DOWN_CHECK_TOPOLOGY:
	case DOWN_REQUEST_TOPOLOGY:
		hdcp->tp_msgid = msgid;
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}

static ssize_t msm_hdcp_2x_sysfs_wta_min_level_change(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	int rc;
	int min_enc_lvl;
	ssize_t ret = count;
	struct msm_hdcp *hdcp = NULL;

	if (!dev) {
		pr_err("invalid device pointer\n");
		return -ENODEV;
	}

	hdcp = dev_get_drvdata(dev);
	if (!hdcp) {
		pr_err("invalid driver pointer\n");
		return -ENODEV;
	}

	rc = kstrtoint(buf, 10, &min_enc_lvl);
	if (rc) {
		pr_err("kstrtoint failed. rc=%d\n", rc);
		return -EINVAL;
	}

	if (hdcp->cb && hdcp->client_ctx)
		hdcp->cb(hdcp->client_ctx, min_enc_lvl);

	return ret;
}

static DEVICE_ATTR(tp, 0644, msm_hdcp_1x_sysfs_rda_tp,
	msm_hdcp_1x_sysfs_wta_tp);

static DEVICE_ATTR(min_level_change, 0200, NULL,
	msm_hdcp_2x_sysfs_wta_min_level_change);

static struct attribute *msm_hdcp_fs_attrs[] = {
	&dev_attr_tp.attr,
	&dev_attr_min_level_change.attr,
	NULL
};

static struct attribute_group msm_hdcp_fs_attr_group = {
	.attrs = msm_hdcp_fs_attrs
};

static int msm_hdcp_open(struct inode *inode, struct file *file)
{
	return 0;
}

static int msm_hdcp_close(struct inode *inode, struct file *file)
{
	return 0;
}

static const struct file_operations msm_hdcp_fops = {
	.owner = THIS_MODULE,
	.open = msm_hdcp_open,
	.release = msm_hdcp_close,
};

static const struct of_device_id msm_hdcp_dt_match[] = {
	{ .compatible = "qcom,msm-hdcp",},
	{}
};

MODULE_DEVICE_TABLE(of, msm_hdcp_dt_match);

static int msm_hdcp_probe(struct platform_device *pdev)
{
	int ret;
	struct msm_hdcp *hdcp;

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

	hdcp->pdev = pdev;

	platform_set_drvdata(pdev, hdcp);

	ret = alloc_chrdev_region(&hdcp->dev_num, 0, 1, DRIVER_NAME);
	if (ret  < 0) {
		pr_err("alloc_chrdev_region failed ret = %d\n", ret);
		goto error_get_dev_num;
	}

	hdcp->class = class_create(THIS_MODULE, CLASS_NAME);
	if (IS_ERR(hdcp->class)) {
		ret = PTR_ERR(hdcp->class);
		pr_err("couldn't create class rc = %d\n", ret);
		goto error_class_create;
	}

	hdcp->device = device_create(hdcp->class, NULL,
		hdcp->dev_num, NULL, DRIVER_NAME);
	if (IS_ERR(hdcp->device)) {
		ret = PTR_ERR(hdcp->device);
		pr_err("device_create failed %d\n", ret);
		goto error_class_device_create;
	}

	cdev_init(&hdcp->cdev, &msm_hdcp_fops);
	ret = cdev_add(&hdcp->cdev, MKDEV(MAJOR(hdcp->dev_num), 0), 1);
	if (ret < 0) {
		pr_err("cdev_add failed %d\n", ret);
		goto error_cdev_add;
	}

	ret = sysfs_create_group(&hdcp->device->kobj, &msm_hdcp_fs_attr_group);
	if (ret)
		pr_err("unable to register msm_hdcp sysfs nodes\n");

	return 0;
error_cdev_add:
	device_destroy(hdcp->class, hdcp->dev_num);
error_class_device_create:
	class_destroy(hdcp->class);
error_class_create:
	unregister_chrdev_region(hdcp->dev_num, 1);
error_get_dev_num:
	devm_kfree(&pdev->dev, hdcp);
	hdcp = NULL;
	return ret;
}

static int msm_hdcp_remove(struct platform_device *pdev)
{
	struct msm_hdcp *hdcp;

	hdcp = platform_get_drvdata(pdev);
	if (!hdcp)
		return -ENODEV;

	sysfs_remove_group(&hdcp->device->kobj,
	&msm_hdcp_fs_attr_group);
	cdev_del(&hdcp->cdev);
	device_destroy(hdcp->class, hdcp->dev_num);
	class_destroy(hdcp->class);
	unregister_chrdev_region(hdcp->dev_num, 1);

	devm_kfree(&pdev->dev, hdcp);
	hdcp = NULL;
	return 0;
}

static struct platform_driver msm_hdcp_driver = {
	.probe = msm_hdcp_probe,
	.remove = msm_hdcp_remove,
	.driver = {
		.name = "msm_hdcp",
		.of_match_table = msm_hdcp_dt_match,
		.pm = NULL,
	}
};

static int __init msm_hdcp_init(void)
{
	return platform_driver_register(&msm_hdcp_driver);
}

static void __exit msm_hdcp_exit(void)
{
	return platform_driver_unregister(&msm_hdcp_driver);
}

module_init(msm_hdcp_init);
module_exit(msm_hdcp_exit);

MODULE_DESCRIPTION("MSM HDCP driver");
MODULE_LICENSE("GPL v2");
