/* $Id: etrax100pardata.c,v 1.1 2000/10/04 12:37:46 jonashg Exp $
 * 
 * ETRAX parallel port data driver (read only).
 *
 */

#include <linux/mm.h>		/* verify_area() */
#include <asm/svinto.h>		/* R_PAR0 macros */

#define PARDATA_MAJOR 126	/* node major */

#define PAR_OE 0x00100000  /* Output Enable on par port */

static int pardata_write(struct inode *inode, struct file *file,
                         const char *buf, int count);
static int pardata_open(struct inode *inode, struct file *file);
static void pardata_close(struct inode *inode, struct file *file);

static struct file_operations pardata_fops = {
  NULL,           /* lseek */
  NULL,           /* read */
  pardata_write,  /* write */
  NULL,           /* readdir */
  NULL,           /* select */
  NULL,           /* ioctl */
  NULL,           /* mmap */
  pardata_open,   /* open */
  pardata_close   /* release */
};

static void write_data(byte data)
{
  *R_PAR0_CTRL_DATA = data | PAR_OE;
}

/*
 * Only writes the first char in buf.
 */
static int pardata_write(struct inode *inode, struct file *file,
              const char *buf, int count)
{
  unsigned int i;
  int retval;

  retval = verify_area(VERIFY_READ, (void *)buf, count);
  if (retval != 0) {
    printk("PARDATA: VERIFY_READ error: %i\n", retval);
    return retval;
  }
  
  write_data(*buf);

  return 1;
}

/*
 * Opens parport 0 in manual mode
 */
static int pardata_open(struct inode *inode, struct file *file)
{
  *R_PAR0_CONFIG = 0x00000060;  /* Manual-mode, enable port,
                                   immeditate mode change */
  return 0;
}

/*
 * Does nothing.
 */
static void pardata_close(struct inode *inode, struct file *file)
{
}

/*
 * Registers the character device and clears the data bits.
 */
void etrax_par_data_init()
{
  printk("Etrax/100 parallel port data driver v0.1"
         " (c) 2000 Axis Communications AB\r\n");
  
  if (register_chrdev(PARDATA_MAJOR, "PARDATA", &pardata_fops)) {
    printk("unable to get major %d for PARDATA\n", PARDATA_MAJOR);
  }

  write_data(0x00);
}
