/*
 * 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 = 0, scroll_interval = 0;

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("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("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");
