Lines Matching +full:spi +full:- +full:fsi
1 // SPDX-License-Identifier: GPL-2.0-or-later
6 #include <linux/fsi.h>
11 #include <linux/spi/spi.h>
71 struct fsi_device *fsi; /* FSI2SPI CFAM engine device */ member
76 struct device *dev; /* SPI controller device */
86 static int fsi_spi_check_mux(struct fsi_device *fsi, struct device *dev) in fsi_spi_check_mux() argument
92 rc = fsi_slave_read(fsi->slave, FSI_MBOX_ROOT_CTRL_8, &root_ctrl_8_be, in fsi_spi_check_mux()
103 return -ENOLINK; in fsi_spi_check_mux()
112 rc = fsi_device_read(ctx->bridge->fsi, FSI2SPI_STATUS, &sts_be, in fsi_spi_check_status()
119 dev_err(ctx->dev, "Error with FSI2SPI interface: %08x.\n", sts); in fsi_spi_check_status()
120 return -EIO; in fsi_spi_check_status()
131 u32 cmd = offset + ctx->base; in fsi_spi_read_reg()
132 struct fsi2spi *bridge = ctx->bridge; in fsi_spi_read_reg()
137 return -EINVAL; in fsi_spi_read_reg()
139 rc = mutex_lock_interruptible(&bridge->lock); in fsi_spi_read_reg()
144 rc = fsi_device_write(bridge->fsi, FSI2SPI_CMD, &cmd_be, in fsi_spi_read_reg()
153 rc = fsi_device_read(bridge->fsi, FSI2SPI_DATA0, &data_be, in fsi_spi_read_reg()
160 rc = fsi_device_read(bridge->fsi, FSI2SPI_DATA1, &data_be, in fsi_spi_read_reg()
166 dev_dbg(ctx->dev, "Read %02x[%016llx].\n", offset, *value); in fsi_spi_read_reg()
169 mutex_unlock(&bridge->lock); in fsi_spi_read_reg()
178 u32 cmd = offset + ctx->base; in fsi_spi_write_reg()
179 struct fsi2spi *bridge = ctx->bridge; in fsi_spi_write_reg()
182 return -EINVAL; in fsi_spi_write_reg()
184 rc = mutex_lock_interruptible(&bridge->lock); in fsi_spi_write_reg()
188 dev_dbg(ctx->dev, "Write %02x[%016llx].\n", offset, value); in fsi_spi_write_reg()
191 rc = fsi_device_write(bridge->fsi, FSI2SPI_DATA0, &data_be, in fsi_spi_write_reg()
197 rc = fsi_device_write(bridge->fsi, FSI2SPI_DATA1, &data_be, in fsi_spi_write_reg()
203 rc = fsi_device_write(bridge->fsi, FSI2SPI_CMD, &cmd_be, in fsi_spi_write_reg()
211 mutex_unlock(&bridge->lock); in fsi_spi_write_reg()
221 rx[i] = (u8)(in >> (8 * ((num_bytes - 1) - i))); in fsi_spi_data_in()
236 out_bytes[8 - (i + 1)] = tx[i]; in fsi_spi_data_out()
245 dev_dbg(ctx->dev, "Resetting SPI controller.\n"); in fsi_spi_reset()
268 dev_err(ctx->dev, "%s error: %016llx\n", dir, *status); in fsi_spi_status()
274 return -EREMOTEIO; in fsi_spi_status()
283 * Add the next byte of instruction to the 8-byte sequence register. in fsi_spi_sequence_add()
288 seq->data |= (u64)val << seq->bit; in fsi_spi_sequence_add()
289 seq->bit -= 8; in fsi_spi_sequence_add()
294 seq->bit = 56; in fsi_spi_sequence_init()
295 seq->data = 0ULL; in fsi_spi_sequence_init()
306 if (transfer->tx_buf) { in fsi_spi_transfer_data()
310 const u8 *tx = transfer->tx_buf; in fsi_spi_transfer_data()
312 while (transfer->len > sent) { in fsi_spi_transfer_data()
314 (int)transfer->len - sent); in fsi_spi_transfer_data()
324 return -ETIMEDOUT; in fsi_spi_transfer_data()
333 } else if (transfer->rx_buf) { in fsi_spi_transfer_data()
336 u8 *rx = transfer->rx_buf; in fsi_spi_transfer_data()
338 while (transfer->len > recv) { in fsi_spi_transfer_data()
343 return -ETIMEDOUT; in fsi_spi_transfer_data()
355 (int)transfer->len - recv); in fsi_spi_transfer_data()
378 return -ETIMEDOUT; in fsi_spi_transfer_init()
390 dev_err(ctx->dev, in fsi_spi_transfer_init()
393 return -EIO; in fsi_spi_transfer_init()
428 u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(spi_get_chipselect(mesg->spi, 0) + 1); in fsi_spi_transfer_one_message()
433 rc = fsi_spi_check_mux(ctx->bridge->fsi, ctx->dev); in fsi_spi_transfer_one_message()
437 list_for_each_entry(transfer, &mesg->transfers, transfer_list) { in fsi_spi_transfer_one_message()
442 if (!transfer->tx_buf || transfer->len > SPI_FSI_MAX_TX_SIZE) { in fsi_spi_transfer_one_message()
443 rc = -EINVAL; in fsi_spi_transfer_one_message()
447 dev_dbg(ctx->dev, "Start tx of %d bytes.\n", transfer->len); in fsi_spi_transfer_one_message()
456 len = transfer->len; in fsi_spi_transfer_one_message()
460 len -= 8; in fsi_spi_transfer_one_message()
464 if (!list_is_last(&transfer->transfer_list, in fsi_spi_transfer_one_message()
465 &mesg->transfers)) { in fsi_spi_transfer_one_message()
469 if (next->rx_buf) { in fsi_spi_transfer_one_message()
472 if (next->len > SPI_FSI_MAX_RX_SIZE) { in fsi_spi_transfer_one_message()
473 rc = -EINVAL; in fsi_spi_transfer_one_message()
477 dev_dbg(ctx->dev, "Sequence rx of %d bytes.\n", in fsi_spi_transfer_one_message()
478 next->len); in fsi_spi_transfer_one_message()
480 shift = SPI_FSI_SEQUENCE_SHIFT_IN(next->len); in fsi_spi_transfer_one_message()
507 mesg->status = rc; in fsi_spi_transfer_one_message()
513 static size_t fsi_spi_max_transfer_size(struct spi_device *spi) in fsi_spi_max_transfer_size() argument
524 struct fsi_device *fsi = to_fsi_dev(dev); in fsi_spi_probe() local
526 rc = fsi_spi_check_mux(fsi, dev); in fsi_spi_probe()
528 return -ENODEV; in fsi_spi_probe()
532 return -ENOMEM; in fsi_spi_probe()
534 bridge->fsi = fsi; in fsi_spi_probe()
535 mutex_init(&bridge->lock); in fsi_spi_probe()
537 for_each_available_child_of_node(dev->of_node, np) { in fsi_spi_probe()
551 ctlr->dev.of_node = np; in fsi_spi_probe()
552 ctlr->num_chipselect = of_get_available_child_count(np) ?: 1; in fsi_spi_probe()
553 ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX; in fsi_spi_probe()
554 ctlr->max_transfer_size = fsi_spi_max_transfer_size; in fsi_spi_probe()
555 ctlr->transfer_one_message = fsi_spi_transfer_one_message; in fsi_spi_probe()
558 ctx->dev = &ctlr->dev; in fsi_spi_probe()
559 ctx->bridge = bridge; in fsi_spi_probe()
560 ctx->base = base + SPI_FSI_BASE; in fsi_spi_probe()
570 return -ENODEV; in fsi_spi_probe()
579 MODULE_DEVICE_TABLE(fsi, fsi_spi_ids);
584 .name = "spi-fsi",
592 MODULE_DESCRIPTION("FSI attached SPI controller");