| .. | .. |
|---|
| 26 | 26 | #include <linux/clk.h> |
|---|
| 27 | 27 | #include <linux/io.h> |
|---|
| 28 | 28 | #include <linux/module.h> |
|---|
| 29 | | -#include <linux/gpio.h> |
|---|
| 29 | +#include <linux/gpio/machine.h> |
|---|
| 30 | +#include <linux/gpio/consumer.h> |
|---|
| 30 | 31 | |
|---|
| 31 | 32 | |
|---|
| 32 | 33 | #define SPI_FIFO_SIZE 4 |
|---|
| .. | .. |
|---|
| 79 | 80 | void __iomem *membase; |
|---|
| 80 | 81 | int baseclk; |
|---|
| 81 | 82 | struct clk *clk; |
|---|
| 82 | | - int last_chipselect; |
|---|
| 83 | + struct gpio_desc *last_chipselect; |
|---|
| 83 | 84 | int last_chipselect_val; |
|---|
| 84 | 85 | }; |
|---|
| 85 | 86 | |
|---|
| .. | .. |
|---|
| 95 | 96 | static void txx9spi_cs_func(struct spi_device *spi, struct txx9spi *c, |
|---|
| 96 | 97 | int on, unsigned int cs_delay) |
|---|
| 97 | 98 | { |
|---|
| 98 | | - int val = (spi->mode & SPI_CS_HIGH) ? on : !on; |
|---|
| 99 | | - |
|---|
| 99 | + /* |
|---|
| 100 | + * The GPIO descriptor will track polarity inversion inside |
|---|
| 101 | + * gpiolib. |
|---|
| 102 | + */ |
|---|
| 100 | 103 | if (on) { |
|---|
| 101 | 104 | /* deselect the chip with cs_change hint in last transfer */ |
|---|
| 102 | | - if (c->last_chipselect >= 0) |
|---|
| 103 | | - gpio_set_value(c->last_chipselect, |
|---|
| 105 | + if (c->last_chipselect) |
|---|
| 106 | + gpiod_set_value(c->last_chipselect, |
|---|
| 104 | 107 | !c->last_chipselect_val); |
|---|
| 105 | | - c->last_chipselect = spi->chip_select; |
|---|
| 106 | | - c->last_chipselect_val = val; |
|---|
| 108 | + c->last_chipselect = spi->cs_gpiod; |
|---|
| 109 | + c->last_chipselect_val = on; |
|---|
| 107 | 110 | } else { |
|---|
| 108 | | - c->last_chipselect = -1; |
|---|
| 111 | + c->last_chipselect = NULL; |
|---|
| 109 | 112 | ndelay(cs_delay); /* CS Hold Time */ |
|---|
| 110 | 113 | } |
|---|
| 111 | | - gpio_set_value(spi->chip_select, val); |
|---|
| 114 | + gpiod_set_value(spi->cs_gpiod, on); |
|---|
| 112 | 115 | ndelay(cs_delay); /* CS Setup Time / CS Recovery Time */ |
|---|
| 113 | 116 | } |
|---|
| 114 | 117 | |
|---|
| .. | .. |
|---|
| 118 | 121 | |
|---|
| 119 | 122 | if (!spi->max_speed_hz) |
|---|
| 120 | 123 | return -EINVAL; |
|---|
| 121 | | - |
|---|
| 122 | | - if (gpio_direction_output(spi->chip_select, |
|---|
| 123 | | - !(spi->mode & SPI_CS_HIGH))) { |
|---|
| 124 | | - dev_err(&spi->dev, "Cannot setup GPIO for chipselect.\n"); |
|---|
| 125 | | - return -EINVAL; |
|---|
| 126 | | - } |
|---|
| 127 | 124 | |
|---|
| 128 | 125 | /* deselect chip */ |
|---|
| 129 | 126 | spin_lock(&c->lock); |
|---|
| .. | .. |
|---|
| 248 | 245 | len -= count * wsize; |
|---|
| 249 | 246 | } |
|---|
| 250 | 247 | m->actual_length += t->len; |
|---|
| 251 | | - if (t->delay_usecs) |
|---|
| 252 | | - udelay(t->delay_usecs); |
|---|
| 248 | + spi_transfer_delay_exec(t); |
|---|
| 253 | 249 | |
|---|
| 254 | 250 | if (!cs_change) |
|---|
| 255 | 251 | continue; |
|---|
| .. | .. |
|---|
| 320 | 316 | return 0; |
|---|
| 321 | 317 | } |
|---|
| 322 | 318 | |
|---|
| 319 | +/* |
|---|
| 320 | + * Chip select uses GPIO only, further the driver is using the chip select |
|---|
| 321 | + * numer (from the device tree "reg" property, and this can only come from |
|---|
| 322 | + * device tree since this i MIPS and there is no way to pass platform data) as |
|---|
| 323 | + * the GPIO number. As the platform has only one GPIO controller (the txx9 GPIO |
|---|
| 324 | + * chip) it is thus using the chip select number as an offset into that chip. |
|---|
| 325 | + * This chip has a maximum of 16 GPIOs 0..15 and this is what all platforms |
|---|
| 326 | + * register. |
|---|
| 327 | + * |
|---|
| 328 | + * We modernized this behaviour by explicitly converting that offset to an |
|---|
| 329 | + * offset on the GPIO chip using a GPIO descriptor machine table of the same |
|---|
| 330 | + * size as the txx9 GPIO chip with a 1-to-1 mapping of chip select to GPIO |
|---|
| 331 | + * offset. |
|---|
| 332 | + * |
|---|
| 333 | + * This is admittedly a hack, but it is countering the hack of using "reg" to |
|---|
| 334 | + * contain a GPIO offset when it should be using "cs-gpios" as the SPI bindings |
|---|
| 335 | + * state. |
|---|
| 336 | + */ |
|---|
| 337 | +static struct gpiod_lookup_table txx9spi_cs_gpio_table = { |
|---|
| 338 | + .dev_id = "spi0", |
|---|
| 339 | + .table = { |
|---|
| 340 | + GPIO_LOOKUP_IDX("TXx9", 0, "cs", 0, GPIO_ACTIVE_LOW), |
|---|
| 341 | + GPIO_LOOKUP_IDX("TXx9", 1, "cs", 1, GPIO_ACTIVE_LOW), |
|---|
| 342 | + GPIO_LOOKUP_IDX("TXx9", 2, "cs", 2, GPIO_ACTIVE_LOW), |
|---|
| 343 | + GPIO_LOOKUP_IDX("TXx9", 3, "cs", 3, GPIO_ACTIVE_LOW), |
|---|
| 344 | + GPIO_LOOKUP_IDX("TXx9", 4, "cs", 4, GPIO_ACTIVE_LOW), |
|---|
| 345 | + GPIO_LOOKUP_IDX("TXx9", 5, "cs", 5, GPIO_ACTIVE_LOW), |
|---|
| 346 | + GPIO_LOOKUP_IDX("TXx9", 6, "cs", 6, GPIO_ACTIVE_LOW), |
|---|
| 347 | + GPIO_LOOKUP_IDX("TXx9", 7, "cs", 7, GPIO_ACTIVE_LOW), |
|---|
| 348 | + GPIO_LOOKUP_IDX("TXx9", 8, "cs", 8, GPIO_ACTIVE_LOW), |
|---|
| 349 | + GPIO_LOOKUP_IDX("TXx9", 9, "cs", 9, GPIO_ACTIVE_LOW), |
|---|
| 350 | + GPIO_LOOKUP_IDX("TXx9", 10, "cs", 10, GPIO_ACTIVE_LOW), |
|---|
| 351 | + GPIO_LOOKUP_IDX("TXx9", 11, "cs", 11, GPIO_ACTIVE_LOW), |
|---|
| 352 | + GPIO_LOOKUP_IDX("TXx9", 12, "cs", 12, GPIO_ACTIVE_LOW), |
|---|
| 353 | + GPIO_LOOKUP_IDX("TXx9", 13, "cs", 13, GPIO_ACTIVE_LOW), |
|---|
| 354 | + GPIO_LOOKUP_IDX("TXx9", 14, "cs", 14, GPIO_ACTIVE_LOW), |
|---|
| 355 | + GPIO_LOOKUP_IDX("TXx9", 15, "cs", 15, GPIO_ACTIVE_LOW), |
|---|
| 356 | + { }, |
|---|
| 357 | + }, |
|---|
| 358 | +}; |
|---|
| 359 | + |
|---|
| 323 | 360 | static int txx9spi_probe(struct platform_device *dev) |
|---|
| 324 | 361 | { |
|---|
| 325 | 362 | struct spi_master *master; |
|---|
| .. | .. |
|---|
| 373 | 410 | if (ret) |
|---|
| 374 | 411 | goto exit; |
|---|
| 375 | 412 | |
|---|
| 376 | | - c->last_chipselect = -1; |
|---|
| 413 | + c->last_chipselect = NULL; |
|---|
| 377 | 414 | |
|---|
| 378 | 415 | dev_info(&dev->dev, "at %#llx, irq %d, %dMHz\n", |
|---|
| 379 | 416 | (unsigned long long)res->start, irq, |
|---|
| 380 | 417 | (c->baseclk + 500000) / 1000000); |
|---|
| 418 | + |
|---|
| 419 | + gpiod_add_lookup_table(&txx9spi_cs_gpio_table); |
|---|
| 381 | 420 | |
|---|
| 382 | 421 | /* the spi->mode bits understood by this driver: */ |
|---|
| 383 | 422 | master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; |
|---|
| .. | .. |
|---|
| 387 | 426 | master->transfer = txx9spi_transfer; |
|---|
| 388 | 427 | master->num_chipselect = (u16)UINT_MAX; /* any GPIO numbers */ |
|---|
| 389 | 428 | master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); |
|---|
| 429 | + master->use_gpio_descriptors = true; |
|---|
| 390 | 430 | |
|---|
| 391 | 431 | ret = devm_spi_register_master(&dev->dev, master); |
|---|
| 392 | 432 | if (ret) |
|---|