/*
 * Picvue PVC160206 display driver
 *
 * Brian Murphy <brian.murphy@eicon.com>
 *
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>

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

#include <linux/timer.h>

#include "picvue.h"

static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
static int pvc_linedata[PVC_NLINES];
static struct proc_dir_entry *pvc_display_dir;
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(pvc_display_tasklet, &pvc_display, 0);

static int pvc_proc_read_line(char *page, char **start,
			     off_t off, int count,
			     int *eof, void *data)
{
	char *origpage = page;
	int lineno = *(int *)data;

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

	down(&pvc_sem);
	page += sprintf(page, "%s\n", pvc_lines[lineno]);
	up(&pvc_sem);

	return page - origpage;
}

static int pvc_proc_write_line(struct file *file, const char *buffer,
			   unsigned long count, void *data)
{
	int origcount = count;
	int lineno = *(int *)data;

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

	if (count > PVC_LINELEN)
		count = PVC_LINELEN;

	if (buffer[count-1] == '\n')
		count--;

	down(&pvc_sem);
	strncpy(pvc_lines[lineno], buffer, count);
	pvc_lines[lineno][count] = '\0';
	up(&pvc_sem);

	tasklet_schedule(&pvc_display_tasklet);

	return origcount;
}

static int pvc_proc_write_scroll(struct file *file, const char *buffer,
			   unsigned long count, void *data)
{
	int origcount = count;
	int cmd = simple_strtol(buffer, NULL, 10);

	down(&pvc_sem);
	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);
	}
	up(&pvc_sem);

	return origcount;
}

static int pvc_proc_read_scroll(char *page, char **start,
			     off_t off, int count,
			     int *eof, void *data)
{
	char *origpage = page;

	down(&pvc_sem);
	page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
	up(&pvc_sem);

	return page - origpage;
}


void pvc_proc_timerfunc(unsigned long data)
{
	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)
{
	int i;
	for (i = 0; i < PVC_NLINES; i++)
		remove_proc_entry(pvc_linename[i], pvc_display_dir);
	remove_proc_entry("scroll", pvc_display_dir);
	remove_proc_entry(DISPLAY_DIR_NAME, NULL);

	del_timer(&timer);
}

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

	pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
	if (pvc_display_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 = create_proc_entry(pvc_linename[i], 0644,
					       pvc_display_dir);
		if (proc_entry == NULL)
			goto error;

		proc_entry->read_proc = pvc_proc_read_line;
		proc_entry->write_proc = pvc_proc_write_line;
		proc_entry->data = &pvc_linedata[i];
	}
	proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir);
	if (proc_entry == NULL)
		goto error;

	proc_entry->write_proc = pvc_proc_write_scroll;
	proc_entry->read_proc = pvc_proc_read_scroll;

	init_timer(&timer);
	timer.function = pvc_proc_timerfunc;

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

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