/*
 *  arch/m68k/q40/config.c
 *
 *  Copyright (C) 1999 Richard Zidlicky
 *
 * originally based on:
 *
 *  linux/bvme/config.c
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file README.legal in the main directory of this archive
 * for more details.
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/serial_reg.h>
#include <linux/rtc.h>
#include <linux/vt_kern.h>

#include <asm/io.h>
#include <asm/rtc.h>
#include <asm/bootinfo.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/q40_master.h>

extern irqreturn_t q40_process_int (int level, struct pt_regs *regs);
extern void q40_init_IRQ (void);
static void q40_get_model(char *model);
static int  q40_get_hardware_list(char *buffer);
extern void q40_sched_init(irq_handler_t handler);

extern unsigned long q40_gettimeoffset (void);
extern int q40_hwclk (int, struct rtc_time *);
extern unsigned int q40_get_ss (void);
extern int q40_set_clock_mmss (unsigned long);
static int q40_get_rtc_pll(struct rtc_pll_info *pll);
static int q40_set_rtc_pll(struct rtc_pll_info *pll);
extern void q40_reset (void);
void q40_halt(void);
extern void q40_waitbut(void);
void q40_set_vectors (void);

extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );

extern char m68k_debug_device[];
static void q40_mem_console_write(struct console *co, const char *b,
				    unsigned int count);

extern int ql_ticks;

static struct console q40_console_driver = {
	.name =		"debug",
	.flags =	CON_PRINTBUFFER,
	.index =	-1,
};


/* early debugging function:*/
extern char *q40_mem_cptr; /*=(char *)0xff020000;*/
static int _cpleft;

static void q40_mem_console_write(struct console *co, const char *s,
				  unsigned int count)
{
  char *p=(char *)s;

  if (count<_cpleft)
    while (count-- >0){
      *q40_mem_cptr=*p++;
      q40_mem_cptr+=4;
      _cpleft--;
    }
}
#if 0
void printq40(char *str)
{
  int l=strlen(str);
  char *p=q40_mem_cptr;

  while (l-- >0 && _cpleft-- >0)
    {
      *p=*str++;
      p+=4;
    }
  q40_mem_cptr=p;
}
#endif

static int halted=0;

#ifdef CONFIG_HEARTBEAT
static void q40_heartbeat(int on)
{
  if (halted) return;

  if (on)
    Q40_LED_ON();
  else
    Q40_LED_OFF();
}
#endif

void q40_reset(void)
{
        halted=1;
        printk ("\n\n*******************************************\n"
		"Called q40_reset : press the RESET button!! \n"
		"*******************************************\n");
	Q40_LED_ON();
	while(1) ;
}
void q40_halt(void)
{
        halted=1;
        printk ("\n\n*******************\n"
		    "  Called q40_halt\n"
		    "*******************\n");
	Q40_LED_ON();
	while(1) ;
}

static void q40_get_model(char *model)
{
    sprintf(model, "Q40");
}

/* No hardware options on Q40? */

static int q40_get_hardware_list(char *buffer)
{
    *buffer = '\0';
    return 0;
}

static unsigned int serports[]={0x3f8,0x2f8,0x3e8,0x2e8,0};
void q40_disable_irqs(void)
{
  unsigned i,j;

  j=0;
  while((i=serports[j++])) outb(0,i+UART_IER);
  master_outb(0,EXT_ENABLE_REG);
  master_outb(0,KEY_IRQ_ENABLE_REG);
}

