/* 
 * 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");
