FreeCalypso > hg > fc-tourmaline
diff src/cs/drivers/drv_core/armio/armio.c @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children | 6fb17a32c5bd |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/drivers/drv_core/armio/armio.c Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,488 @@ +/* + * 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 (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