// SPDX-License-Identifier: GPL-2.0
/*
 * Support for atomisp driver sysfs interface
 *
 * Copyright (c) 2014 Intel Corporation. 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 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/device.h>
#include <linux/err.h>
#include <linux/kernel.h>

#include "atomisp_compat.h"
#include "atomisp_internal.h"
#include "atomisp_ioctl.h"
#include "atomisp_drvfs.h"
#include "hmm/hmm.h"
#include "ia_css_debug.h"

/*
 * _iunit_debug:
 * dbglvl: iunit css driver trace level
 * dbgopt: iunit debug option:
 *        bit 0: binary list
 *        bit 1: running binary
 *        bit 2: memory statistic
*/
struct _iunit_debug {
	struct device_driver	*drv;
	struct atomisp_device	*isp;
	unsigned int		dbglvl;
	unsigned int		dbgfun;
	unsigned int		dbgopt;
};

#define OPTION_BIN_LIST			BIT(0)
#define OPTION_BIN_RUN			BIT(1)
#define OPTION_VALID			(OPTION_BIN_LIST \
					| OPTION_BIN_RUN)

static struct _iunit_debug iunit_debug = {
	.dbglvl = 0,
	.dbgopt = OPTION_BIN_LIST,
};

static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
				    unsigned int opt)
{
	int ret = 0;

	if (opt & OPTION_VALID) {
		if (opt & OPTION_BIN_LIST) {
			ret = atomisp_css_dump_blob_infor(isp);
			if (ret) {
				dev_err(isp->dev, "%s dump blob infor err[ret:%d]\n",
					__func__, ret);
				goto opt_err;
			}
		}

		if (opt & OPTION_BIN_RUN) {
			if (isp->asd.streaming) {
				atomisp_css_dump_sp_raw_copy_linecount(true);
				atomisp_css_debug_dump_isp_binary();
			} else {
				ret = -EPERM;
				dev_err(isp->dev, "%s dump running bin err[ret:%d]\n",
					__func__, ret);
				goto opt_err;
			}
		}
	} else {
		ret = -EINVAL;
		dev_err(isp->dev, "%s dump nothing[ret=%d]\n", __func__, ret);
	}

opt_err:
	return ret;
}

static ssize_t iunit_dbglvl_show(struct device_driver *drv, char *buf)
{
	iunit_debug.dbglvl = dbg_level;
	return sysfs_emit(buf, "dtrace level:%u\n", iunit_debug.dbglvl);
}

static ssize_t iunit_dbglvl_store(struct device_driver *drv, const char *buf,
				  size_t size)
{
	if (kstrtouint(buf, 10, &iunit_debug.dbglvl)
	    || iunit_debug.dbglvl < 1
	    || iunit_debug.dbglvl > 9) {
		return -ERANGE;
	}
	ia_css_debug_set_dtrace_level(iunit_debug.dbglvl);

	return size;
}

static ssize_t iunit_dbgfun_show(struct device_driver *drv, char *buf)
{
	iunit_debug.dbgfun = atomisp_get_css_dbgfunc();
	return sysfs_emit(buf, "dbgfun opt:%u\n", iunit_debug.dbgfun);
}

static ssize_t iunit_dbgfun_store(struct device_driver *drv, const char *buf,
				  size_t size)
{
	unsigned int opt;
	int ret;

	ret = kstrtouint(buf, 10, &opt);
	if (ret)
		return ret;

	ret = atomisp_set_css_dbgfunc(iunit_debug.isp, opt);
	if (ret)
		return ret;

	iunit_debug.dbgfun = opt;

	return size;
}

static ssize_t iunit_dbgopt_show(struct device_driver *drv, char *buf)
{
	return sysfs_emit(buf, "option:0x%x\n", iunit_debug.dbgopt);
}

static ssize_t iunit_dbgopt_store(struct device_driver *drv, const char *buf,
				  size_t size)
{
	unsigned int opt;
	int ret;

	ret = kstrtouint(buf, 10, &opt);
	if (ret)
		return ret;

	iunit_debug.dbgopt = opt;
	ret = iunit_dump_dbgopt(iunit_debug.isp, iunit_debug.dbgopt);
	if (ret)
		return ret;

	return size;
}

static const struct driver_attribute iunit_drvfs_attrs[] = {
	__ATTR(dbglvl, 0644, iunit_dbglvl_show, iunit_dbglvl_store),
	__ATTR(dbgfun, 0644, iunit_dbgfun_show, iunit_dbgfun_store),
	__ATTR(dbgopt, 0644, iunit_dbgopt_show, iunit_dbgopt_store),
};

static int iunit_drvfs_create_files(struct device_driver *drv)
{
	int i, ret = 0;

	for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
		ret |= driver_create_file(drv, &iunit_drvfs_attrs[i]);

	return ret;
}

static void iunit_drvfs_remove_files(struct device_driver *drv)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
		driver_remove_file(drv, &iunit_drvfs_attrs[i]);
}

int atomisp_drvfs_init(struct atomisp_device *isp)
{
	struct device_driver *drv = isp->dev->driver;
	int ret;

	iunit_debug.isp = isp;
	iunit_debug.drv = drv;

	ret = iunit_drvfs_create_files(iunit_debug.drv);
	if (ret) {
		dev_err(isp->dev, "drvfs_create_files error: %d\n", ret);
		iunit_drvfs_remove_files(iunit_debug.drv);
	}

	return ret;
}

void atomisp_drvfs_exit(void)
{
	iunit_drvfs_remove_files(iunit_debug.drv);
}
