/*
*   IBM Confidential
*
*   OCO Source Materials
*
*   (c) Copyright IBM Corp. 1994, 1998
*
*   The source code for this program is not published or otherwise divested of its
*   tradesecrets, irrespective of what has been deposited with the U.S. Copyright Office.
*/

/**************************************************************************
 *
 * SOURCE FILE NAME =  KBDRM.C
 *
 * DESCRIPTIVE NAME =  Keyboard interface to RM subsystem.
 *
 * VERSION = V0.1
 *
 * DATE  09/02/94
 *
 * DESCRIPTION : (see above)
 *
 * Purpose: (see above)
 *
 *
 *
 * FUNCTIONS  :
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 *
 *
 * EXTERNAL FUNCTIONS
 *
 * CHANGE ACTIVITY =
 *   DATE      FLAG        APAR   CHANGE DESCRIPTION
 *   --------  ----------  -----  ----------------------------------------
 *   09/02/94                     opened file
 *   06/30/98  LR_USB             Modified to support USB Keyboard Client.
 *
 ****************************************************************************/

#define INCL_NOPMAPI
#include <os2.h>

#include "kbdrm.h"  // brings in rmcalls.h
#include "kbd.h"

/*--------------------------------------------------------*/
/* # D E F I N E S                                        */
/*--------------------------------------------------------*/

// #defines in KBDRM.H

/*--------------------------------------------------------*/
/* Set the DRIVERSTRUCT and ADAPTERSTRUCT data areas      */
/*--------------------------------------------------------*/

/*----------------------------------------------*/
/* Driver Description                           */
/*----------------------------------------------*/
DRIVERSTRUCT DriverStruct =
{
   "IBMKBD.SYS",                             /* DrvrName                */
   "IBM Keyboard Device Dependent Driver",   /* DrvrDescript            */
   "IBM - OS/2",                             /* VendorName              */
   CMVERSION_MAJOR,                          /* MajorVer                */
   CMVERSION_MINOR,                          /* MinorVer                */
   1998,6,26,                                /* Date                    */
   DRF_STATIC,                               /* DrvrFlags               */
   DRT_OS2,                                  /* DrvrType                */
   DRS_CHAR,                                 /* DrvrSubType             */
   NULL                                      /* DrvrCallback            */
};

/*----------------------------------------------*/
/* Adapter Description                          */
/*----------------------------------------------*/
ADAPTERSTRUCT AdapterStruct =
{
  "KBD_0 Keyboard Controller",               /* AdaptDescriptName      */
  0,                                         /* AdapterFlags           */
  AS_BASE_INPUT,                             /* BaseType               */
  AS_SUB_KBD,                                /* SubType                */
  AS_INTF_GENERIC,                           /* InterfaceType          */
  AS_HOSTBUS_PLANAR,                         /* HostBusType            */
  AS_BUSWIDTH_8BIT,                          /* HostBusWidth           */
  NULL                                       /* pAdjunctList           */
};

/************************************************/
/* Device Description                           */
/************************************************/
DEVICESTRUCT DeviceStruct =
{
  NULL,                              /* DevDescriptName;   */
  0,                                 /* DevFlags;          */
  DS_TYPE_IO,                        /* DevType;           */
  NULL                               /* pAdjunctList;      */
};


/*----------------------------------------------*/
/* GLOBAL VARS FOR RM                           */
/*                                              */
/* RM.LIB needs these declared                  */
/*----------------------------------------------*/
PFN             RM_Help0              = 0L;  /*VPNP*/
PFN             RM_Help3              = 0L;  /*VPNP*/
ULONG           RMFlags               = 0L;  /*VPNP*/

/*----------------------------------------------*/
/* GLOBAL HANDLE VARIABLES                      */
/*                                              */
/* These variables get the handles for          */
/* drivers, adapter (only 1), and resources.    */
/*                                              */
/*----------------------------------------------*/

HDRIVER   hDriver   = NULL;     // global handle to driver
HADAPTER  hAdapter  = NULL;     // global handle to adapter
HDEVICE   hDevice   = NULL;     // global handle to driver
HRESOURCE hPortBUFF = NULL;     // global handle to ports resource
HRESOURCE hPortCMD  = NULL;     // global handle to ports resource
HRESOURCE hResIRQs  = NULL;     // global handle to IRQs resource

/*--------------------------------------------------------*/
/* RM_KBD_CreateDriver - registers to RM susbsystem       */
/*                       (which initializes the DD to     */
/*                        RM connection)                  */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* PSZ DrvrName - ptr to driver name (taken from command  */
/*                line)                                   */
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* This function is a thin wrapper for the RMCreateDriver */
/* call. Modifications for specific drivers might include */
/* adding more parameters to be set into the              */
/* DriverStruct and actually returning the hDriver        */
/* to the caller (instead of maintaining it in a global   */
/* var). In any case, modifications to the DriverStruct   */
/* decalred above will have to made.                      */
/*--------------------------------------------------------*/
int
mtobin(char *stg)
{
   char *mons[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
   int i,j,m;

   for (i=0 ; i < 12 ; i++) {
      m=0;
      for (j=0 ; j < 3 ; j++) {
         if (mons[i][j] == stg[j]) m++;
      }
      if (m == 3) return(1+i);
   }
   return(0);
}

int
atobin(char *stg)
{
   int rv=0;

   while (*stg >= '0' && *stg <= '9') {
      rv=(rv*10)+(*stg-'0');
      stg++;
   }
   return(rv);
}

USHORT RM_KBD_CreateDriver( VOID)
{
/* RAR: Convert __DATE__ into a format for DriverStuct */
   char *stg=__DATE__;    //Format is MMMbDDbYYYY  b=space  MMM='Jan' 'Feb'

   DriverStruct.Date.Month = (UCHAR)mtobin (stg);  //LR_USB   DriverStruct.Date.Month=mtobin(stg);
   DriverStruct.Date.Day  = (UCHAR)atobin (stg+4); //LR_USB   DriverStruct.Date.Day  =atobin(stg+4);
   DriverStruct.Date.Year =atobin(stg+7);
   return( RMCreateDriver( &DriverStruct, &hDriver));
}

/*--------------------------------------------------------*/
/* RM_KBD_DestroyDriver - deregisters the driver from     */
/*                        RM sub-system and releases all  */
/*                        claimed resources               */
/*                                                        */
/*--------------------------------------------------------*/

VOID RM_KBD_DestroyDriver( VOID)
{
   RMDestroyDriver( hDriver);
}

/*--------------------------------------------------------*/
/* RM_KBD_CreateAdapter - tells RM to associate adapter   */
/*                        to driver and resources to      */
/*                        adapater                        */
/*                                                        */
/*--------------------------------------------------------*/

USHORT RM_KBD_CreateAdapter( VOID)
{
   UCHAR       ResourceBuf[ MAX_RES_BUF_SIZE];
   PAHRESOURCE pResourceList = (PAHRESOURCE)ResourceBuf;

   pResourceList->NumResource = 3;

   pResourceList->hResource[0] = hPortBUFF;
   pResourceList->hResource[1] = hPortCMD;
   pResourceList->hResource[2] = hResIRQs;

   return ( RMCreateAdapter( hDriver,
                             &hAdapter,
                             &AdapterStruct,
                             NULL,
                             pResourceList ));
}

/*--------------------------------------------------------*/
/* RM_KBD_CreateDevice - registers to RM susbsystem       */
/*                                                        */
/*--------------------------------------------------------*/

USHORT RM_KBD_CreateDevice( USHORT Keyboard_ID)
{
   if (Keyboard_ID == 84) {
      DeviceStruct.DevDescriptName = "KBD_84 84/85 Key Keyboard Device";
   }
   else if (Keyboard_ID == 88) {
      DeviceStruct.DevDescriptName = "KBD_88 88/89 Key Keyboard Device";
   }
   else if (Keyboard_ID == 101) {
      DeviceStruct.DevDescriptName = "KBD_101 101/102 Key Enhanced Keyboard Device";
   }
   else if (Keyboard_ID == 122) {
      DeviceStruct.DevDescriptName = "KBD_122 122 Key Keyboard Device";
   }
   else {
      DeviceStruct.DevDescriptName = "KBD_X Unknown Keyboard Device";
   }

   return( RMCreateDevice( hDriver,
                           &hDevice,
                           &DeviceStruct,
                           hAdapter,
                           NULL));
}

/*--------------------------------------------------------*/
/* RM_KBD_AlllocPortBuffer - attempts to claim a port     */
/*                           resource from RM subsystem   */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_KBD_AllocPortBuffer( VOID)
{

   RESOURCESTRUCT Resource;

   if ( hPortBUFF)
   {
         return( RM_KBD_ERR_RESOURCECLAIMED);
   }

   Resource.ResourceType              = RS_TYPE_IO;
   Resource.IOResource.BaseIOPort     = PORT_BUFFER;
   Resource.IOResource.NumIOPorts     = 1;
   Resource.IOResource.IOFlags        = RS_IO_SHARED;
   Resource.IOResource.IOAddressLines = DECODE_WIDTH;

   /*---------------------------------------------------*/
   /* Allocate Driver Handle                            */
   /*---------------------------------------------------*/

   return( RMAllocResource( hDriver, &hPortBUFF , &Resource));

}

/*--------------------------------------------------------*/
/* RM_KBD_AlllocPortCmd - attempts to claim a port        */
/*                        resource from RM subsystem      */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_KBD_AllocPortCmd( VOID)
{

   RESOURCESTRUCT Resource;

   if ( hPortCMD)
   {
         return( RM_KBD_ERR_RESOURCECLAIMED);
   }

   Resource.ResourceType              = RS_TYPE_IO;
   Resource.IOResource.BaseIOPort     = PORT_CMD;
   Resource.IOResource.NumIOPorts     = 1;
   Resource.IOResource.IOFlags        = RS_IO_SHARED;
   Resource.IOResource.IOAddressLines = DECODE_WIDTH;

   /*---------------------------------------------------*/
   /* Allocate Driver Handle                            */
   /*---------------------------------------------------*/

   return( RMAllocResource( hDriver, &hPortCMD , &Resource));

}

/*--------------------------------------------------------*/
/* RM_KBD_AllocIRQ   - attempts to claim a IRQ resource   */
/*                       from RM subsystem                */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* USHORT IRQlevel - IRQ level to claim                   */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_KBD_AllocIRQ( USHORT IRQlevel)
{

   RESOURCESTRUCT Resource;

   if ( hResIRQs)
   {
         return( RM_KBD_ERR_RESOURCECLAIMED);
   }

   /*------------------------------------------------*/
   /* Request IRQ Resource  from RM......            */
   /*------------------------------------------------*/
   Resource.ResourceType          = RS_TYPE_IRQ;
   Resource.IRQResource.IRQLevel  = IRQlevel;
   Resource.IRQResource.PCIIrqPin = RS_PCI_INT_NONE;
   Resource.IRQResource.IRQFlags  = RS_IRQ_EXCLUSIVE;


   /*---------------------------------------------------*/
   /* Allocate Driver Handle                            */
   /*---------------------------------------------------*/
   return( RMAllocResource( hDriver, &hResIRQs , &Resource));

}
