static void spi_stm_gpio_chipselect(struct spi_device *spi, int value) { unsigned int out; if (spi->chip_select == (typeof(spi->chip_select))(STM_GPIO_INVALID)) return; if (!spi->controller_data) { if (gpio_request(spi->chip_select, "spi_stm cs")) { dev_err(&spi->dev, "failed to allocate CS pin\n"); return; } spi->controller_data = (void *)1; gpio_direction_output(spi->chip_select, spi->mode & SPI_CS_HIGH); } if (value == BITBANG_CS_ACTIVE) out = spi->mode & SPI_CS_HIGH ? 1 : 0; else out = spi->mode & SPI_CS_HIGH ? 0 : 1; gpio_set_value(spi->chip_select, out); dev_dbg(&spi->dev, "%s PIO%d[%d] -> %d \n", value == BITBANG_CS_ACTIVE ? "select" : "deselect", stm_gpio_port(spi->chip_select), stm_gpio_pin(spi->chip_select), out); return; }
static void stx7108_pio_dump_pad_config(const char *name, int port, struct stm_pad_config *pad_config) { #ifdef DEBUG_RETIME_CONF int i, gpios_num = pad_config->gpios_num; pr_info("%s port=%d, gpios_num = %d\n", name, port, gpios_num); pr_info("GPIO (retime\tclk1notclk0\tclknotdata\tdouble_edge\t" "invertclk\tdelay_input)\n"); for (i = 0; i < gpios_num; i++) { struct stm_pad_gpio *pad_gpio = &pad_config->gpios[i]; struct stx7108_pio_config *priv = pad_gpio->priv; struct stx7108_pio_retime_config *retime = priv->retime; pr_info("PIO%d[%d] %d\t\t%d\t\t%d\t%d\t\t%d\t\t%d\n", stm_gpio_port(pad_gpio->gpio), stm_gpio_pin(pad_gpio->gpio), retime->retime, retime->clk1notclk0, retime->clknotdata, retime->double_edge, retime->invertclk, retime->delay_input); } #endif }
static void stm_gpio_irq_chip_enable(unsigned int pin_irq) { unsigned gpio = irq_to_gpio(pin_irq); int port_no = stm_gpio_port(gpio); int pin_no = stm_gpio_pin(gpio); pr_debug("enabling pin %d\n", pin_no); set__PIO_SET_PMASK__SET_PMASK__SET(stm_gpio_bases[port_no], pin_no); }
int stm_gpio_direction(unsigned int gpio, unsigned int direction) { int port_no = stm_gpio_port(gpio); int pin_no = stm_gpio_pin(gpio); BUG_ON(gpio >= stm_gpio_num); __stm_gpio_direction(&stm_gpio_ports[port_no], pin_no, direction); return 0; }
static int stm_gpio_irq_chip_type(unsigned int pin_irq, unsigned type) { unsigned gpio = irq_to_gpio(pin_irq); int port_no = stm_gpio_port(gpio); int pin_no = stm_gpio_pin(gpio); struct stm_gpio_port *port = &stm_gpio_ports[port_no]; struct stm_gpio_pin *pin = &port->pins[pin_no]; int comp; pr_debug("setting pin %d to type %d\n", pin_no, type); switch (type) { case IRQ_TYPE_EDGE_RISING: pin->flags = PIN_FAKE_EDGE | PIN_IGNORE_FALLING_EDGE; comp = 1; port->irq_level_mask &= ~(1 << pin_no); break; case IRQ_TYPE_LEVEL_HIGH: pin->flags = 0; comp = 0; port->irq_level_mask |= (1 << pin_no); break; case IRQ_TYPE_EDGE_FALLING: pin->flags = PIN_FAKE_EDGE | PIN_IGNORE_RISING_EDGE; comp = 0; port->irq_level_mask &= ~(1 << pin_no); break; case IRQ_TYPE_LEVEL_LOW: pin->flags = 0; comp = 1; port->irq_level_mask |= (1 << pin_no); break; case IRQ_TYPE_EDGE_BOTH: pin->flags = PIN_FAKE_EDGE; comp = gpio_get_value(gpio); port->irq_level_mask &= ~(1 << pin_no); break; default: return -EINVAL; } set__PIO_PCOMP__PCOMP(port->base, pin_no, comp); return 0; }
static int stx5206_pio_config(unsigned gpio, enum stm_pad_gpio_direction direction, int function, void *priv) { int port = stm_gpio_port(gpio); int pin = stm_gpio_pin(gpio); BUG_ON(port > ARRAY_SIZE(stx5206_pio_devices)); if (function == STX5206_GPIO_FUNCTION) { switch (direction) { case stm_pad_gpio_direction_in: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_IN); break; case stm_pad_gpio_direction_out: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_OUT); break; case stm_pad_gpio_direction_bidir: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_BIDIR); break; default: BUG(); break; } } else if (direction == stm_pad_gpio_direction_in) { BUG_ON(function != -1); stm_gpio_direction(gpio, STM_GPIO_DIRECTION_IN); } else { static struct sysconf_field *sys_cfg_16; static struct sysconf_field *sys_cfg_17; switch (direction) { case stm_pad_gpio_direction_out: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_ALT_OUT); break; case stm_pad_gpio_direction_bidir: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_ALT_BIDIR); break; default: BUG(); break; } if (!sys_cfg_16) { sys_cfg_16 = sysconf_claim(SYS_CFG, 16, 0, 31, "PIO Config"); BUG_ON(!sys_cfg_16); sys_cfg_17 = sysconf_claim(SYS_CFG, 17, 0, 31, "PIO Config"); BUG_ON(!sys_cfg_17); } if (port > 0) { struct sysconf_field *cfg; int offset; unsigned int value; BUG_ON(function < 0); BUG_ON(function > 3); if (port < 3) cfg = sys_cfg_16; else cfg = sys_cfg_17; offset = 16 * ((port - 1) % 2) + pin; value = sysconf_read(cfg); value &= ~((1 << (offset + 8)) | (1 << offset)); value |= ((function >> 1) & 1) << (offset + 8); value |= (function & 1) << offset; sysconf_write(cfg, value); } else { BUG_ON(function != 0); } }
[4] = { 34, 4, }, [5] = { 35, 4, }, [6] = { 36, 4, }, [7] = { 37, 4, }, [8] = { 46, 3, }, [9] = { 47, 4, }, [10] = { 39, 2, }, [11] = { 53, 4, }, [12] = { 48, 5, }, [13] = { 49, 5, }, [14] = { 0, 1, }, [15] = { 50, 4, }, [16] = { 54, 2, }, }; int port = stm_gpio_port(gpio); int pin = stm_gpio_pin(gpio); BUG_ON(port > ARRAY_SIZE(functions)); if (function == 0) { switch (direction) { case stm_pad_gpio_direction_in: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_IN); break; case stm_pad_gpio_direction_out: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_OUT); break; case stm_pad_gpio_direction_bidir: stm_gpio_direction(gpio, STM_GPIO_DIRECTION_BIDIR); break; default: