Lines Matching +full:clock +full:- +full:master
1 // SPDX-License-Identifier: GPL-2.0-only
39 #include <asm/dcr-regs.h>
41 /* bits in mode register - bit 0 is MSb */
44 * SPI_PPC4XX_MODE_SCP = 0 means "data latched on trailing edge of clock"
45 * SPI_PPC4XX_MODE_SCP = 1 means "data latched on leading edge of clock"
54 * SPI_PPC4XX_MODE_RD = 0 means "MSB first" - this is the normal mode
55 * SPI_PPC4XX_MODE_RD = 1 means "LSB first" - this is bit-reversed mode
61 * SPI_PPC4XX_MODE_CI = 0 means "clock idles low"
62 * SPI_PPC4XX_MODE_CI = 1 means "clock idles high"
83 /* clock settings (SCP and CI) for various SPI modes */
99 * Clock divisor modulus register
103 * CDM = (OPBCLK/4*SCPClkOut) - 1
118 /* need this to set the SPI clock */
129 struct spi_master *master; member
133 /* need this so we can set the clock in the chipselect routine */
143 dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", in spi_ppc4xx_txrx()
144 t->tx_buf, t->rx_buf, t->len); in spi_ppc4xx_txrx()
146 hw = spi_master_get_devdata(spi->master); in spi_ppc4xx_txrx()
148 hw->tx = t->tx_buf; in spi_ppc4xx_txrx()
149 hw->rx = t->rx_buf; in spi_ppc4xx_txrx()
150 hw->len = t->len; in spi_ppc4xx_txrx()
151 hw->count = 0; in spi_ppc4xx_txrx()
154 data = hw->tx ? hw->tx[0] : 0; in spi_ppc4xx_txrx()
155 out_8(&hw->regs->txd, data); in spi_ppc4xx_txrx()
156 out_8(&hw->regs->cr, SPI_PPC4XX_CR_STR); in spi_ppc4xx_txrx()
157 wait_for_completion(&hw->done); in spi_ppc4xx_txrx()
159 return hw->count; in spi_ppc4xx_txrx()
164 struct ppc4xx_spi *hw = spi_master_get_devdata(spi->master); in spi_ppc4xx_setupxfer()
165 struct spi_ppc4xx_cs *cs = spi->controller_state; in spi_ppc4xx_setupxfer()
172 bits_per_word = spi->bits_per_word; in spi_ppc4xx_setupxfer()
173 speed = spi->max_speed_hz; in spi_ppc4xx_setupxfer()
180 if (t->bits_per_word) in spi_ppc4xx_setupxfer()
181 bits_per_word = t->bits_per_word; in spi_ppc4xx_setupxfer()
183 if (t->speed_hz) in spi_ppc4xx_setupxfer()
184 speed = min(t->speed_hz, spi->max_speed_hz); in spi_ppc4xx_setupxfer()
187 if (!speed || (speed > spi->max_speed_hz)) { in spi_ppc4xx_setupxfer()
188 dev_err(&spi->dev, "invalid speed_hz (%d)\n", speed); in spi_ppc4xx_setupxfer()
189 return -EINVAL; in spi_ppc4xx_setupxfer()
193 out_8(&hw->regs->mode, cs->mode); in spi_ppc4xx_setupxfer()
195 /* Set the clock */ in spi_ppc4xx_setupxfer()
197 scr = (hw->opb_freq / speed) - 1; in spi_ppc4xx_setupxfer()
201 dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", cdm, speed); in spi_ppc4xx_setupxfer()
203 if (in_8(&hw->regs->cdm) != cdm) in spi_ppc4xx_setupxfer()
204 out_8(&hw->regs->cdm, cdm); in spi_ppc4xx_setupxfer()
206 mutex_lock(&hw->bitbang.lock); in spi_ppc4xx_setupxfer()
207 if (!hw->bitbang.busy) { in spi_ppc4xx_setupxfer()
208 hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); in spi_ppc4xx_setupxfer()
211 mutex_unlock(&hw->bitbang.lock); in spi_ppc4xx_setupxfer()
218 struct spi_ppc4xx_cs *cs = spi->controller_state; in spi_ppc4xx_setup()
220 if (!spi->max_speed_hz) { in spi_ppc4xx_setup()
221 dev_err(&spi->dev, "invalid max_speed_hz (must be non-zero)\n"); in spi_ppc4xx_setup()
222 return -EINVAL; in spi_ppc4xx_setup()
228 return -ENOMEM; in spi_ppc4xx_setup()
229 spi->controller_state = cs; in spi_ppc4xx_setup()
234 * no need to read-modify-write in spi_ppc4xx_setup()
236 cs->mode = SPI_PPC4XX_MODE_SPE; in spi_ppc4xx_setup()
238 switch (spi->mode & (SPI_CPHA | SPI_CPOL)) { in spi_ppc4xx_setup()
240 cs->mode |= SPI_CLK_MODE0; in spi_ppc4xx_setup()
243 cs->mode |= SPI_CLK_MODE1; in spi_ppc4xx_setup()
246 cs->mode |= SPI_CLK_MODE2; in spi_ppc4xx_setup()
249 cs->mode |= SPI_CLK_MODE3; in spi_ppc4xx_setup()
253 if (spi->mode & SPI_LSB_FIRST) in spi_ppc4xx_setup()
254 cs->mode |= SPI_PPC4XX_MODE_RD; in spi_ppc4xx_setup()
268 status = in_8(&hw->regs->sr); in spi_ppc4xx_int()
273 * BSY de-asserts one cycle after the transfer is complete. The in spi_ppc4xx_int()
282 dev_dbg(hw->dev, "got interrupt but spi still busy?\n"); in spi_ppc4xx_int()
285 lstatus = in_8(&hw->regs->sr); in spi_ppc4xx_int()
289 dev_err(hw->dev, "busywait: too many loops!\n"); in spi_ppc4xx_int()
290 complete(&hw->done); in spi_ppc4xx_int()
294 status = in_8(&hw->regs->sr); in spi_ppc4xx_int()
295 dev_dbg(hw->dev, "loops %d status %x\n", cnt, status); in spi_ppc4xx_int()
299 count = hw->count; in spi_ppc4xx_int()
300 hw->count++; in spi_ppc4xx_int()
303 data = in_8(&hw->regs->rxd); in spi_ppc4xx_int()
304 if (hw->rx) in spi_ppc4xx_int()
305 hw->rx[count] = data; in spi_ppc4xx_int()
309 if (count < hw->len) { in spi_ppc4xx_int()
310 data = hw->tx ? hw->tx[count] : 0; in spi_ppc4xx_int()
311 out_8(&hw->regs->txd, data); in spi_ppc4xx_int()
312 out_8(&hw->regs->cr, SPI_PPC4XX_CR_STR); in spi_ppc4xx_int()
314 complete(&hw->done); in spi_ppc4xx_int()
322 kfree(spi->controller_state); in spi_ppc4xx_cleanup()
343 struct spi_master *master; in spi_ppc4xx_of_probe() local
346 struct device_node *np = op->dev.of_node; in spi_ppc4xx_of_probe()
347 struct device *dev = &op->dev; in spi_ppc4xx_of_probe()
352 master = spi_alloc_master(dev, sizeof *hw); in spi_ppc4xx_of_probe()
353 if (master == NULL) in spi_ppc4xx_of_probe()
354 return -ENOMEM; in spi_ppc4xx_of_probe()
355 master->dev.of_node = np; in spi_ppc4xx_of_probe()
356 platform_set_drvdata(op, master); in spi_ppc4xx_of_probe()
357 hw = spi_master_get_devdata(master); in spi_ppc4xx_of_probe()
358 hw->master = master; in spi_ppc4xx_of_probe()
359 hw->dev = dev; in spi_ppc4xx_of_probe()
361 init_completion(&hw->done); in spi_ppc4xx_of_probe()
364 bbp = &hw->bitbang; in spi_ppc4xx_of_probe()
365 bbp->master = hw->master; in spi_ppc4xx_of_probe()
366 bbp->setup_transfer = spi_ppc4xx_setupxfer; in spi_ppc4xx_of_probe()
367 bbp->txrx_bufs = spi_ppc4xx_txrx; in spi_ppc4xx_of_probe()
368 bbp->use_dma = 0; in spi_ppc4xx_of_probe()
369 bbp->master->setup = spi_ppc4xx_setup; in spi_ppc4xx_of_probe()
370 bbp->master->cleanup = spi_ppc4xx_cleanup; in spi_ppc4xx_of_probe()
371 bbp->master->bits_per_word_mask = SPI_BPW_MASK(8); in spi_ppc4xx_of_probe()
372 bbp->master->use_gpio_descriptors = true; in spi_ppc4xx_of_probe()
377 bbp->master->num_chipselect = 0; in spi_ppc4xx_of_probe()
379 /* the spi->mode bits understood by this driver: */ in spi_ppc4xx_of_probe()
380 bbp->master->mode_bits = in spi_ppc4xx_of_probe()
383 /* Get the clock for the OPB */ in spi_ppc4xx_of_probe()
387 ret = -ENODEV; in spi_ppc4xx_of_probe()
390 /* Get the clock (Hz) for the OPB */ in spi_ppc4xx_of_probe()
391 clk = of_get_property(opbnp, "clock-frequency", NULL); in spi_ppc4xx_of_probe()
393 dev_err(dev, "OPB: no clock-frequency property set\n"); in spi_ppc4xx_of_probe()
395 ret = -ENODEV; in spi_ppc4xx_of_probe()
398 hw->opb_freq = *clk; in spi_ppc4xx_of_probe()
399 hw->opb_freq >>= 2; in spi_ppc4xx_of_probe()
407 hw->mapbase = resource.start; in spi_ppc4xx_of_probe()
408 hw->mapsize = resource_size(&resource); in spi_ppc4xx_of_probe()
411 if (hw->mapsize < sizeof(struct spi_ppc4xx_regs)) { in spi_ppc4xx_of_probe()
413 ret = -EINVAL; in spi_ppc4xx_of_probe()
418 hw->irqnum = irq_of_parse_and_map(np, 0); in spi_ppc4xx_of_probe()
419 ret = request_irq(hw->irqnum, spi_ppc4xx_int, in spi_ppc4xx_of_probe()
426 if (!request_mem_region(hw->mapbase, hw->mapsize, DRIVER_NAME)) { in spi_ppc4xx_of_probe()
428 ret = -EBUSY; in spi_ppc4xx_of_probe()
432 hw->regs = ioremap(hw->mapbase, sizeof(struct spi_ppc4xx_regs)); in spi_ppc4xx_of_probe()
434 if (!hw->regs) { in spi_ppc4xx_of_probe()
436 ret = -ENXIO; in spi_ppc4xx_of_probe()
443 dev->dma_mask = 0; in spi_ppc4xx_of_probe()
446 dev_err(dev, "failed to register SPI master\n"); in spi_ppc4xx_of_probe()
455 iounmap(hw->regs); in spi_ppc4xx_of_probe()
457 release_mem_region(hw->mapbase, hw->mapsize); in spi_ppc4xx_of_probe()
459 free_irq(hw->irqnum, hw); in spi_ppc4xx_of_probe()
461 spi_master_put(master); in spi_ppc4xx_of_probe()
469 struct spi_master *master = platform_get_drvdata(op); in spi_ppc4xx_of_remove() local
470 struct ppc4xx_spi *hw = spi_master_get_devdata(master); in spi_ppc4xx_of_remove()
472 spi_bitbang_stop(&hw->bitbang); in spi_ppc4xx_of_remove()
473 release_mem_region(hw->mapbase, hw->mapsize); in spi_ppc4xx_of_remove()
474 free_irq(hw->irqnum, hw); in spi_ppc4xx_of_remove()
475 iounmap(hw->regs); in spi_ppc4xx_of_remove()
476 spi_master_put(master); in spi_ppc4xx_of_remove()
481 { .compatible = "ibm,ppc4xx-spi", },