/* Configure GPIO */ int pm8x41_gpio_config(uint8_t gpio, struct pm8x41_gpio *config) { uint8_t val; uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio); /* Disable the GPIO */ val = REG_READ(gpio_base + GPIO_EN_CTL); val &= ~BIT(PERPH_EN_BIT); REG_WRITE(gpio_base + GPIO_EN_CTL, val); /* Select the mode */ val = config->function | (config->direction << 4); REG_WRITE(gpio_base + GPIO_MODE_CTL, val); /* Set the right pull */ val = config->pull; REG_WRITE(gpio_base + GPIO_DIG_PULL_CTL, val); /* Select the VIN */ val = config->vin_sel; REG_WRITE(gpio_base + GPIO_DIG_VIN_CTL, val); if (config->direction == PM_GPIO_DIR_OUT) { /* Set the right dig out control */ val = config->out_strength | (config->output_buffer << 4); REG_WRITE(gpio_base + GPIO_DIG_OUT_CTL, val); } /* Enable the GPIO */ val = REG_READ(gpio_base + GPIO_EN_CTL); val |= BIT(PERPH_EN_BIT); REG_WRITE(gpio_base + GPIO_EN_CTL, val); return 0; }
/* Configure GPIO */ int pm8x41_gpio_config(uint8_t gpio, struct pm8x41_gpio *config) { uint8_t val; uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio); /* Only input configuration is implemented at this time. */ ASSERT(config->direction == PM_GPIO_DIR_IN); /* Disable the GPIO */ val = REG_READ(gpio_base + GPIO_EN_CTL); val &= ~BIT(PERPH_EN_BIT); REG_WRITE(gpio_base + GPIO_EN_CTL, val); /* Select the mode */ val = config->function | (config->direction << 4); REG_WRITE(gpio_base + GPIO_MODE_CTL, val); /* Set the right pull */ val = config->pull; REG_WRITE(gpio_base + GPIO_DIG_PULL_CTL, val); /* Select the VIN */ val = config->vin_sel; REG_WRITE(gpio_base + GPIO_DIG_VIN_CTL, val); /* Enable the GPIO */ val = REG_READ(gpio_base + GPIO_EN_CTL); val |= BIT(PERPH_EN_BIT); REG_WRITE(gpio_base + GPIO_EN_CTL, val); return 1; }
/* Write the output value of the requested gpio */ int pm8x41_gpio_set(uint8_t gpio, uint8_t value) { uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio); uint8_t val; /* Set the output value of the gpio */ val = REG_READ(gpio_base + GPIO_MODE_CTL); val = (val & ~PM_GPIO_OUTPUT_MASK) | value; REG_WRITE(gpio_base + GPIO_MODE_CTL, val); return 0; }
/* Reads the status of requested gpio */ int pm8x41_gpio_get(uint8_t gpio, uint8_t *status) { uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio); *status = REG_READ(gpio_base + GPIO_STATUS); /* Return the value of the GPIO pin */ *status &= BIT(GPIO_STATUS_VAL_BIT); dprintf(SPEW, "GPIO %d status is %d\n", gpio, *status); return 1; }
/* Reads the status of requested gpio */ int pm8x41_gpio_get_sid(uint8_t sid, uint8_t gpio, uint8_t *status) { uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio); gpio_base &= 0x0ffff; /* clear sid */ gpio_base |= (sid << 16); /* add sid */ *status = REG_READ(gpio_base + GPIO_STATUS); /* Return the value of the GPIO pin */ *status &= BIT(GPIO_STATUS_VAL_BIT); dprintf(SPEW, "GPIO %d status is %d\n", gpio, *status); return 0; }
/* Write the output value of the requested gpio */ int pm8x41_gpio_set_sid(uint8_t sid, uint8_t gpio, uint8_t value) { uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio); uint8_t val; gpio_base &= 0x0ffff; /* clear sid */ gpio_base |= (sid << 16); /* add sid */ dprintf(SPEW, "%s: gpio=%d base=%x\n", __func__, gpio, gpio_base); /* Set the output value of the gpio */ val = REG_READ(gpio_base + GPIO_MODE_CTL); val = (val & ~PM_GPIO_OUTPUT_MASK) | value; REG_WRITE(gpio_base + GPIO_MODE_CTL, val); return 0; }
/* Configure PM and PMI GPIO with slave id */ int pm8x41_gpio_config_sid(uint8_t sid, uint8_t gpio, struct pm8x41_gpio *config) { uint8_t val; uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio); gpio_base &= 0x0ffff; /* clear sid */ gpio_base |= (sid << 16); /* add sid */ dprintf(SPEW, "%s: gpio=%d base=%x\n", __func__, gpio, gpio_base); /* Disable the GPIO */ val = REG_READ(gpio_base + GPIO_EN_CTL); val &= ~BIT(PERPH_EN_BIT); REG_WRITE(gpio_base + GPIO_EN_CTL, val); /* Select the mode */ val = config->function | (config->direction << 4); REG_WRITE(gpio_base + GPIO_MODE_CTL, val); /* Set the right pull */ val = config->pull; REG_WRITE(gpio_base + GPIO_DIG_PULL_CTL, val); /* Select the VIN */ val = config->vin_sel; REG_WRITE(gpio_base + GPIO_DIG_VIN_CTL, val); if (config->direction == PM_GPIO_DIR_OUT) { /* Set the right dig out control */ val = config->out_strength | (config->output_buffer << 4); REG_WRITE(gpio_base + GPIO_DIG_OUT_CTL, val); } /* Enable the GPIO */ val = REG_READ(gpio_base + GPIO_EN_CTL); val |= BIT(PERPH_EN_BIT); REG_WRITE(gpio_base + GPIO_EN_CTL, val); return 0; }