view src/cs/drivers/drv_core/armio/armio.c @ 276:4221c724c664

R2D: preparations for adding LCD hardware suspend handling
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 07 Sep 2021 21:05:38 +0000
parents 6fb17a32c5bd
children
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 !!!

#ifdef CONFIG_TANGO_MODEM
#include "ffs/ffs_api.h"

SYS_UWORD8 AI_Tango_pinmux[4];
#endif

#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_MCSI_MODEM) || 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) = 0x3F05;
#elif defined(CONFIG_TARGET_LUNA)
      *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x2106;
#elif (MMI != 0) || defined(CONFIG_GPIO1_HIGH)
      *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x3F06;
#else
      *((volatile SYS_UWORD16 *) ARMIO_OUT) = 0x3F04;
#endif

    // ARMIO_CNTL_REG register configuration :
    // set IOs 1,2,5,7,9,14 and 15 as ouputs.
    // all others are FreeCalypso additions
    #if defined(CONFIG_GPIO046_OUTPUTS) || defined(CONFIG_TARGET_GTM900)
      AI_ConfigBitAsOutput(0);
    #endif
    #ifndef CONFIG_TANGO_MODEM	/* we do dynamic config on Tango instead */
      AI_ConfigBitAsOutput(1);
      #ifndef CONFIG_TARGET_LEONARDO	/* GPIO 2 is an input on Leonardo! */
        AI_ConfigBitAsOutput(2);
      #endif
      #ifdef CONFIG_GPIO3_OUTPUT
        AI_ConfigBitAsOutput(3);
      #endif
    #endif
    #ifdef CONFIG_GPIO046_OUTPUTS
      AI_ConfigBitAsOutput(4);
    #endif
    AI_ConfigBitAsOutput(5);
    #ifdef CONFIG_GPIO046_OUTPUTS
      AI_ConfigBitAsOutput(6);
    #endif
    AI_ConfigBitAsOutput(7);
    #if 1	/* FreeCalypso addition for all targets */
      AI_ConfigBitAsOutput(8);
    #endif
    AI_ConfigBitAsOutput(9);
    #ifdef CONFIG_MCSI_UNUSED
      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
}

#ifdef CONFIG_TANGO_MODEM
void AI_Init_Tango_pinmux(void)
{
	ffs_file_read("/etc/tango-pinmux", AI_Tango_pinmux, 4);
	/* apply this config */
	if (AI_Tango_pinmux[0] & 0x80) {
		if (AI_Tango_pinmux[0] & 1)
			AI_SetBit(1);
		else
			AI_ResetBit(1);
		AI_ConfigBitAsOutput(1);
	}
	/* GPIO2 config */
	if (AI_Tango_pinmux[1] & 0x02) {
		if (AI_Tango_pinmux[1] & 0x01)
			AI_SetBit(2);
		else
			AI_ResetBit(2);
		AI_ConfigBitAsOutput(2);
	}
	/* GPIO3 config */
	if (AI_Tango_pinmux[1] & 0x20) {
		if (AI_Tango_pinmux[1] & 0x10)
			AI_SetBit(3);
		else
			AI_ResetBit(3);
		AI_ConfigBitAsOutput(3);
	}
	/* RESET_OUT/IO7 config */
	if (AI_Tango_pinmux[2] & 0x08) {
		AI_EnableBit(3);
		if (AI_Tango_pinmux[2] & 0x02) {
			if (AI_Tango_pinmux[2] & 0x01)
				AI_SetBit(7);
			else
				AI_ResetBit(7);
		} else
			AI_ConfigBitAsInput(7);
	}
	/* MCSI/GPIO config */
	if (AI_Tango_pinmux[2] & 0x80) {
		if (AI_Tango_pinmux[3] & 0x10) {
			if (AI_Tango_pinmux[3] & 0x01)
				AI_SetBit(9);
			else
				AI_ResetBit(9);
		} else
			AI_ConfigBitAsInput(9);
		AI_EnableBit(5);
		AI_EnableBit(6);
		AI_EnableBit(7);
		AI_EnableBit(8);
		if (AI_Tango_pinmux[3] & 0x20) {
			if (AI_Tango_pinmux[3] & 0x02)
				AI_SetBit(10);
			else
				AI_ResetBit(10);
			AI_ConfigBitAsOutput(10);
		}
		if (AI_Tango_pinmux[3] & 0x40) {
			if (AI_Tango_pinmux[3] & 0x04)
				AI_SetBit(11);
			else
				AI_ResetBit(11);
			AI_ConfigBitAsOutput(11);
		}
		if (AI_Tango_pinmux[3] & 0x80) {
			if (AI_Tango_pinmux[3] & 0x08)
				AI_SetBit(12);
			else
				AI_ResetBit(12);
			AI_ConfigBitAsOutput(12);
		}
	}
}
#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