/*
 *  linux/drivers/serial/tsuart-bat3.c
 *
 *  TS-UART loader for Technologic Systems TS-BAT3
 *
 *  (c) 2006 Technologic Systems
 *
 * This source code is hereby licensed to the Linux 2.4 kernel under the
 * GPL, and to Technologic Systems customers under the BSD license.
 *
 * 2006-05-12:mos:initial version completed
 *
 */
#include <linux/version.h>
#include <linux/slab.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/proc_fs.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/serial_core.h>
//#include <serial_core.h>
#include <asm/hardware/serial_amba.h>
#include <linux/ts_sbc.h>
#include <asm/uaccess.h>
#include "tsuart.h"

#define BOARD_ID_BAT3 0xBA13

struct uart_driver *dr3=0;

static int tryInitPort(int iobase) {
  struct tsuart_port *ts;
  unsigned val;

  ts = kmalloc(sizeof(struct tsuart_port),GFP_KERNEL);
  if (!ts) {
    printk("Unable to allocate memory for tsuart port\n");
    return 0;
  }
  init_tsuart_port(ts);
  ts->u.iotype = SERIAL_IO_PORT;
  ts->get = tsuartGetIO8;
  ts->put = tsuartPutIO8;
  ts->debugFlags = portDebug;
  ts->u.iobase = TS7XXX_IO8_BASE + TS7XXX_ISAIO + iobase;
  ts->boardId = BOARD_ID_BAT3;
  ts->mdmctrl = 0;
  val = tsuartGetIO8(ts,0);
  if (val == 0x28) {
    val = tsuartGetIO8(ts,1);
    if ((val & 0x80) == 0x80) {
      ts->u.irq = 33;
      if ((val & 0x40) == 0x40) {
	ts->localStatus |= PORT_STATUS_SHIRQ; // IRQ6 with sharing...
      }
    } else {
      ts->u.irq = 32; // IRQ5... is this right?
    }
    ts->u.iobase += 2; // point to STAT register
    printk("TS-UART/BAT3 found at port 0x%04X\n",iobase);
    if (tsuart_register_port(dr3,ts) == 0) {
      return 1;
    }
  }
  return 0;
}

static int __init tsuart_init(void)
{
  int ports=0;

  dr3 = kmalloc(sizeof(struct uart_driver),GFP_KERNEL);
  if (!dr3) {
    printk("Unable to allocate memory for tsuart port\n");
    return 0;
  }
 if (!tsuart_configure_driver(dr3,234,95,"ttyT3S","cuat3s",4)) {
    kfree(dr3);
    return 0;
  }

  if (tryInitPort(0x100)) {
    ports++;
  }
  if (tryInitPort(0x110)) {
    ports++;
  }
  if (tryInitPort(0x200)) {
    ports++;
  }
  if (tryInitPort(0x210)) {
    ports++;
  }
  if (ports == 0) {
    printk("TS-UART/BAT3 did not detect a TS-BAT3 board\n");
  }
  return (ports > 0) ? 0 : -1;
}

static void __exit tsuart_exit(void)
{
  // This module can be safely unloaded after initialization is complete.
  // We allow module to load only so error conditions can be detected.
}

module_init(tsuart_init);
module_exit(tsuart_exit);

EXPORT_NO_SYMBOLS;
