Lines Matching +full:done +full:- +full:gpios

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
69 { "qcom,spi-qup-v1.1.1", QCOM_SPI_HW_QPI_V1_1 },
70 { "qcom,spi-qup-v2.1.1", QCOM_SPI_HW_QPI_V2_1 },
71 { "qcom,spi-qup-v2.2.1", QCOM_SPI_HW_QPI_V2_2 },
88 if (sc->cs_pins[cs] == NULL) { in qcom_spi_set_chipsel()
89 device_printf(sc->sc_dev, in qcom_spi_set_chipsel()
112 gpio_pin_set_active(sc->cs_pins[cs], pinactive); in qcom_spi_set_chipsel()
113 gpio_pin_is_active(sc->cs_pins[cs], &pinactive); in qcom_spi_set_chipsel()
128 device_printf(sc->sc_dev, in qcom_spi_intr()
130 goto done; in qcom_spi_intr()
137 if (sc->transfer.active == false) { in qcom_spi_intr()
138 device_printf(sc->sc_dev, in qcom_spi_intr()
141 goto done; in qcom_spi_intr()
145 if (sc->intr.error) { in qcom_spi_intr()
146 sc->intr.error = false; in qcom_spi_intr()
147 device_printf(sc->sc_dev, "ERROR: intr\n"); in qcom_spi_intr()
150 if (sc->intr.do_rx) { in qcom_spi_intr()
151 sc->intr.do_rx = false; in qcom_spi_intr()
154 if (sc->state.transfer_mode == QUP_IO_M_MODE_FIFO) in qcom_spi_intr()
159 device_printf(sc->sc_dev, in qcom_spi_intr()
161 goto done; in qcom_spi_intr()
164 if (sc->intr.do_tx) { in qcom_spi_intr()
165 sc->intr.do_tx = false; in qcom_spi_intr()
175 if (sc->state.transfer_mode == QUP_IO_M_MODE_FIFO) in qcom_spi_intr()
180 device_printf(sc->sc_dev, in qcom_spi_intr()
182 goto done; in qcom_spi_intr()
189 * set the done flag here. in qcom_spi_intr()
191 if (sc->intr.done) { in qcom_spi_intr()
192 sc->intr.done = false; in qcom_spi_intr()
193 sc->transfer.done = true; in qcom_spi_intr()
195 "%s: transfer done\n", __func__); in qcom_spi_intr()
199 done: in qcom_spi_intr()
201 "%s: done\n", __func__); in qcom_spi_intr()
212 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) in qcom_spi_probe()
220 * Allocate GPIOs if provided in the SPI controller block.
225 * and then use GPIOs for the later ones.
231 * And finally, iterating over the cs-gpios list to allocate GPIOs
234 * their properties are (and look for "spi-cs-high".)
243 node = ofw_bus_get_node(sc->sc_dev); in qcom_spi_attach_gpios()
244 for (idx = 0; idx < nitems(sc->cs_pins); idx++) { in qcom_spi_attach_gpios()
245 err = gpio_pin_get_by_ofw_propidx(sc->sc_dev, node, in qcom_spi_attach_gpios()
246 "cs-gpios", idx, &sc->cs_pins[idx]); in qcom_spi_attach_gpios()
248 err = gpio_pin_setflags(sc->cs_pins[idx], in qcom_spi_attach_gpios()
251 device_printf(sc->sc_dev, in qcom_spi_attach_gpios()
262 gpio_pin_set_active(sc->cs_pins[idx], 1); in qcom_spi_attach_gpios()
263 gpio_pin_is_active(sc->cs_pins[idx], &tmp); in qcom_spi_attach_gpios()
266 device_printf(sc->sc_dev, in qcom_spi_attach_gpios()
268 sc->cs_pins[idx] = NULL; in qcom_spi_attach_gpios()
276 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); in qcom_spi_sysctl_attach()
277 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); in qcom_spi_sysctl_attach()
280 "debug", CTLFLAG_RW, &sc->sc_debug, 0, in qcom_spi_sysctl_attach()
290 sc->sc_dev = dev; in qcom_spi_attach()
295 sc->hw_version = in qcom_spi_attach()
296 ofw_bus_search_compatible(dev, compat_data)->ocd_data; in qcom_spi_attach()
298 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); in qcom_spi_attach()
301 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in qcom_spi_attach()
303 if (!sc->sc_mem_res) { in qcom_spi_attach()
310 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in qcom_spi_attach()
312 if (!sc->sc_irq_res) { in qcom_spi_attach()
318 ret = bus_setup_intr(dev, sc->sc_irq_res, in qcom_spi_attach()
320 NULL, qcom_spi_intr, sc, &sc->sc_irq_h); in qcom_spi_attach()
330 ret = clk_get_by_ofw_name(dev, 0, "core", &sc->clk_core); in qcom_spi_attach()
336 ret = clk_get_by_ofw_name(dev, 0, "iface", &sc->clk_iface); in qcom_spi_attach()
344 ret = clk_enable(sc->clk_core); in qcom_spi_attach()
350 ret = clk_enable(sc->clk_iface); in qcom_spi_attach()
358 * Read optional spi-max-frequency in qcom_spi_attach()
360 if (OF_getencprop(ofw_bus_get_node(dev), "spi-max-frequency", in qcom_spi_attach()
362 sc->config.max_frequency = val; in qcom_spi_attach()
364 sc->config.max_frequency = SPI_MAX_RATE; in qcom_spi_attach()
367 * Read optional cs-select in qcom_spi_attach()
369 if (OF_getencprop(ofw_bus_get_node(dev), "cs-select", in qcom_spi_attach()
371 sc->config.cs_select = val; in qcom_spi_attach()
373 sc->config.cs_select = 0; in qcom_spi_attach()
376 * Read optional num-cs in qcom_spi_attach()
378 if (OF_getencprop(ofw_bus_get_node(dev), "num-cs", in qcom_spi_attach()
380 sc->config.num_cs = val; in qcom_spi_attach()
382 sc->config.num_cs = SPI_NUM_CHIPSELECTS; in qcom_spi_attach()
399 sc->config.input_block_size, in qcom_spi_attach()
400 sc->config.output_block_size); in qcom_spi_attach()
402 sc->config.input_fifo_size, in qcom_spi_attach()
403 sc->config.output_fifo_size); in qcom_spi_attach()
423 sc->spibus = device_add_child(dev, "spibus", -1); in qcom_spi_attach()
425 /* We're done, so shut down the interface clock for now */ in qcom_spi_attach()
426 device_printf(dev, "DONE: shutting down interface clock for now\n"); in qcom_spi_attach()
427 clk_disable(sc->clk_iface); in qcom_spi_attach()
435 if (sc->sc_irq_h) in qcom_spi_attach()
436 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_h); in qcom_spi_attach()
437 if (sc->sc_mem_res) in qcom_spi_attach()
438 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in qcom_spi_attach()
439 if (sc->sc_irq_res) in qcom_spi_attach()
440 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); in qcom_spi_attach()
441 if (sc->clk_core) { in qcom_spi_attach()
442 clk_disable(sc->clk_core); in qcom_spi_attach()
443 clk_release(sc->clk_core); in qcom_spi_attach()
445 if (sc->clk_iface) { in qcom_spi_attach()
446 clk_disable(sc->clk_iface); in qcom_spi_attach()
447 clk_release(sc->clk_iface); in qcom_spi_attach()
450 if (sc->cs_pins[i] != NULL) in qcom_spi_attach()
451 gpio_pin_release(sc->cs_pins[i]); in qcom_spi_attach()
453 mtx_destroy(&sc->sc_mtx); in qcom_spi_attach()
462 * size. The QUP hardware supports doing multi-phase transactions
464 * not yet being done here.
476 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
489 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
496 sc->transfer.tx_buf = tx_buf; in qcom_spi_transfer_pio_block()
497 sc->transfer.tx_len = tx_len; in qcom_spi_transfer_pio_block()
498 sc->transfer.rx_buf = rx_buf; in qcom_spi_transfer_pio_block()
499 sc->transfer.rx_len = rx_len; in qcom_spi_transfer_pio_block()
500 sc->transfer.done = false; in qcom_spi_transfer_pio_block()
501 sc->transfer.active = false; in qcom_spi_transfer_pio_block()
504 * Loop until the full transfer set is done. in qcom_spi_transfer_pio_block()
510 while (sc->transfer.tx_offset < sc->transfer.tx_len) { in qcom_spi_transfer_pio_block()
513 * it also finishing a sub-transfer and we're in qcom_spi_transfer_pio_block()
517 sc->transfer.active = false; in qcom_spi_transfer_pio_block()
522 sc->transfer.tx_offset, sc->transfer.tx_len, in qcom_spi_transfer_pio_block()
523 sc->transfer.rx_offset, sc->transfer.rx_len); in qcom_spi_transfer_pio_block()
528 * Otherwise the second sub-transfer that we queue up in qcom_spi_transfer_pio_block()
534 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
536 goto done; in qcom_spi_transfer_pio_block()
539 bzero(&sc->intr, sizeof(sc->intr)); in qcom_spi_transfer_pio_block()
540 sc->transfer.done = false; in qcom_spi_transfer_pio_block()
544 * sub-transfer will be. in qcom_spi_transfer_pio_block()
548 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
551 goto done; in qcom_spi_transfer_pio_block()
560 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
563 goto done; in qcom_spi_transfer_pio_block()
572 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
575 goto done; in qcom_spi_transfer_pio_block()
581 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
584 goto done; in qcom_spi_transfer_pio_block()
590 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
593 goto done; in qcom_spi_transfer_pio_block()
596 ret = qcom_spi_hw_setup_spi_config(sc, sc->state.frequency, in qcom_spi_transfer_pio_block()
599 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
602 goto done; in qcom_spi_transfer_pio_block()
608 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
611 goto done; in qcom_spi_transfer_pio_block()
616 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
619 goto done; in qcom_spi_transfer_pio_block()
623 * Setup is done; reset the controller and start the PIO in qcom_spi_transfer_pio_block()
631 sc->transfer.active = true; in qcom_spi_transfer_pio_block()
634 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
636 goto done; in qcom_spi_transfer_pio_block()
644 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
646 goto done; in qcom_spi_transfer_pio_block()
654 if (sc->state.transfer_mode == QUP_IO_M_MODE_FIFO) in qcom_spi_transfer_pio_block()
659 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
661 goto done; in qcom_spi_transfer_pio_block()
669 device_printf(sc->sc_dev, in qcom_spi_transfer_pio_block()
671 goto done; in qcom_spi_transfer_pio_block()
677 * sub-transfer) or timeout. in qcom_spi_transfer_pio_block()
680 while (ret == 0 && sc->transfer.done == false) { in qcom_spi_transfer_pio_block()
683 ret = msleep(sc, &sc->sc_mtx, 0, "qcom_spi", 0); in qcom_spi_transfer_pio_block()
686 done: in qcom_spi_transfer_pio_block()
702 sc->transfer.active = false; in qcom_spi_transfer_pio_block()
725 cmd->tx_cmd_sz, cmd->rx_cmd_sz, in qcom_spi_transfer()
726 cmd->tx_data_sz, cmd->rx_data_sz); in qcom_spi_transfer()
733 while (sc->sc_busy == true) in qcom_spi_transfer()
734 mtx_sleep(sc, &sc->sc_mtx, 0, "qcom_spi_wait", 0); in qcom_spi_transfer()
739 sc->sc_busy = true; in qcom_spi_transfer()
741 sc->state.cs_high = !! (cs_val & SPIBUS_CS_HIGH); in qcom_spi_transfer()
742 sc->state.frequency = clock_val; in qcom_spi_transfer()
746 * with the driver lock held, as the SPI lock is non-sleepable in qcom_spi_transfer()
757 ret = clk_set_freq(sc->clk_iface, sc->state.frequency, 0); in qcom_spi_transfer()
759 device_printf(sc->sc_dev, in qcom_spi_transfer()
761 sc->state.frequency); in qcom_spi_transfer()
764 clk_enable(sc->clk_iface); in qcom_spi_transfer()
773 device_printf(sc->sc_dev, in qcom_spi_transfer()
775 goto done; in qcom_spi_transfer()
779 if (sc->cs_pins[cs_val & ~SPIBUS_CS_HIGH] == NULL) in qcom_spi_transfer()
787 ret = qcom_spi_transfer_pio_block(sc, mode_val, cmd->tx_cmd, in qcom_spi_transfer()
788 cmd->tx_cmd_sz, cmd->rx_cmd, cmd->rx_cmd_sz); in qcom_spi_transfer()
790 device_printf(sc->sc_dev, in qcom_spi_transfer()
792 goto done; in qcom_spi_transfer()
798 if (cmd->tx_data_sz > 0) { in qcom_spi_transfer()
799 ret = qcom_spi_transfer_pio_block(sc, mode_val, cmd->tx_data, in qcom_spi_transfer()
800 cmd->tx_data_sz, cmd->rx_data, cmd->rx_data_sz); in qcom_spi_transfer()
802 device_printf(sc->sc_dev, in qcom_spi_transfer()
805 goto done; in qcom_spi_transfer()
809 done: in qcom_spi_transfer()
810 /* De-assert GPIO/CS */ in qcom_spi_transfer()
811 if (sc->cs_pins[cs_val & ~SPIBUS_CS_HIGH] == NULL) in qcom_spi_transfer()
818 * across a clk API as that's a sleep lock and we're non-sleepable. in qcom_spi_transfer()
823 clk_disable(sc->clk_iface); in qcom_spi_transfer()
827 * We're done; so mark the bus as not busy and wakeup in qcom_spi_transfer()
830 sc->sc_busy = false; in qcom_spi_transfer()
842 bus_generic_detach(sc->sc_dev); in qcom_spi_detach()
844 if (sc->sc_irq_h) in qcom_spi_detach()
845 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_h); in qcom_spi_detach()
847 if (sc->clk_iface) { in qcom_spi_detach()
848 clk_disable(sc->clk_iface); in qcom_spi_detach()
849 clk_release(sc->clk_iface); in qcom_spi_detach()
851 if (sc->clk_core) { in qcom_spi_detach()
852 clk_disable(sc->clk_core); in qcom_spi_detach()
853 clk_release(sc->clk_core); in qcom_spi_detach()
857 if (sc->cs_pins[i] != NULL) in qcom_spi_detach()
858 gpio_pin_release(sc->cs_pins[i]); in qcom_spi_detach()
861 if (sc->sc_mem_res) in qcom_spi_detach()
862 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in qcom_spi_detach()
863 if (sc->sc_irq_res) in qcom_spi_detach()
864 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); in qcom_spi_detach()
866 mtx_destroy(&sc->sc_mtx); in qcom_spi_detach()