/*
 * Diamond Systems Corporation DMM16 A/D Converter Board 
 *
 *  FOR USE WITH LINUX -- JANET ESTABRIDIS   17 MAY 1999
 *  out statements -- REVERSE port #, data -->  data, port # IN LINUX
 *  Only writing functions I need to operate in MATS FFM environment
 *
 * 

 DMM16 specific code

 */
#include "dmm16.h"
#include <stdio.h>
#include <asm/io.h>
//#include <sys/ioctl.h>

////////////////////////////////////////////////////////////////////
//
//  MISC FUNCTIONS -- Read or Write to any Register on any board
//
///////////////////////////////////////////////////////////////////

////////////////////////////////////////////////
// DSC_REGISTER_WRITE()
// Driver access to any board register.
////////////////////////////////////////////////
BYTE RegisterWrite(boardInfo *b, REGPARAMS *params )
{
  outb( params->data , b->baseAddress + (params->address & 0x0F) );
  return DE_NONE;
}

////////////////////////////////////////////////
// DSC_REGISTER_READ()
// Driver access to any board register.
////////////////////////////////////////////////
BYTE RegisterRead(boardInfo *b, REGPARAMS *params )
{
  params->data = inb(b->baseAddress + (params->address & 0x0F));
  return DE_NONE;
}

//////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////

BYTE DMM16Init(boardInfo *b)
{
   BYTE retval = DE_NONE;

   /* do hardware test -- Clear Channel Reg and  Read back */
   outb( 0, b->baseAddress + ADCHANREG ); /* clear channel register */
   if (inb(b->baseAddress + ADCHANREG) != 0)
     {
       return( DE_HW_FAILURE );
     }

   outb( 0xff, b->baseAddress + ADCHANREG );
   if (inb(b->baseAddress + ADCHANREG) != 0xff)
     {
       return( DE_HW_FAILURE );
     }

   //============ MAY WANT TO ADD A CALL TO A ROUTINE THAT WILL SAMPLE
   //============ ON A CHANNEL AND MAKE SURE WE ARE SAMPLING TOO

   //============ For now, clear some registers
   outb( 0x00, b->baseAddress + ADCHANREG );      //clear channel reg
   outb( 0x00, b->baseAddress + INTFFREG );       //clear interrupt ff reg
   outb( 0x00, b->baseAddress + CNTRLREG );       //clear control reg
   outb( 0x00, b->baseAddress + COUNTTREG );      //clear counter/timer reg
   outb( (b->polarity == UNIPOLAR) ? 0x10 : 0, b->baseAddress + ACONFIGREG );        //setup D/A polarity --


   return retval;
}

BYTE DMM16ADSetSettings(boardInfo *b,DSCADSETTINGS *dscadsettings)
{
   BYTE aconfig;

   if (dscadsettings->currentChannel > 15)
   {
     /*    debug(("currentChannel too high\n"));
     strcpy(error_message,"currentChannel to high.");*/
      return DE_INVALID_PARM;
   }

   aconfig = 0;
   switch (dscadsettings->gain)
   {
      case GAIN_1 :
         aconfig = (aconfig & 0xfc) | 0;
         break;
      case GAIN_2 :
         aconfig = (aconfig & 0xfc) | 1;
         break;
      case GAIN_4 :
         aconfig = (aconfig & 0xfc) | 2;
         break;
      case GAIN_8 :
         aconfig = (aconfig & 0xfc) | 3;
         break;
      default :
    /*       debug(("bad gain %i\n",dscadsettings->gain));
	       strcpy(error_message,"Invalid Gain.");*/
         return DE_INVALID_PARM;
   }

   switch (dscadsettings->range)
   {
      case RANGE_BIPOLAR_5 :
         aconfig = (aconfig & 0xf3) | (0 << 2);
         break;
      case RANGE_BIPOLAR_10 :
         aconfig = (aconfig & 0xf3) | (2 << 2);
         break;
      case RANGE_UNIPOLAR_10 :
         aconfig = (aconfig & 0xf3) | (3 << 2);
         break;
      default :
    /*       debug(("bad range\n"));
	      strcpy(error_message,"Invalid Range.");*/
         return DE_INVALID_PARM;
   }

   if (b->polarity == UNIPOLAR)
      aconfig |= 0x10;

   /* first set the current channel */
   outb( dscadsettings->currentChannel | (dscadsettings->currentChannel << 4), b->baseAddress + ADCHANREG );   

   /* then set A/D conversion */
   outb( aconfig, b->baseAddress + ACONFIGREG );

   return DE_NONE;
}

/* these 3 interrupt callbacks are always called with interrupts disabled */
void DMM16StartInterrupts(boardInfo *b)
{
   BYTE config;
   WORD junk;


}

void DMM16ClearInterrupt(boardInfo *b)
{
   


}

void DMM16EndInterrupts(boardInfo *b)
{
   BYTE config;

   config = inb(b->baseAddress + 9);
   config &= 0x7f;
   

   outb( config, b->baseAddress + 9 ); /* clear INTE */
}

////////////////////////////////////////////////
// DRVR_FUNCTIONS()
////////////////////////////////////////////////
//BYTE Dmm16_DrvrFunctions(boardInfo *b, WORD func,void *params)
// { ; }

////////////////////////////////////////////////
// A2D_FUNCTIONS()
////////////////////////////////////////////////
BYTE Dmm16_A2DFunctions(boardInfo *b, WORD func,void *params)
{
  BYTE retval;

  return retval;
}

////////////////////////////////////////////////
// D2A_FUNCTIONS()
////////////////////////////////////////////////
BYTE Dmm16_D2AFunctions(boardInfo *b, WORD func,void *params)
{
  BYTE retval;

  return retval;
}

////////////////////////////////////////////////
// DIO_FUNCTIONS()
////////////////////////////////////////////////
BYTE Dmm16_DIOFunctions(boardInfo *b, WORD func, void *params)
{
  BYTE retval;

  return retval;
}

////////////////////////////////////////////////
// CTR_FUNCTIONS()
////////////////////////////////////////////////
BYTE Dmm16_CtrFunctions(boardInfo *b, WORD func,void *params)
{
  BYTE retval;

  return retval;
}

////////////////////////////////////////////////
// OTHER_FUNCTIONS()
////////////////////////////////////////////////
BYTE Dmm16_OtherFunctions(boardInfo *b, WORD func,void *params)
{
  BYTE retval;


  return retval;
}











