view src/cs/drivers/drv_core/armio/armio.c @ 629:3231dd9b38c1

armio.c: make GPIOs 8 & 13 outputs driving 1 on all "classic" targets Calypso GPIOs 8 & 13 are pinmuxed with MCUEN1 & MCUEN2, respectively, and on powerup these pins are MCUEN, i.e., outputs driving 1. TI's code for C-Sample and earlier turns them into GPIOs configured as outputs also driving 1 - so far, so good - but TI's code for BOARD 41 (which covers D-Sample, Leonardo and all real world Calypso devices derived from the latter) switches them from MCUEN to GPIOs, but then leaves them as inputs. Given that the hardware powerup state of these two pins is outputs driving 1, every Calypso board design MUST be compatible with such driving; typically these GPIO signals will be either unused and unconnected or connected as outputs driving some peripheral. Turning these pins into GPIO inputs will result in floating inputs on every reasonably-wired board, thus I am convinced that this configuration is nothing but a bug on the part of whoever wrote this code at TI. This floating input bug had already been fixed earlier for GTA modem and FCDEV3B targets; the present change makes the fix unconditional for all "classic" targets. The newly affected targets are D-Sample, Leonardo, Tango and GTM900.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 02 Jan 2020 05:38:26 +0000
parents 0cbe7438f974
children b639f7ab0007
line wrap: on
line source

/*
 * ARMIO.C 
 *
 *
 * Control diagnostic bits
 *
 * Reference : GCS207
 *
 */


#include "l1sw.cfg"
#include "swconfig.cfg"
#ifdef BLUETOOTH_INCLUDED
#include "btemobile.cfg"
#endif
#if (OP_L1_STANDALONE == 1)
  #include "l1_macro.h"
  #include "l1_confg.h"
#endif
#include "board.cfg"
#include "chipset.cfg"
#include "fc-target.h"

#if (OP_L1_STANDALONE == 0)
  #include "main/sys_types.h"
#else
  #include "sys_types.h"
#endif


#include "memif/mem.h"

#include "inth/iq.h"
#include "armio/armio.h"
#include "abb/abb.h"	 // for AI_Power function : to be removed, use ABB_Power_Off in abb.c file instead !!!

#if (CHIPSET != 12)
/*
 * AI_EnableBit
 *
 * Enable ARMIO input/output bit (see CLKM module specification)
 */
void AI_EnableBit(int bit)
{
  *((volatile SYS_UWORD16 *) CLKM_IO_CNTL) |= (1<<bit); 
}

/*
 * AI_DisableBit
 *
 * Disable ARMIO input/output bit (see CLKM module specification)
 */
void AI_DisableBit(int bit)
{
  *((volatile SYS_UWORD16 *) CLKM_IO_CNTL) &= ~(1<<bit); 
}

#endif /* CHIPSET != 12 */

/*
 * AI_SetBit
 *
 * Switch-on one bit
 */
void AI_SetBit(int bit)
{
   *((volatile SYS_UWORD16 *) ARMIO_OUT) |= (1<<bit); 
}

/*
 * AI_ResetBit
 *
 * Switch-off one bit
 */
void AI_ResetBit(int bit)
{
   *((volatile SYS_UWORD16 *) ARMIO_OUT) &= ~(1<<bit); 
}

/*
 * AI_ConfigBitAsOutput
 *
 * Set this bit as an output
 */
void AI_ConfigBitAsOutput(int bit)
{
   *((volatile SYS_UWORD16 *) ARMIO_IO_CNTL) &= ~(1<<bit); 
}

/*
 * AI_ConfigBitAsInput
 *
 * Set this bit as an input
 */
void AI_ConfigBitAsInput(int bit)
{
   *((volatile SYS_UWORD16 *) ARMIO_IO_CNTL) |= (1<<bit); 
}


/*
 * AI_ReadBit
 *
 * Read value in register
 */
SYS_BOOL AI_ReadBit(int bit)
{
   if ((*((volatile SYS_UWORD16 *) ARMIO_IN)) & (1<<bit))
      return (1);
   else
      return (0);
}

/*
 * AI_Power
 *
 * Switch-on or off the board
 *
 * Parameters : SYS_UWORD8 power: 1 to power-on (maintain power)
 *                                0 to power-off
 *
 */
#if (OP_L1_STANDALONE == 0)
void AI_Power(SYS_UWORD8 power)
{
  if (power == 0) 
  {
	ABB_Power_Off();
  }
}
#endif

/*
 * AI_ResetIoConfig
 *
 * Reset all default IO configurations
 *
 */
void AI_ResetIoConfig(void)
{
  *((volatile SYS_UWORD16 *) ARMIO_IO_CNTL) = 0xFFFF; // all bits are inputs
  #if (CHIPSET != 12)
    *((volatile SYS_UWORD16 *) CLKM_IO_CNTL) = 0;       // default config
  #endif /* CHIPSET != 12 */
}


