Lines Matching +full:cs +full:- +full:x
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
31 * Driver for imx Enhanced Configurable SPI; master-mode only.
143 {"fsl,imx51-ecspi", true},
144 {"fsl,imx53-ecspi", true},
145 {"fsl,imx6dl-ecspi", true},
146 {"fsl,imx6q-ecspi", true},
147 {"fsl,imx6sx-ecspi", true},
148 {"fsl,imx6ul-ecspi", true},
156 return (bus_read_4(sc->memres, offset));
163 bus_write_4(sc->memres, offset, value);
172 if (sc->basefreq <= busfreq)
176 * Brute-force this; all real-world bus speeds are going to be found on
180 pre = ((sc->basefreq >> post) / busfreq) - 1;
190 if (sc->debug >= 2) {
191 device_printf(sc->dev,
193 sc->basefreq, busfreq, pre, post,
194 (sc->basefreq / (pre + 1)) / (1 << post));
201 spi_set_chipsel(struct spi_softc *sc, u_int cs, bool active)
207 * active-high in the dts, but are supposed to be treated as active-low
210 * slave can say its chipsel is active-high, so if that option is
213 pinactive = !active ^ (bool)(cs & SPIBUS_CS_HIGH);
215 if (sc->debug >= 2) {
216 device_printf(sc->dev, "chipsel %u changed to %u\n",
217 (cs & ~SPIBUS_CS_HIGH), pinactive);
224 gpio_pin_set_active(sc->cspins[cs & ~SPIBUS_CS_HIGH], pinactive);
225 gpio_pin_is_active(sc->cspins[cs & ~SPIBUS_CS_HIGH], &pinactive);
229 spi_hw_setup(struct spi_softc *sc, u_int cs, u_int mode, u_int freq)
237 sc->ctlreg = CTLREG_EN | CTLREG_CMODES_MASTER | CTLREG_SMC;
238 sc->ctlreg |= spi_calc_clockdiv(sc, freq);
239 sc->ctlreg |= 7 << CTLREG_BLEN_SHIFT; /* XXX byte at a time */
240 WR4(sc, ECSPI_CTLREG, sc->ctlreg);
244 * SPI hardware's chip-select set to zero. The actual chip select is
248 if (cs & SPIBUS_CS_HIGH)
276 while (sc->rxidx < sc->rxlen && (RD4(sc, ECSPI_STATREG) & SREG_RR)) {
277 sc->rxbuf[sc->rxidx++] = (uint8_t)RD4(sc, ECSPI_RXDATA);
278 --sc->fifocnt;
286 while (sc->txidx < sc->txlen && sc->fifocnt < FIFO_SIZE) {
287 WR4(sc, ECSPI_TXDATA, sc->txbuf[sc->txidx++]);
288 ++sc->fifocnt;
295 if (sc->txidx == sc->txlen)
296 sc->intreg = (sc->intreg & ~INTREG_TDREN) | INTREG_TEEN;
305 mtx_lock(&sc->mtx);
308 intreg = sc->intreg;
318 if (sc->debug || bootverbose) {
319 device_printf(sc->dev, "rxoverflow rxidx %u txidx %u\n",
320 sc->rxidx, sc->txidx);
322 sc->intreg = 0;
324 mtx_unlock(&sc->mtx);
336 * - If Transfer Complete is set (shift register is empty) and we've
338 * - Else if Tx Fifo Empty is set, we need to stop waiting for that and
342 if (sc->txidx == sc->txlen) {
343 if ((status & SREG_TC) && sc->fifocnt == 0) {
344 sc->intreg = 0;
347 sc->intreg &= ~(sc->intreg & ~INTREG_TEEN);
348 sc->intreg |= INTREG_TCEN | INTREG_RREN;
357 if (sc->intreg != intreg) {
358 WR4(sc, ECSPI_INTREG, sc->intreg);
362 if (sc->debug >= 3) {
363 device_printf(sc->dev,
364 "spi_intr, sreg 0x%08x intreg was 0x%08x now 0x%08x\n",
365 status, intreg, sc->intreg);
368 mtx_unlock(&sc->mtx);
376 if (sc->debug >= 1) {
377 device_printf(sc->dev,
385 sc->rxbuf = rxbuf;
386 sc->rxlen = len;
387 sc->rxidx = 0;
388 sc->txbuf = txbuf;
389 sc->txlen = len;
390 sc->txidx = 0;
391 sc->intreg = INTREG_RDREN | INTREG_TDREN;
394 /* Enable interrupts last; spi_fill_txfifo() can change sc->intreg */
395 WR4(sc, ECSPI_INTREG, sc->intreg);
398 while (err == 0 && sc->intreg != 0)
399 err = msleep(sc, &sc->mtx, 0, "imxspi", 10 * hz);
401 if (sc->rxidx != sc->rxlen || sc->txidx != sc->txlen)
411 uint32_t cs, mode, clock;
414 spibus_get_cs(child, &cs);
418 if (cs > CS_MAX || sc->cspins[cs] == NULL) {
419 if (sc->debug || bootverbose)
420 device_printf(sc->dev, "Invalid chip select %u\n", cs);
424 mtx_lock(&sc->mtx);
425 device_busy(sc->dev);
427 if (sc->debug >= 1) {
428 device_printf(sc->dev,
429 "spi_transfer, cs 0x%x clock %u mode %u\n",
430 cs, clock, mode);
434 spi_hw_setup(sc, cs, mode, clock);
435 spi_set_chipsel(sc, cs, true);
439 if (cmd->tx_cmd_sz > 0)
440 err = spi_xfer_buf(sc, cmd->rx_cmd, cmd->tx_cmd,
441 cmd->tx_cmd_sz);
442 if (cmd->tx_data_sz > 0 && err == 0)
443 err = spi_xfer_buf(sc, cmd->rx_data, cmd->tx_data,
444 cmd->tx_data_sz);
447 spi_set_chipsel(sc, cs, false);
450 device_unbusy(sc->dev);
451 mtx_unlock(&sc->mtx);
473 if ((error = bus_generic_detach(sc->dev)) != 0)
476 for (idx = 0; idx < nitems(sc->cspins); ++idx) {
477 if (sc->cspins[idx] != NULL)
478 gpio_pin_release(sc->cspins[idx]);
481 if (sc->inthandle != NULL)
482 bus_teardown_intr(sc->dev, sc->intres, sc->inthandle);
483 if (sc->intres != NULL)
484 bus_release_resource(sc->dev, SYS_RES_IRQ, 0, sc->intres);
485 if (sc->memres != NULL)
486 bus_release_resource(sc->dev, SYS_RES_MEMORY, 0, sc->memres);
488 mtx_destroy(&sc->mtx);
500 sc->dev = dev;
501 sc->basefreq = imx_ccm_ecspi_hz();
503 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
505 /* Set up debug-enable sysctl. */
506 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
507 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
508 OID_AUTO, "debug", CTLFLAG_RWTUN, &sc->debug, 0,
513 sc->memres = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &rid,
515 if (sc->memres == NULL) {
516 device_printf(sc->dev, "could not allocate registers\n");
517 spi_detach(sc->dev);
523 sc->intres = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &rid,
525 if (sc->intres == NULL) {
526 device_printf(sc->dev, "could not allocate interrupt\n");
527 device_detach(sc->dev);
530 err = bus_setup_intr(sc->dev, sc->intres, INTR_TYPE_MISC | INTR_MPSAFE,
531 NULL, spi_intr, sc, &sc->inthandle);
533 device_printf(sc->dev, "could not setup interrupt handler");
534 device_detach(sc->dev);
539 node = ofw_bus_get_node(sc->dev);
540 for (idx = 0; idx < nitems(sc->cspins); ++idx) {
541 err = gpio_pin_get_by_ofw_propidx(sc->dev, node, "cs-gpios",
542 idx, &sc->cspins[idx]);
544 gpio_pin_setflags(sc->cspins[idx], GPIO_PIN_OUTPUT);
545 } else if (sc->debug >= 2) {
546 device_printf(sc->dev,
558 * Add the spibus driver as a child, and setup a one-shot intrhook to
563 sc->spibus = device_add_child(dev, "spibus", DEVICE_UNIT_ANY);
575 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)