static void enable_usb_vbus(void) { qm_gpio_port_config_t cfg = {0}; cfg.direction |= BIT(USB_VBUS_GPIO_PIN); qm_gpio_set_config(USB_VBUS_GPIO_PORT, &cfg); qm_gpio_set_pin(USB_VBUS_GPIO_PORT, USB_VBUS_GPIO_PIN); }
static void spi_cb_dispatch(void *user_data, process_event_t ev, process_data_t ev_data) { struct sol_spi *spi = (struct sol_spi *)ev_data; qm_gpio_set_pin(spi->slave_select.port, spi->slave_select.pin); spi->xfer.cb((void *)spi->xfer.data, spi, spi->xfer.xfer.tx, spi->xfer.xfer.rx, spi->xfer.status); }
/* * Configure a GPIO pin (or onboard LED pin) as an output and drive an * initial value. */ static void gpio_set_out(unsigned int pin, unsigned int initial_value) { gpio_cfg.direction = BIT(pin); /* Configure pin for output. */ qm_gpio_set_config(QM_GPIO_0, &gpio_cfg); if (initial_value) { qm_gpio_set_pin(QM_GPIO_0, pin); } else { qm_gpio_clear_pin(QM_GPIO_0, pin); } }
/* * Configure a GPIO pin (or onboard LED pin) as an output and drive an * initial value. */ static void gpio_set_out(unsigned int pin, unsigned int initial_value) { qm_pmux_select(pin, QM_PMUX_FN_0); /* Pin Muxing. */ gpio_cfg.direction = BIT(pin); /* Configure pin for output. */ qm_gpio_set_config(QM_GPIO_0, &gpio_cfg); if (initial_value) { qm_gpio_set_pin(QM_GPIO_0, pin); } else { qm_gpio_clear_pin(QM_GPIO_0, pin); } }
int main(void) { qm_rtc_config_t rtc_cfg; uint32_t aonc_start; uint32_t rtc_trigger; /* Initialise RTC configuration. */ rtc_cfg.init_val = 0; /* Set initial value to 0. */ rtc_cfg.alarm_en = 1; /* Enable alarm. */ rtc_cfg.alarm_val = QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1); /* 1s alarm. */ rtc_cfg.callback = NULL; rtc_cfg.callback_data = NULL; rtc_cfg.prescaler = CLK_RTC_DIV_1; qm_rtc_set_config(QM_RTC_0, &rtc_cfg); /* * The RTC clock resides in a different clock domain * to the system clock. * It takes 3-4 RTC ticks for a system clock write to propagate * to the RTC domain. * If an entry to sleep is initiated without waiting for the * transaction to complete the SOC will not wake from sleep. */ aonc_start = QM_AONC[QM_AONC_0]->aonc_cnt; while (QM_AONC[QM_AONC_0]->aonc_cnt - aonc_start < RTC_SYNC_CLK_COUNT) { } QM_IR_UNMASK_INT(QM_IRQ_RTC_0_INT); QM_IRQ_REQUEST(QM_IRQ_RTC_0_INT, qm_rtc_0_isr); /* * Enable LPSS by the Sensor Subsystem. * This will clock gate sensor peripherals. */ qm_ss_power_soc_lpss_enable(); /* * Signal to the x86 core that the Sensor Subsystem * is ready to enter LPSS mode. */ QM_SCSS_GP->gps2 |= QM_SCSS_GP_SENSOR_READY; rtc_trigger = switch_rtc_to_level(); /* Go to LPSS, RTC will wake the Sensor Subsystem up. */ qm_ss_power_cpu_ss2(); /* Log the interrupt event in soc_watch. */ SOC_WATCH_LOG_EVENT(SOCW_EVENT_INTERRUPT, QM_IRQ_RTC_0_INT_VECTOR); restore_rtc_trigger(rtc_trigger); /* Clear the SENSOR_READY flag in General Purpose Sticky Register 2. */ QM_SCSS_GP->gps2 &= ~QM_SCSS_GP_SENSOR_READY; /* * Disable LPSS. * This will restore clock gating of sensor peripherals. */ qm_ss_power_soc_lpss_disable(); /* Core still in C2 mode. */ qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT); clk_sys_udelay(GPIO_TOGGLE_DELAY); qm_gpio_set_pin(QM_GPIO_0, PIN_OUT); clk_sys_udelay(GPIO_TOGGLE_DELAY); qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT); /* Set another alarm 1 second from now. */ qm_rtc_set_alarm(QM_RTC_0, QM_RTC[QM_RTC_0]->rtc_ccvr + (QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1))); /* * The RTC clock resides in a different clock domain * to the system clock. * It takes 3-4 RTC ticks for a system clock write to propagate * to the RTC domain. * If an entry to sleep is initiated without waiting for the * transaction to complete the SOC will not wake from sleep. */ aonc_start = QM_AONC[QM_AONC_0]->aonc_cnt; while (QM_AONC[QM_AONC_0]->aonc_cnt - aonc_start < RTC_SYNC_CLK_COUNT) { } /* * Enable LPSS by the Sensor Subsystem. * This will clock gate sensor peripherals. */ qm_ss_power_soc_lpss_enable(); /* * Signal to the x86 core that the Sensor Subsystem * is ready to enter LPSS mode. */ QM_SCSS_GP->gps2 |= QM_SCSS_GP_SENSOR_READY; rtc_trigger = switch_rtc_to_level(); /* Go to LPSS, RTC will wake the Sensor Subsystem up. */ qm_ss_power_cpu_ss2(); /* Log the interrupt event in soc_watch. */ SOC_WATCH_LOG_EVENT(SOCW_EVENT_INTERRUPT, QM_IRQ_RTC_0_INT_VECTOR); restore_rtc_trigger(rtc_trigger); /* Clear the SENSOR_READY flag in General Purpose Sticky Register 2. */ QM_SCSS_GP->gps2 &= ~QM_SCSS_GP_SENSOR_READY; /* * Disable LPSS. * This will restore clock gating of sensor peripherals. */ qm_ss_power_soc_lpss_disable(); /* Core still in C2LP mode. */ qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT); clk_sys_udelay(GPIO_TOGGLE_DELAY); qm_gpio_set_pin(QM_GPIO_0, PIN_OUT); clk_sys_udelay(GPIO_TOGGLE_DELAY); qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT); /* Trigger soc_watch flush. */ SOC_WATCH_TRIGGER_FLUSH(); return 0; }
static int spi_set_gpio_ss(struct sol_spi *spi) { qm_gpio_port_config_t cfg; uint32_t mask; qm_rc_t ret; #if QUARK_SE spi->slave_select.port = QM_GPIO_0; switch (spi->bus) { case QM_SPI_MST_0: switch (spi->slave) { case QM_SPI_SS_0: spi->slave_select.pin = 24; break; case QM_SPI_SS_1: spi->slave_select.pin = 25; break; case QM_SPI_SS_2: spi->slave_select.pin = 26; break; case QM_SPI_SS_3: spi->slave_select.pin = 27; break; default: return -EINVAL; } break; case QM_SPI_MST_1: switch (spi->slave) { case QM_SPI_SS_0: spi->slave_select.pin = 11; break; case QM_SPI_SS_1: spi->slave_select.pin = 12; break; case QM_SPI_SS_2: spi->slave_select.pin = 13; break; case QM_SPI_SS_3: spi->slave_select.pin = 14; break; default: return -EINVAL; } break; default: return -EINVAL; } #elif QUARK_D2000 spi->slave_select.port = QM_GPIO_0; switch (spi->slave) { case QM_SPI_SS_0: spi->slave_select.pin = 0; break; case QM_SPI_SS_1: spi->slave_select.pin = 1; break; case QM_SPI_SS_2: spi->slave_select.pin = 2; break; case QM_SPI_SS_3: spi->slave_select.pin = 3; break; default: return -EINVAL; } #endif mask = BIT(spi->slave_select.pin); ret = qm_gpio_get_config(spi->slave_select.port, &cfg); SOL_EXP_CHECK(ret != QM_RC_OK, -EIO); cfg.direction |= mask; cfg.int_en &= mask; ret = qm_gpio_set_config(spi->slave_select.port, &cfg); SOL_EXP_CHECK(ret != QM_RC_OK, -EIO); qm_gpio_set_pin(spi->slave_select.port, spi->slave_select.pin); return 0; }