void __init config_q40(void)
{
    mach_sched_init      = q40_sched_init;

    mach_init_IRQ        = q40_init_IRQ;
    mach_gettimeoffset   = q40_gettimeoffset;
    mach_hwclk           = q40_hwclk;
    mach_get_ss          = q40_get_ss;
    mach_get_rtc_pll     = q40_get_rtc_pll;
    mach_set_rtc_pll     = q40_set_rtc_pll;
    mach_set_clock_mmss	 = q40_set_clock_mmss;

    mach_reset		 = q40_reset;
    mach_get_model       = q40_get_model;
    mach_get_hardware_list = q40_get_hardware_list;

#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
    mach_beep            = q40_mksound;
#endif
#ifdef CONFIG_HEARTBEAT
    mach_heartbeat = q40_heartbeat;
#endif
    mach_halt = q40_halt;

    /* disable a few things that SMSQ might have left enabled */
    q40_disable_irqs();

    /* no DMA at all, but ide-scsi requires it.. make sure
     * all physical RAM fits into the boundary - otherwise
     * allocator may play costly and useless tricks */
    mach_max_dma_address = 1024*1024*1024;

    /* useful for early debugging stages - writes kernel messages into SRAM */
    if (!strncmp( m68k_debug_device,"mem",3 ))
      {
	/*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/
	_cpleft=2000-((long)q40_mem_cptr-0xff020000)/4;
	q40_console_driver.write = q40_mem_console_write;
	register_console(&q40_console_driver);
      }
}


int q40_parse_bootinfo(const struct bi_record *rec)
{
  return 1;
}


static inline unsigned char bcd2bin (unsigned char b)
{
	return ((b>>4)*10 + (b&15));
}

static inline unsigned char bin2bcd (unsigned char b)
{
	return (((b/10)*16) + (b%10));
}


unsigned long q40_gettimeoffset (void)
{
    return 5000*(ql_ticks!=0);
}


/*
 * Looks like op is non-zero for setting the clock, and zero for
 * reading the clock.
 *
 *  struct hwclk_time {
 *         unsigned        sec;       0..59
 *         unsigned        min;       0..59
 *         unsigned        hour;      0..23
 *         unsigned        day;       1..31
 *         unsigned        mon;       0..11
 *         unsigned        year;      00...
 *         int             wday;      0..6, 0 is Sunday, -1 means unknown/don't set
 * };
 */

int q40_hwclk(int op, struct rtc_time *t)
{
        if (op)
	{	/* Write.... */
	        Q40_RTC_CTRL |= Q40_RTC_WRITE;

		Q40_RTC_SECS = bin2bcd(t->tm_sec);
		Q40_RTC_MINS = bin2bcd(t->tm_min);
		Q40_RTC_HOUR = bin2bcd(t->tm_hour);
		Q40_RTC_DATE = bin2bcd(t->tm_mday);
		Q40_RTC_MNTH = bin2bcd(t->tm_mon + 1);
		Q40_RTC_YEAR = bin2bcd(t->tm_year%100);
		if (t->tm_wday >= 0)
			Q40_RTC_DOW = bin2bcd(t->tm_wday+1);

	        Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
	}
	else
	{	/* Read....  */
	  Q40_RTC_CTRL |= Q40_RTC_READ;

	  t->tm_year = bcd2bin (Q40_RTC_YEAR);
	  t->tm_mon  = bcd2bin (Q40_RTC_MNTH)-1;
	  t->tm_mday = bcd2bin (Q40_RTC_DATE);
	  t->tm_hour = bcd2bin (Q40_RTC_HOUR);
	  t->tm_min  = bcd2bin (Q40_RTC_MINS);
	  t->tm_sec  = bcd2bin (Q40_RTC_SECS);

	  Q40_RTC_CTRL &= ~(Q40_RTC_READ);

	  if (t->tm_year < 70)
	    t->tm_year += 100;
	  t->tm_wday = bcd2bin(Q40_RTC_DOW)-1;

	}

	return 0;
}

unsigned int q40_get_ss(void)
{
	return bcd2bin(Q40_RTC_SECS);
}

/*
 * Set the minutes and seconds from seconds value 'nowtime'.  Fail if
 * clock is out by > 30 minutes.  Logic lifted from atari code.
 */

int q40_set_clock_mmss (unsigned long nowtime)
{
	int retval = 0;
	short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;

	int rtc_minutes;


	rtc_minutes = bcd2bin (Q40_RTC_MINS);

	if ((rtc_minutes < real_minutes
		? real_minutes - rtc_minutes
			: rtc_minutes - real_minutes) < 30)
	{
	        Q40_RTC_CTRL |= Q40_RTC_WRITE;
		Q40_RTC_MINS = bin2bcd(real_minutes);
		Q40_RTC_SECS = bin2bcd(real_seconds);
		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
	}
	else
		retval = -1;


	return retval;
}


/* get and set PLL calibration of RTC clock */
#define Q40_RTC_PLL_MASK ((1<<5)-1)
#define Q40_RTC_PLL_SIGN (1<<5)

static int q40_get_rtc_pll(struct rtc_pll_info *pll)
{
	int tmp=Q40_RTC_CTRL;
	pll->pll_value = tmp & Q40_RTC_PLL_MASK;
	if (tmp & Q40_RTC_PLL_SIGN)
		pll->pll_value = -pll->pll_value;
	pll->pll_max=31;
	pll->pll_min=-31;
	pll->pll_posmult=512;
	pll->pll_negmult=256;
	pll->pll_clock=125829120;
	return 0;
}

static int q40_set_rtc_pll(struct rtc_pll_info *pll)
{
	if (!pll->pll_ctrl){
		/* the docs are a bit unclear so I am doublesetting */
		/* RTC_WRITE here ... */
		int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) |
			  Q40_RTC_WRITE;
		Q40_RTC_CTRL |= Q40_RTC_WRITE;
		Q40_RTC_CTRL = tmp;
		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
		return 0;
	} else
		return -EINVAL;
}