/*
 * AI_ClockEnable
 *
 * Enable ARMIO clock module
 *
 */
void AI_ClockEnable(void)
{
   *((volatile SYS_UWORD16 *) ARMIO_CNTL_REG) |= ARMIO_CLOCKEN;    // set to 1 bit 5
}


/*
 * AI_InitIOConfig
 *
 * Configure all GPIOs at initialization in order to optimize the power consumption 
 * of the C-Sample :
 *  - select IOs 8,9,10,11,12 and 13 on the pins instead of MCSI and MCUEN signals.
 *  - configure these IOs in output high.
 *  - configure the IOs 0 (Vibrator LED) and 1 (LCD_A0) in output low.
 */
void AI_InitIOConfig(void)
{
  // reset the IOs config
  AI_ResetIoConfig();

  // CLKM_IO_CNTL register configuration :
  // select IOs 6,8,9,10,11,12 and 13 on the pins instead of MCSI and MCUEN signals.
  AI_EnableBit(0);	/* FreeCalypso addition */
  AI_EnableBit(2);
  AI_EnableBit(4);

  #ifdef CONFIG_TARGET_PIRELLI
    AI_EnableBit(1);
    AI_EnableBit(3);
  #endif

  /* Bits 5,6,7,8 are used to output I/O 9,10,11,12 or MCSI pins */
  /* If Bluetooth, IO should be disabled, outputting MCSI used for Bluetooth voice */
  /*
   * FreeCalypso change: we don't have BT, our new criterion is
   * whether or not a given board is wired for MCSI.
   */
  #if defined(CONFIG_TARGET_FCMODEM) || defined(CONFIG_TARGET_PIRELLI)
    AI_DisableBit(5);
    AI_DisableBit(6);
    AI_DisableBit(7);
    AI_DisableBit(8);
  #else
    AI_EnableBit(5);
    AI_EnableBit(6);
    AI_EnableBit(7);
    AI_EnableBit(8);
  #endif

  AI_EnableBit(9);

  // ARMIO_OUT register configuration :
  // set IOs 8,9,10,11,12 and 13 as high
  // set IOs 0 to 7 as low

  #ifdef CONFIG_TARGET_C11X
    /* C11x GPIO configuration mimics what the original fw sets */

    /* GPIO out all zeros */
    *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x0000;

    /* setting of GPIOs as outputs: register setting from the original fw */
    *((volatile SYS_UWORD16 *) ARMIO_IO_CNTL) = 0x2209;

  #elif defined(CONFIG_TARGET_C139)
    /* C139 GPIO configuration mimics what the original fw sets */

    /* GPIO out all zeros - the LCD backlight is OFF */
    *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x0000;

    /* setting of GPIOs as outputs: register setting from the original fw */
    *((volatile SYS_UWORD16 *) ARMIO_IO_CNTL) = 0x2A09;

  #elif defined(CONFIG_TARGET_C155)
    /* C155 GPIO config based on the available schematics */

    /* GPIO out all zeros - the LCD backlight is OFF */
    *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x0000;

    AI_ConfigBitAsOutput(1);	/* LCD backlight control */
    AI_ConfigBitAsOutput(2);	/* headset jack switch */
    AI_ConfigBitAsOutput(3);	/* LCDA0 (?) */
    AI_ConfigBitAsOutput(8);	/* MUSIC_A0 */
    AI_ConfigBitAsOutput(12);	/* MUSIC_ON */

  #elif defined(CONFIG_TARGET_J100)
    /*
     * GPIO config on this target is based on the disassembly of
     * Init_Target() and AI_InitIOConfig() functions in the official fw.
     */

    /* GPIO out all zeros - the LCD backlight is OFF */
    *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x0000;

    /* setting of GPIOs as outputs: register setting from the original fw */
    *((volatile SYS_UWORD16 *) ARMIO_IO_CNTL) = 0x2A59;

  #elif defined(CONFIG_TARGET_PIRELLI)

    *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x0000;

    AI_ConfigBitAsOutput(1);
    AI_ConfigBitAsOutput(4);
    AI_ConfigBitAsOutput(7);

  #else	/* classic TI/Openmoko/FreeCalypso targets */
    // set IOs 1 and 8 to 13 as high
    // set IOs 0 and 2 to 7 as low
    // On D-Sample GPIO 1 must be set to high to enable the audio amplifier,
    // but on Openmoko's modem it is the interrupt to the AP.
    // On the FCDEV3B it also controls the audio amplifier.
    // On the GTM900 GPIOs 0 and 1 are RI and DSR outputs, respectively.
    // For targets other than GTM900, we enable the audio amplifier
    // if we are in an MMI!=0 build - for ACI builds use the AT@SPKR command.
#ifdef CONFIG_TARGET_GTM900
      *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x3F01;
#elif (MMI != 0)
      *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x3F02;
#else
      *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x3F00;
#endif

    // ARMIO_CNTL_REG register configuration :
    // set IOs 1,2,5,7,9,14 and 15 as ouputs.
    // bits conditionalized on CONFIG_TARGET_GTAMODEM or CONFIG_TARGET_FCFAM
    // are FreeCalypso additions
    #if defined(CONFIG_TARGET_GTAMODEM) || defined(CONFIG_TARGET_FCFAM) || \
        defined(CONFIG_TARGET_GTM900)
      AI_ConfigBitAsOutput(0);
    #endif
    AI_ConfigBitAsOutput(1);
    AI_ConfigBitAsOutput(2);
    #ifdef CONFIG_TARGET_GTAMODEM
      AI_ConfigBitAsOutput(3);
    #endif
    #if defined(CONFIG_TARGET_GTAMODEM) || defined(CONFIG_TARGET_FCFAM)
      AI_ConfigBitAsOutput(4);
    #endif
    AI_ConfigBitAsOutput(5);
    #if defined(CONFIG_TARGET_GTAMODEM) || defined(CONFIG_TARGET_FCFAM)
      AI_ConfigBitAsOutput(6);
    #endif
    AI_ConfigBitAsOutput(7);
    #if 1	/* FreeCalypso addition for all targets */
      AI_ConfigBitAsOutput(8);
    #endif
    AI_ConfigBitAsOutput(9);
    #ifdef CONFIG_TARGET_GTAMODEM
      AI_ConfigBitAsOutput(10);
      AI_ConfigBitAsOutput(11);
      AI_ConfigBitAsOutput(12);
    #endif
    #if 1	/* FreeCalypso addition for all targets */
      AI_ConfigBitAsOutput(13);
    #endif
    AI_ConfigBitAsOutput(14);
    AI_ConfigBitAsOutput(15);
  #endif
}

