Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: modify set_cs_timing parameter

This patch modified set_cs_timing parameter, no need pass in spi_delay
to set_cs_timing callback.
By the way, we modified the mediatek and tegra114 spi driver to fix build err.
In mediatek spi driver, We have support set absolute time not clk_count,
and call this function in prepare_message not user's API.

Signed-off-by: Mason Zhang <Mason.Zhang@mediatek.com>
Link: https://lore.kernel.org/r/20210804133746.6742-1-Mason.Zhang@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Mason Zhang and committed by
Mark Brown
04e6bb0d 8c33ebfe

+66 -52
+61 -46
drivers/spi/spi-mt65xx.c
··· 208 208 writel(reg_val, mdata->base + SPI_CMD_REG); 209 209 } 210 210 211 + static int mtk_spi_set_hw_cs_timing(struct spi_device *spi) 212 + { 213 + struct mtk_spi *mdata = spi_master_get_devdata(spi->master); 214 + struct spi_delay *cs_setup = &spi->cs_setup; 215 + struct spi_delay *cs_hold = &spi->cs_hold; 216 + struct spi_delay *cs_inactive = &spi->cs_inactive; 217 + u16 setup, hold, inactive; 218 + u32 reg_val; 219 + int delay; 220 + 221 + delay = spi_delay_to_ns(cs_setup, NULL); 222 + if (delay < 0) 223 + return delay; 224 + setup = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000; 225 + 226 + delay = spi_delay_to_ns(cs_hold, NULL); 227 + if (delay < 0) 228 + return delay; 229 + hold = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000; 230 + 231 + delay = spi_delay_to_ns(cs_inactive, NULL); 232 + if (delay < 0) 233 + return delay; 234 + inactive = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000; 235 + 236 + setup = setup ? setup : 1; 237 + hold = hold ? hold : 1; 238 + inactive = inactive ? inactive : 1; 239 + 240 + reg_val = readl(mdata->base + SPI_CFG0_REG); 241 + if (mdata->dev_comp->enhance_timing) { 242 + hold = min(hold, 0xffff); 243 + setup = min(setup, 0xffff); 244 + reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET); 245 + reg_val |= (((hold - 1) & 0xffff) 246 + << SPI_ADJUST_CFG0_CS_HOLD_OFFSET); 247 + reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET); 248 + reg_val |= (((setup - 1) & 0xffff) 249 + << SPI_ADJUST_CFG0_CS_SETUP_OFFSET); 250 + } else { 251 + hold = min(hold, 0xff); 252 + setup = min(setup, 0xff); 253 + reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET); 254 + reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET); 255 + reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET); 256 + reg_val |= (((setup - 1) & 0xff) 257 + << SPI_CFG0_CS_SETUP_OFFSET); 258 + } 259 + writel(reg_val, mdata->base + SPI_CFG0_REG); 260 + 261 + inactive = min(inactive, 0xff); 262 + reg_val = readl(mdata->base + SPI_CFG1_REG); 263 + reg_val &= ~SPI_CFG1_CS_IDLE_MASK; 264 + reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET); 265 + writel(reg_val, mdata->base + SPI_CFG1_REG); 266 + 267 + return 0; 268 + } 269 + 211 270 static int mtk_spi_prepare_message(struct spi_master *master, 212 271 struct spi_message *msg) 213 272 { ··· 343 284 << SPI_CFG1_GET_TICK_DLY_OFFSET); 344 285 writel(reg_val, mdata->base + SPI_CFG1_REG); 345 286 287 + /* set hw cs timing */ 288 + mtk_spi_set_hw_cs_timing(spi); 346 289 return 0; 347 290 } 348 291 ··· 587 526 return (xfer->len > MTK_SPI_MAX_FIFO_SIZE && 588 527 (unsigned long)xfer->tx_buf % 4 == 0 && 589 528 (unsigned long)xfer->rx_buf % 4 == 0); 590 - } 591 - 592 - static int mtk_spi_set_hw_cs_timing(struct spi_device *spi, 593 - struct spi_delay *setup, 594 - struct spi_delay *hold, 595 - struct spi_delay *inactive) 596 - { 597 - struct mtk_spi *mdata = spi_master_get_devdata(spi->master); 598 - u16 setup_dly, hold_dly, inactive_dly; 599 - u32 reg_val; 600 - 601 - if ((setup && setup->unit != SPI_DELAY_UNIT_SCK) || 602 - (hold && hold->unit != SPI_DELAY_UNIT_SCK) || 603 - (inactive && inactive->unit != SPI_DELAY_UNIT_SCK)) { 604 - dev_err(&spi->dev, 605 - "Invalid delay unit, should be SPI_DELAY_UNIT_SCK\n"); 606 - return -EINVAL; 607 - } 608 - 609 - setup_dly = setup ? setup->value : 1; 610 - hold_dly = hold ? hold->value : 1; 611 - inactive_dly = inactive ? inactive->value : 1; 612 - 613 - reg_val = readl(mdata->base + SPI_CFG0_REG); 614 - if (mdata->dev_comp->enhance_timing) { 615 - reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET); 616 - reg_val |= (((hold_dly - 1) & 0xffff) 617 - << SPI_ADJUST_CFG0_CS_HOLD_OFFSET); 618 - reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET); 619 - reg_val |= (((setup_dly - 1) & 0xffff) 620 - << SPI_ADJUST_CFG0_CS_SETUP_OFFSET); 621 - } else { 622 - reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET); 623 - reg_val |= (((hold_dly - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET); 624 - reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET); 625 - reg_val |= (((setup_dly - 1) & 0xff) 626 - << SPI_CFG0_CS_SETUP_OFFSET); 627 - } 628 - writel(reg_val, mdata->base + SPI_CFG0_REG); 629 - 630 - reg_val = readl(mdata->base + SPI_CFG1_REG); 631 - reg_val &= ~SPI_CFG1_CS_IDLE_MASK; 632 - reg_val |= (((inactive_dly - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET); 633 - writel(reg_val, mdata->base + SPI_CFG1_REG); 634 - 635 - return 0; 636 529 } 637 530 638 531 static int mtk_spi_setup(struct spi_device *spi)
+4 -4
drivers/spi/spi-tegra114.c
··· 717 717 dma_release_channel(dma_chan); 718 718 } 719 719 720 - static int tegra_spi_set_hw_cs_timing(struct spi_device *spi, 721 - struct spi_delay *setup, 722 - struct spi_delay *hold, 723 - struct spi_delay *inactive) 720 + static int tegra_spi_set_hw_cs_timing(struct spi_device *spi) 724 721 { 725 722 struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master); 723 + struct spi_delay *setup = &spi->cs_setup; 724 + struct spi_delay *hold = &spi->cs_hold; 725 + struct spi_delay *inactive = &spi->cs_inactive; 726 726 u8 setup_dly, hold_dly, inactive_dly; 727 727 u32 setup_hold; 728 728 u32 spi_cs_timing;
+1 -2
include/linux/spi/spi.h
··· 554 554 * to configure specific CS timing through spi_set_cs_timing() after 555 555 * spi_setup(). 556 556 */ 557 - int (*set_cs_timing)(struct spi_device *spi, struct spi_delay *setup, 558 - struct spi_delay *hold, struct spi_delay *inactive); 557 + int (*set_cs_timing)(struct spi_device *spi); 559 558 560 559 /* bidirectional bulk transfers 561 560 *