void keyboard_raw_init(void) { keyboard_raw_enable_interrupt(0); gpio_config_module(MODULE_KEYBOARD_SCAN, 1); /* Enable keyboard scan interrupt */ MEC1322_INT_ENABLE(17) |= 1 << 21; MEC1322_INT_BLK_EN |= 1 << 17; MEC1322_KS_KSI_INT_EN = 0xff; }
static void configure_port(int port, int kbps) { MEC1322_I2C_CTRL(port) = CTRL_PIN; MEC1322_I2C_OWN_ADDR(port) = 0x0; configure_port_speed(port, kbps); MEC1322_I2C_CTRL(port) = CTRL_PIN | CTRL_ESO | CTRL_ACK | CTRL_ENI; MEC1322_I2C_CONFIG(port) |= 1 << 10; /* ENAB */ /* Enable interrupt */ MEC1322_I2C_CONFIG(port) |= 1 << 29; /* ENIDI */ MEC1322_INT_ENABLE(12) |= (1 << port); MEC1322_INT_BLK_EN |= 1 << 12; task_enable_irq(MEC1322_IRQ_I2C_0 + port); }
int gpio_enable_interrupt(enum gpio_signal signal) { int i, port, girq_id, bit_id; if (gpio_list[signal].mask == 0) return EC_SUCCESS; i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); port = gpio_list[signal].port; girq_id = int_map[port].girq_id; bit_id = (port - int_map[port].port_offset) * 8 + i; MEC1322_INT_ENABLE(girq_id) |= (1 << bit_id); MEC1322_INT_BLK_EN |= (1 << girq_id); return EC_SUCCESS; }
void system_hibernate(uint32_t seconds, uint32_t microseconds) { int i; #ifdef CONFIG_HOSTCMD_PD /* Inform the PD MCU that we are going to hibernate. */ host_command_pd_request_hibernate(); /* Wait to ensure exchange with PD before hibernating. */ msleep(100); #endif cflush(); if (board_hibernate) board_hibernate(); /* Disable interrupts */ interrupt_disable(); for (i = 0; i <= 92; ++i) { task_disable_irq(i); task_clear_pending_irq(i); } for (i = 8; i <= 23; ++i) MEC1322_INT_DISABLE(i) = 0xffffffff; MEC1322_INT_BLK_DIS |= 0xffff00; /* Power down ADC VREF */ MEC1322_EC_ADC_VREF_PD |= 1; /* Assert nSIO_RESET */ MEC1322_PCR_PWR_RST_CTL |= 1; /* Disable UART */ MEC1322_UART_ACT &= ~0x1; MEC1322_LPC_ACT &= ~0x1; /* Disable JTAG */ MEC1322_EC_JTAG_EN &= ~1; /* Disable 32KHz clock */ MEC1322_VBAT_CE &= ~0x2; /* Stop watchdog */ MEC1322_WDG_CTL &= ~1; /* Stop timers */ MEC1322_TMR32_CTL(0) &= ~1; MEC1322_TMR32_CTL(1) &= ~1; MEC1322_TMR16_CTL(0) &= ~1; /* Power down ADC */ MEC1322_ADC_CTRL &= ~1; /* Disable blocks */ MEC1322_PCR_CHIP_SLP_EN |= 0x3; MEC1322_PCR_EC_SLP_EN |= MEC1322_PCR_EC_SLP_EN_SLEEP; MEC1322_PCR_HOST_SLP_EN |= MEC1322_PCR_HOST_SLP_EN_SLEEP; MEC1322_PCR_EC_SLP_EN2 |= MEC1322_PCR_EC_SLP_EN2_SLEEP; MEC1322_PCR_SLOW_CLK_CTL &= 0xfffffc00; /* Set sleep state */ MEC1322_PCR_SYS_SLP_CTL = (MEC1322_PCR_SYS_SLP_CTL & ~0x7) | 0x2; CPU_SCB_SYSCTRL |= 0x4; /* Setup GPIOs for hibernate */ if (board_hibernate_late) board_hibernate_late(); #ifdef CONFIG_USB_PD_PORT_COUNT /* * Leave USB-C charging enabled in hibernate, in order to * allow wake-on-plug. 5V enable must be pulled low. */ #if CONFIG_USB_PD_PORT_COUNT > 0 gpio_set_flags(GPIO_USB_C0_5V_EN, GPIO_PULL_DOWN | GPIO_INPUT); gpio_set_level(GPIO_USB_C0_CHARGE_EN_L, 0); #endif #if CONFIG_USB_PD_PORT_COUNT > 1 gpio_set_flags(GPIO_USB_C1_5V_EN, GPIO_PULL_DOWN | GPIO_INPUT); gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, 0); #endif #endif /* CONFIG_USB_PD_PORT_COUNT */ if (hibernate_wake_pins_used > 0) { for (i = 0; i < hibernate_wake_pins_used; ++i) { const enum gpio_signal pin = hibernate_wake_pins[i]; gpio_reset(pin); gpio_enable_interrupt(pin); } interrupt_enable(); task_enable_irq(MEC1322_IRQ_GIRQ8); task_enable_irq(MEC1322_IRQ_GIRQ9); task_enable_irq(MEC1322_IRQ_GIRQ10); task_enable_irq(MEC1322_IRQ_GIRQ11); task_enable_irq(MEC1322_IRQ_GIRQ20); } if (seconds || microseconds) { MEC1322_INT_BLK_EN |= 1 << 17; MEC1322_INT_ENABLE(17) |= 1 << 20; interrupt_enable(); task_enable_irq(MEC1322_IRQ_HTIMER); if (seconds > 2) { ASSERT(seconds <= 0xffff / 8); MEC1322_HTIMER_CONTROL = 1; MEC1322_HTIMER_PRELOAD = (seconds * 8 + microseconds / 125000); } else { MEC1322_HTIMER_CONTROL = 0; MEC1322_HTIMER_PRELOAD = (seconds * 1000000 + microseconds) * 2 / 71; } } asm("wfi"); /* Use 48MHz clock to speed through wake-up */ MEC1322_PCR_PROC_CLK_CTL = 1; /* Reboot */ _system_reset(0, 1); /* We should never get here. */ while (1) ; }
/* * Most registers in LPC module are reset when the host is off. We need to * set up LPC again when the host is starting up. */ static void setup_lpc(void) { gpio_config_module(MODULE_LPC, 1); /* Set up interrupt on LRESET# deassert */ MEC1322_INT_SOURCE(19) = 1 << 1; MEC1322_INT_ENABLE(19) |= 1 << 1; MEC1322_INT_BLK_EN |= 1 << 19; task_enable_irq(MEC1322_IRQ_GIRQ19); /* Set up ACPI0 for 0x62/0x66 */ MEC1322_LPC_ACPI_EC0_BAR = 0x00628304; MEC1322_INT_ENABLE(15) |= 1 << 6; MEC1322_INT_BLK_EN |= 1 << 15; /* Clear STATUS_PROCESSING bit in case it was set during sysjump */ MEC1322_ACPI_EC_STATUS(0) &= ~EC_LPC_STATUS_PROCESSING; task_enable_irq(MEC1322_IRQ_ACPIEC0_IBF); /* Set up ACPI1 for 0x200/0x204 */ MEC1322_LPC_ACPI_EC1_BAR = 0x02008407; MEC1322_INT_ENABLE(15) |= 1 << 8; MEC1322_INT_BLK_EN |= 1 << 15; MEC1322_ACPI_EC_STATUS(1) &= ~EC_LPC_STATUS_PROCESSING; task_enable_irq(MEC1322_IRQ_ACPIEC1_IBF); /* Set up 8042 interface at 0x60/0x64 */ MEC1322_LPC_8042_BAR = 0x00608104; /* Set up indication of Auxillary sts */ MEC1322_8042_KB_CTRL |= 1 << 7; MEC1322_8042_ACT |= 1; MEC1322_INT_ENABLE(15) |= ((1 << 13) | (1 << 14)); MEC1322_INT_BLK_EN |= 1 << 15; task_enable_irq(MEC1322_IRQ_8042EM_IBF); task_enable_irq(MEC1322_IRQ_8042EM_OBF); #ifndef CONFIG_KEYBOARD_IRQ_GPIO /* Set up SERIRQ for keyboard */ MEC1322_8042_KB_CTRL |= (1 << 5); MEC1322_LPC_SIRQ(1) = 0x01; #endif /* Set up EMI module for memory mapped region, base address 0x800 */ MEC1322_LPC_EMI_BAR = 0x0800800f; MEC1322_INT_ENABLE(15) |= 1 << 2; MEC1322_INT_BLK_EN |= 1 << 15; task_enable_irq(MEC1322_IRQ_EMI); /* Access data RAM through alias address */ MEC1322_EMI_MBA0 = (uint32_t)mem_mapped - 0x118000 + 0x20000000; /* * Limit EMI read / write range. First 256 bytes are RW for host * commands. Second 256 bytes are RO for mem-mapped data. */ MEC1322_EMI_MRL0 = 0x200; MEC1322_EMI_MWL0 = 0x100; /* Set up Mailbox for Port80 trapping */ MEC1322_MBX_INDEX = 0xff; MEC1322_LPC_MAILBOX_BAR = 0x00808901; /* We support LPC args and version 3 protocol */ *(lpc_get_memmap_range() + EC_MEMMAP_HOST_CMD_FLAGS) = EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED | EC_HOST_CMD_FLAG_VERSION_3; /* Sufficiently initialized */ init_done = 1; /* Update host events now that we can copy them to memmap */ update_host_event_status(); }
void system_hibernate(uint32_t seconds, uint32_t microseconds) { int i; cflush(); /* Disable interrupts */ interrupt_disable(); for (i = 0; i <= 92; ++i) { task_disable_irq(i); task_clear_pending_irq(i); } for (i = 8; i <= 23; ++i) MEC1322_INT_DISABLE(i) = 0xffffffff; MEC1322_INT_BLK_DIS |= 0xffff00; /* Set processor clock to lowest, 1MHz */ MEC1322_PCR_PROC_CLK_CTL = 48; /* Power down ADC VREF */ MEC1322_EC_ADC_VREF_PD |= 1; /* Assert nSIO_RESET */ MEC1322_PCR_PWR_RST_CTL |= 1; /* Disable UART */ MEC1322_UART_ACT &= ~0x1; MEC1322_LPC_ACT &= ~0x1; /* Disable JTAG */ MEC1322_EC_JTAG_EN &= ~1; /* Disable 32KHz clock */ MEC1322_VBAT_CE &= ~0x2; /* Stop watchdog */ MEC1322_WDG_CTL &= ~1; /* Stop timers */ MEC1322_TMR32_CTL(0) &= ~1; MEC1322_TMR32_CTL(1) &= ~1; MEC1322_TMR16_CTL(0) &= ~1; /* Power down ADC */ MEC1322_ADC_CTRL &= ~1; /* Disable blocks */ MEC1322_PCR_CHIP_SLP_EN |= 0x3; MEC1322_PCR_EC_SLP_EN |= 0xe0700ff7; MEC1322_PCR_HOST_SLP_EN |= 0x5f003; MEC1322_PCR_EC_SLP_EN2 |= 0x1ffffff8; MEC1322_PCR_SYS_SLP_CTL = (MEC1322_PCR_SYS_SLP_CTL & ~0x7) | 0x2; MEC1322_PCR_SLOW_CLK_CTL &= 0xfffffc00; CPU_SCB_SYSCTRL |= 0x4; system_unpower_gpio(); #ifdef CONFIG_WAKE_PIN gpio_set_flags_by_mask(gpio_list[CONFIG_WAKE_PIN].port, gpio_list[CONFIG_WAKE_PIN].mask, gpio_list[CONFIG_WAKE_PIN].flags); gpio_enable_interrupt(CONFIG_WAKE_PIN); interrupt_enable(); task_enable_irq(MEC1322_IRQ_GIRQ8); task_enable_irq(MEC1322_IRQ_GIRQ9); task_enable_irq(MEC1322_IRQ_GIRQ10); task_enable_irq(MEC1322_IRQ_GIRQ11); task_enable_irq(MEC1322_IRQ_GIRQ20); #endif if (seconds || microseconds) { MEC1322_INT_BLK_EN |= 1 << 17; MEC1322_INT_ENABLE(17) |= 1 << 20; interrupt_enable(); task_enable_irq(MEC1322_IRQ_HTIMER); if (seconds > 2) { ASSERT(seconds <= 0xffff / 8); MEC1322_HTIMER_CONTROL = 1; MEC1322_HTIMER_PRELOAD = (seconds * 8 + microseconds / 125000); } else { MEC1322_HTIMER_CONTROL = 0; MEC1322_HTIMER_PRELOAD = (seconds * 1000000 + microseconds) * 2 / 71; } } asm("wfi"); /* We lost states of most modules, let's just reboot */ _system_reset(0, 1); }