// SPDX-License-Identifier: GPL-2.0-only
/*
 * Picvue PVC160206 display driver
 *
 * Brian Murphy <brian.murphy@eicon.com>
 *
 */
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>

#include <linux/timer.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>

#include "picvue.h"

static DEFINE_MUTEX(pvc_mutex);
static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
static int pvc_linedata[PVC_NLINES];
static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
#define DISPLAY_DIR_NAME "display"
static int scroll_dir, scroll_interval;

static struct timer_list timer;

static void pvc_display(unsigned long data)
{
	int i;

	pvc_clear();
	for (i = 0; i < PVC_NLINES; i++)
		pvc_write_string(pvc_lines[i], 0, i);
}

static DECLARE_TASKLET_OLD(pvc_display_tasklet, &pvc_display);

static int pvc_line_proc_show(struct seq_file *m, void *v)
{
	int lineno = *(int *)m->private;

	if (lineno < 0 || lineno >= PVC_NLINES) {
		printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno);
		return 0;
	}

	mutex_lock(&pvc_mutex);
	seq_printf(m, "%s\n", pvc_lines[lineno]);
	mutex_unlock(&pvc_mutex);

	return 0;
}

static int pvc_line_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, pvc_line_proc_show, PDE_DATA(inode));
}

static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf,
				   size_t count, loff_t *pos)
{
	int lineno = *(int *)PDE_DATA(file_inode(file));
	char kbuf[PVC_LINELEN];
	size_t len;

	BUG_ON(lineno < 0 || lineno >= PVC_NLINES);

	len = min(count, sizeof(kbuf) - 1);
	if (copy_from_user(kbuf, buf, len))
		return -EFAULT;
	kbuf[len] = '\0';

	if (len > 0 && kbuf[len - 1] == '\n')
		len--;

	mutex_lock(&pvc_mutex);
	strncpy(pvc_lines[lineno], kbuf, len);
	pvc_lines[lineno][len] = '\0';
	mutex_unlock(&pvc_mutex);

	tasklet_schedule(&pvc_display_tasklet);

	return count;
}

static const struct file_operations pvc_line_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= pvc_line_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= pvc_line_proc_write,
};

static ssize_t pvc_scroll_proc_write(struct file *file, const char __user *buf,
				     size_t count, loff_t *pos)
{
	char kbuf[42];
	size_t len;
	int cmd;

	len = min(count, sizeof(kbuf) - 1);
	if (copy_from_user(kbuf, buf, len))
		return -EFAULT;
	kbuf[len] = '\0';

	cmd = simple_strtol(kbuf, NULL, 10);

	mutex_lock(&pvc_mutex);
	if (scroll_interval != 0)
		del_timer(&timer);

	if (cmd == 0) {
		scroll_dir = 0;
		scroll_interval = 0;
	} else {
		if (cmd < 0) {
			scroll_dir = -1;
			scroll_interval = -cmd;
		} else {
			scroll_dir = 1;
			scroll_interval = cmd;
		}
		add_timer(&timer);
	}
	mutex_unlock(&pvc_mutex);

	return count;
}

static int pvc_scroll_proc_show(struct seq_file *m, void *v)
{
	mutex_lock(&pvc_mutex);
	seq_printf(m, "%d\n", scroll_dir * scroll_interval);
	mutex_unlock(&pvc_mutex);

	return 0;
}

static int pvc_scroll_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, pvc_scroll_proc_show, NULL);
}

static const struct file_operations pvc_scroll_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= pvc_scroll_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= pvc_scroll_proc_write,
};

void pvc_proc_timerfunc(struct timer_list *unused)
{
	if (scroll_dir < 0)
		pvc_move(DISPLAY|RIGHT);
	else if (scroll_dir > 0)
		pvc_move(DISPLAY|LEFT);

	timer.expires = jiffies + scroll_interval;
	add_timer(&timer);
}

static void pvc_proc_cleanup(void)
{
	remove_proc_subtree(DISPLAY_DIR_NAME, NULL);
	del_timer_sync(&timer);
}

static int __init pvc_proc_init(void)
{
	struct proc_dir_entry *dir, *proc_entry;
	int i;

	dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
	if (dir == NULL)
		goto error;

	for (i = 0; i < PVC_NLINES; i++) {
		strcpy(pvc_lines[i], "");
		pvc_linedata[i] = i;
	}
	for (i = 0; i < PVC_NLINES; i++) {
		proc_entry = proc_create_data(pvc_linename[i], 0644, dir,
					&pvc_line_proc_fops, &pvc_linedata[i]);
		if (proc_entry == NULL)
			goto error;
	}
	proc_entry = proc_create("scroll", 0644, dir,
				 &pvc_scroll_proc_fops);
	if (proc_entry == NULL)
		goto error;

	timer_setup(&timer, pvc_proc_timerfunc, 0);

	return 0;
error:
	pvc_proc_cleanup();
	return -ENOMEM;
}

module_init(pvc_proc_init);
module_exit(pvc_proc_cleanup);
MODULE_LICENSE("GPL");
