• Home
  • Raw
  • Download

Lines Matching +full:clkdiv +full:- +full:-

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012-2013 Uwe Kleine-Koenig for Pengutronix
14 #include <linux/platform_data/efm32-spi.h>
17 #define DRIVER_NAME "efm32-spi"
30 #define REG_FRAME_DATABITS(n) ((n) - 3)
86 #define ddata_to_dev(ddata) (&(ddata->bitbang.master->dev))
93 writel_relaxed(value, ddata->base + offset); in efm32_spi_write32()
98 return readl_relaxed(ddata->base + offset); in efm32_spi_read32()
104 struct efm32_spi_ddata *ddata = spi_master_get_devdata(spi->master); in efm32_spi_setup_transfer()
106 unsigned bpw = t->bits_per_word ?: spi->bits_per_word; in efm32_spi_setup_transfer()
107 unsigned speed = t->speed_hz ?: spi->max_speed_hz; in efm32_spi_setup_transfer()
108 unsigned long clkfreq = clk_get_rate(ddata->clk); in efm32_spi_setup_transfer()
109 u32 clkdiv; in efm32_spi_setup_transfer() local
112 (spi->mode & SPI_CPHA ? REG_CTRL_CLKPHA : 0) | in efm32_spi_setup_transfer()
113 (spi->mode & SPI_CPOL ? REG_CTRL_CLKPOL : 0), REG_CTRL); in efm32_spi_setup_transfer()
119 clkdiv = 0; in efm32_spi_setup_transfer()
121 clkdiv = 64 * (DIV_ROUND_UP(2 * clkfreq, speed) - 4); in efm32_spi_setup_transfer()
123 if (clkdiv > (1U << 21)) in efm32_spi_setup_transfer()
124 return -EINVAL; in efm32_spi_setup_transfer()
126 efm32_spi_write32(ddata, clkdiv, REG_CLKDIV); in efm32_spi_setup_transfer()
137 if (ddata->tx_buf) { in efm32_spi_tx_u8()
138 val = *ddata->tx_buf; in efm32_spi_tx_u8()
139 ddata->tx_buf++; in efm32_spi_tx_u8()
142 ddata->tx_len--; in efm32_spi_tx_u8()
152 if (ddata->rx_buf) { in efm32_spi_rx_u8()
153 *ddata->rx_buf = rxdata; in efm32_spi_rx_u8()
154 ddata->rx_buf++; in efm32_spi_rx_u8()
157 ddata->rx_len--; in efm32_spi_rx_u8()
162 while (ddata->tx_len && in efm32_spi_filltx()
163 ddata->tx_len + 2 > ddata->rx_len && in efm32_spi_filltx()
171 struct efm32_spi_ddata *ddata = spi_master_get_devdata(spi->master); in efm32_spi_txrx_bufs()
172 int ret = -EBUSY; in efm32_spi_txrx_bufs()
174 spin_lock_irq(&ddata->lock); in efm32_spi_txrx_bufs()
176 if (ddata->tx_buf || ddata->rx_buf) in efm32_spi_txrx_bufs()
179 ddata->tx_buf = t->tx_buf; in efm32_spi_txrx_bufs()
180 ddata->rx_buf = t->rx_buf; in efm32_spi_txrx_bufs()
181 ddata->tx_len = ddata->rx_len = in efm32_spi_txrx_bufs()
182 t->len * DIV_ROUND_UP(t->bits_per_word, 8); in efm32_spi_txrx_bufs()
186 reinit_completion(&ddata->done); in efm32_spi_txrx_bufs()
190 spin_unlock_irq(&ddata->lock); in efm32_spi_txrx_bufs()
192 wait_for_completion(&ddata->done); in efm32_spi_txrx_bufs()
194 spin_lock_irq(&ddata->lock); in efm32_spi_txrx_bufs()
196 ret = t->len - max(ddata->tx_len, ddata->rx_len); in efm32_spi_txrx_bufs()
199 ddata->tx_buf = ddata->rx_buf = NULL; in efm32_spi_txrx_bufs()
202 spin_unlock_irq(&ddata->lock); in efm32_spi_txrx_bufs()
212 spin_lock(&ddata->lock); in efm32_spi_rxirq()
214 while (ddata->rx_len > 0 && in efm32_spi_rxirq()
222 if (!ddata->rx_len) { in efm32_spi_rxirq()
229 complete(&ddata->done); in efm32_spi_rxirq()
232 spin_unlock(&ddata->lock); in efm32_spi_rxirq()
243 __func__, ddata->tx_len, ddata->rx_len, in efm32_spi_txirq()
247 spin_lock(&ddata->lock); in efm32_spi_txirq()
252 __func__, ddata->tx_len, ddata->rx_len); in efm32_spi_txirq()
254 if (!ddata->tx_len) { in efm32_spi_txirq()
263 spin_unlock(&ddata->lock); in efm32_spi_txirq()
278 struct device_node *np = pdev->dev.of_node; in efm32_spi_probe_dt()
293 dev_dbg(&pdev->dev, "using location %u\n", location); in efm32_spi_probe_dt()
298 dev_info(&pdev->dev, "fall back to location %u\n", location); in efm32_spi_probe_dt()
301 ddata->pdata.location = location; in efm32_spi_probe_dt()
310 struct device_node *np = pdev->dev.of_node; in efm32_spi_probe()
313 return -EINVAL; in efm32_spi_probe()
315 master = spi_alloc_master(&pdev->dev, sizeof(*ddata)); in efm32_spi_probe()
317 dev_dbg(&pdev->dev, in efm32_spi_probe()
319 return -ENOMEM; in efm32_spi_probe()
323 master->dev.of_node = pdev->dev.of_node; in efm32_spi_probe()
325 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in efm32_spi_probe()
326 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); in efm32_spi_probe()
327 master->use_gpio_descriptors = true; in efm32_spi_probe()
331 ddata->bitbang.master = master; in efm32_spi_probe()
332 ddata->bitbang.setup_transfer = efm32_spi_setup_transfer; in efm32_spi_probe()
333 ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs; in efm32_spi_probe()
335 spin_lock_init(&ddata->lock); in efm32_spi_probe()
336 init_completion(&ddata->done); in efm32_spi_probe()
338 ddata->clk = devm_clk_get(&pdev->dev, NULL); in efm32_spi_probe()
339 if (IS_ERR(ddata->clk)) { in efm32_spi_probe()
340 ret = PTR_ERR(ddata->clk); in efm32_spi_probe()
341 dev_err(&pdev->dev, "failed to get clock: %d\n", ret); in efm32_spi_probe()
347 ret = -ENODEV; in efm32_spi_probe()
348 dev_err(&pdev->dev, "failed to determine base address\n"); in efm32_spi_probe()
353 ret = -EINVAL; in efm32_spi_probe()
354 dev_err(&pdev->dev, "memory resource too small\n"); in efm32_spi_probe()
358 ddata->base = devm_ioremap_resource(&pdev->dev, res); in efm32_spi_probe()
359 if (IS_ERR(ddata->base)) { in efm32_spi_probe()
360 ret = PTR_ERR(ddata->base); in efm32_spi_probe()
368 ddata->rxirq = ret; in efm32_spi_probe()
372 ret = ddata->rxirq + 1; in efm32_spi_probe()
374 ddata->txirq = ret; in efm32_spi_probe()
376 ret = clk_prepare_enable(ddata->clk); in efm32_spi_probe()
378 dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret); in efm32_spi_probe()
387 REG_ROUTE_LOCATION(ddata->pdata.location), REG_ROUTE); in efm32_spi_probe()
389 ret = request_irq(ddata->rxirq, efm32_spi_rxirq, in efm32_spi_probe()
392 dev_err(&pdev->dev, "failed to register rxirq (%d)\n", ret); in efm32_spi_probe()
396 ret = request_irq(ddata->txirq, efm32_spi_txirq, in efm32_spi_probe()
399 dev_err(&pdev->dev, "failed to register txirq (%d)\n", ret); in efm32_spi_probe()
403 ret = spi_bitbang_start(&ddata->bitbang); in efm32_spi_probe()
405 dev_err(&pdev->dev, "spi_bitbang_start failed (%d)\n", ret); in efm32_spi_probe()
407 free_irq(ddata->txirq, ddata); in efm32_spi_probe()
409 free_irq(ddata->rxirq, ddata); in efm32_spi_probe()
411 clk_disable_unprepare(ddata->clk); in efm32_spi_probe()
424 spi_bitbang_stop(&ddata->bitbang); in efm32_spi_remove()
428 free_irq(ddata->txirq, ddata); in efm32_spi_remove()
429 free_irq(ddata->rxirq, ddata); in efm32_spi_remove()
430 clk_disable_unprepare(ddata->clk); in efm32_spi_remove()
438 .compatible = "energymicro,efm32-spi",
459 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");