예제 #1
0
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;
}
예제 #2
0
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
}
예제 #3
0
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);
}
예제 #4
0
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;
}
예제 #5
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;
}
예제 #6
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);
		}
	}
예제 #7
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: