text: /*++
  
  Copyright (c) 1997-2000 Microsoft Corporation
  
  Module Name:
  
      topic.c
  
  Abstract:
  
      This module contains the code that contains
      Toshiba topic cardbus controller specific initialization
      and other dispatches
  
  Author:
  
      Ravisankar Pudipeddi (ravisp) 1-Nov-97
      Neil Sandlin (neilsa) 1-Jun-1999
  
  
  Environment:
  
      Kernel mode
  
  Revision History :
  
      Neil Sandlin (neilsa) 3-Mar-99
         new setpower routine interface
  
  --*/
  
  #include "pch.h"
  
  
  
  VOID
  TopicInitialize(
      IN PFDO_EXTENSION FdoExtension
      )
  /*++
  
  Routine Description:
  
      Initialize Toshiba Topic cardbus controllers
  
  Arguments:
  
      FdoExtension - Pointer to the device extension for the controller FDO
  
  Return Value:
  
      None
  --*/
  {
      UCHAR byte;
      USHORT word;
  
      if (FdoExtension->ControllerType == PcmciaTopic95) {
          //
          // 480CDT in a dock needs this for socket registers to be visible.
          // It should be on all the time anyway.
          //
          GetPciConfigSpace(FdoExtension, CFGSPACE_TO_CD_CTRL, &byte, 1);
          byte |= CDCTRL_PCCARD_16_32;
          SetPciConfigSpace(FdoExtension, CFGSPACE_TO_CD_CTRL, &byte, 1);
      }
  
       //enable 3.3V capable
  
      byte = PcicReadSocket(FdoExtension->SocketList, PCIC_TO_FUNC_CTRL) | TO_FCTRL_CARDPWR_ENABLE;
      PcicWriteSocket(FdoExtension->SocketList,
                      PCIC_TO_FUNC_CTRL,
                      byte);
  
      //
      // initialize IRQ routing to ISA
      //
  
      GetPciConfigSpace(FdoExtension, CFGSPACE_BRIDGE_CTRL, &word, 2);
      word |= BCTRL_IRQROUTING_ENABLE;
      SetPciConfigSpace(FdoExtension, CFGSPACE_BRIDGE_CTRL, &word, 2);
  }
  
  
  
  NTSTATUS
  TopicSetPower(
      IN PSOCKET Socket,
      IN BOOLEAN Enable,
      OUT PULONG pDelayTime
      )
  
  /*++
  
  Routine Description:
  
      Set power to the specified socket.
  
  Arguments:
  
      Socket - the socket to set
      Enable - TRUE means to set power - FALSE is to turn it off.
      pDelayTime - specifies delay (msec) to occur after the current phase
  
  Return Value:
  
      STATUS_MORE_PROCESSING_REQUIRED - increment phase, perform delay, recall
      other status values terminate sequence
  
  --*/
  
  {
      NTSTATUS status;
      UCHAR               oldPower, newPower;
  
      if (IsCardBusCardInSocket(Socket)) {
          //
          // Hand over to generic power setting routine
          //
          return(CBSetPower(Socket, Enable, pDelayTime));
      }
  
      switch(Socket->PowerPhase) {
      case 1:
          //
          // R2 card - special handling
          //
          oldPower = PcicReadSocket(Socket, PCIC_PWR_RST);
  
          //
          // Set power values
          //
          if (Enable) {
              //
              // turn power on
              //
              newPower = PC_CARDPWR_ENABLE;
  
              if (Socket->Vcc == 33) {
                  newPower |= PC_VCC_TOPIC_033V;
              }
  
              //
              // set Vpp
              //
              if (Socket->Vcc == Socket->Vpp1) {
                  newPower |= PC_VPP_SETTO_VCC;
              } else if (Socket->Vpp1 == 120) {
                  newPower |= PC_VPP_SETTO_VPP;
              }
  
          } else {
              //
              // turn power off
              //
              newPower = 0;
          }
  
          //
          // Don't nuke the non-power related bits in the register..
          //
          newPower |= (oldPower & PC_PWRON_BITS);
          //
          // If Vcc is turned off, reset OUTPUT_ENABLE & AUTOPWR_ENABLE
          //
          if (!(newPower & PC_CARDPWR_ENABLE)) {
              newPower &= ~PC_PWRON_BITS;
          }
          //
          // Disable ResetDrv
          //
          newPower |= PC_RESETDRV_DISABLE;
  
          status = STATUS_SUCCESS;
          if (newPower != oldPower) {
              PcicWriteSocket(Socket, PCIC_PWR_RST, newPower);
              //
              // Allow ramp up.. (actually we don't need to this if
              // Enable was FALSE).  Keep it for paranoia's sake
              //
              *pDelayTime = PCMCIA_PCIC_STALL_POWER;
              Socket->PowerData = (ULONG) newPower;
              status = STATUS_MORE_PROCESSING_REQUIRED;
          }
          break;
  
      case 2:
  
          newPower = (UCHAR) Socket->PowerData;
  
          if ((newPower & PC_CARDPWR_ENABLE) &&
               ((newPower & PC_PWRON_BITS) != PC_PWRON_BITS)) {
              //
              // More paranoia?
              //
              newPower |= PC_PWRON_BITS;
              PcicWriteSocket(Socket, PCIC_PWR_RST, newPower);
          }
  
          status = STATUS_SUCCESS;
          *pDelayTime = PCMCIA_PCIC_STALL_POWER;
          break;
  
      default:
          ASSERT(FALSE);
          status = STATUS_UNSUCCESSFUL;
      }
      return status;
  }
  
  
  
  VOID
  TopicSetAudio(
      IN PSOCKET Socket,
      IN BOOLEAN Enable
      )
  {
      PFDO_EXTENSION FdoExtension = Socket->DeviceExtension;
      ULONG data;
      ULONG orig_data;
      BOOLEAN setBit;
  
  
      setBit = (IsCardBusCardInSocket(Socket) ^ Enable);
  
      GetPciConfigSpace(FdoExtension, CFGSPACE_TO_CBREG_CTRL, &data, sizeof(data));
      orig_data = data;
  
      if (setBit) {
          data |= CSRCR_TO_CAUDIO_OFF;
      } else {
          data &= ~CSRCR_TO_CAUDIO_OFF;
      }
  
      if (orig_data != data) {
          SetPciConfigSpace(FdoExtension, CFGSPACE_TO_CBREG_CTRL, &data, sizeof(data));
      }
  
  }
  
  
  
  BOOLEAN
  TopicSetZV(
      IN PSOCKET Socket,
      IN BOOLEAN Enable
      )
  {
      UCHAR bData;
  
      if (Enable) {
  
          PcicWriteSocket(Socket, PCIC_TO_MMI_CTRL, TO_MMI_VIDEO_CTRL | TO_MMI_AUDIO_CTRL);
          bData = PcicReadSocket(Socket, PCIC_TO_ADDITIONAL_GENCTRL);
          bData |= TO_GCTRL_CARDREMOVAL_RESET;
          PcicWriteSocket(Socket, PCIC_TO_ADDITIONAL_GENCTRL, bData);
  
      } else {
  
          PcicWriteSocket(Socket, PCIC_TO_MMI_CTRL, 0);
          bData = PcicReadSocket(Socket, PCIC_TO_ADDITIONAL_GENCTRL);
          bData &= ~TO_GCTRL_CARDREMOVAL_RESET;
          PcicWriteSocket(Socket, PCIC_TO_ADDITIONAL_GENCTRL, bData);
  
      }
      return TRUE;
  }
  
  