1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
3 * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
4 * Copyright (c) 2014, I2SE GmbH
7 /* This module implements the Qualcomm Atheros SPI protocol for
8 * kernel-based SPI device.
11 #include <linux/kernel.h>
12 #include <linux/netdevice.h>
13 #include <linux/spi/spi.h>
18 qcaspi_spi_error(struct qcaspi *qca)
20 if (qca->sync != QCASPI_SYNC_READY)
23 netdev_err(qca->net_dev, "spi error\n");
24 qca->sync = QCASPI_SYNC_UNKNOWN;
29 qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result)
33 struct spi_transfer transfer[2];
34 struct spi_message msg;
37 memset(transfer, 0, sizeof(transfer));
39 spi_message_init(&msg);
41 tx_data = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_INTERNAL | reg);
44 transfer[0].tx_buf = &tx_data;
45 transfer[0].len = QCASPI_CMD_LEN;
46 transfer[1].rx_buf = &rx_data;
47 transfer[1].len = QCASPI_CMD_LEN;
49 spi_message_add_tail(&transfer[0], &msg);
51 if (qca->legacy_mode) {
52 spi_sync(qca->spi_dev, &msg);
53 spi_message_init(&msg);
55 spi_message_add_tail(&transfer[1], &msg);
56 ret = spi_sync(qca->spi_dev, &msg);
62 qcaspi_spi_error(qca);
64 *result = be16_to_cpu(rx_data);
70 __qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value)
73 struct spi_transfer transfer[2];
74 struct spi_message msg;
77 memset(&transfer, 0, sizeof(transfer));
79 spi_message_init(&msg);
81 tx_data[0] = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_INTERNAL | reg);
82 tx_data[1] = cpu_to_be16(value);
84 transfer[0].tx_buf = &tx_data[0];
85 transfer[0].len = QCASPI_CMD_LEN;
86 transfer[1].tx_buf = &tx_data[1];
87 transfer[1].len = QCASPI_CMD_LEN;
89 spi_message_add_tail(&transfer[0], &msg);
90 if (qca->legacy_mode) {
91 spi_sync(qca->spi_dev, &msg);
92 spi_message_init(&msg);
94 spi_message_add_tail(&transfer[1], &msg);
95 ret = spi_sync(qca->spi_dev, &msg);
101 qcaspi_spi_error(qca);
107 qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value, int retry)
113 ret = __qcaspi_write_register(qca, reg, value);
120 ret = qcaspi_read_register(qca, reg, &confirmed);
124 ret = confirmed != value;
129 qca->stats.write_verify_failed++;
131 } while (i <= retry);