/*
 * AI_SelectIOForIT
 *
 * Select which IO will be used to generate an interrupt.
 * 'Edge' specifies if interrup must be detected on falling or rising edge.
 *
 * Warning: parameters are not checked.
 */
 
void AI_SelectIOForIT (SYS_UWORD16 Pin, SYS_UWORD16 Edge)
{
  #if (CHIPSET == 12)
    /*
     *  Update INTERRUPT_LEVEL_REG with Edge configuration on Pin selection
     */
    GPIO_INTERRUPT_LEVEL_REG = (Edge & 0x0001) << Pin;

    /*
     *  Update INTERRUPT_MASK_REG to enable interrupt generation on Pin selection
     */
    GPIO_INTERRUPT_MASK_REG = 1 << Pin;
  #else
    /*
     * Bit SET_GPIO_EVENT_MODE (bit 0) is set to enable the GPIO event mode.
     */
     
    *((volatile SYS_UWORD16 *) ARMIO_GPIO_EVENT_MODE) = (Pin << 1) + (Edge << 5) + 1;
  #endif
}

#if (CHIPSET != 12)
/*
 * AI_CheckITSource
 *
 * Check if the interrupt specified by 'Source' is active or not.
 *
 * Output: 0: IT is not active
 *         1: IT is active
 *
 * Warning: parameters are not checked.
 *
 * Warning: If the keypad and GPIO interrupts may occur the GPIO interrupt
 *          must be checked first because the GPIO status bit is reset when
 *          the register is read.
 */
 
int  AI_CheckITSource (SYS_UWORD16 Source)
{
    return (*((volatile SYS_UWORD16 *) ARMIO_KBD_GPIO_INT) & Source ? 1 : 0);
}

/*
 * AI_UnmaskIT
 *
 * Unmask the IT specified by 'Source' (keyboard or GPIO).
 *
 * Warning: parameters are not checked.
 */
 
void AI_UnmaskIT (SYS_UWORD16 Source)
{
    *((volatile SYS_UWORD16 *) ARMIO_KBD_GPIO_MASKIT) &= ~Source;
}

/*
 * AI_MaskIT
 *
 * Mask the IT specified by 'Source' (keyboard or GPIO).
 *
 * Warning: parameters are not checked.
 */
 
void AI_MaskIT (SYS_UWORD16 Source)
{
    *((volatile SYS_UWORD16 *) ARMIO_KBD_GPIO_MASKIT) |= Source;
}
#endif /* CHIPSET != 12 */

#if (CHIPSET == 12)

  void AI_MaskIT(SYS_UWORD16 d_io_number) {
    GPIO_INTERRUPT_MASK_REG |= (1 << d_io_number);
  } /* f_gpio_mask_it() */
  
  void AI_UnmaskIT(SYS_UWORD16 d_io_number) {
    GPIO_INTERRUPT_MASK_REG &= ~(1 << d_io_number);
  } /* f_gpio_unmask_it() */

#endif