0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/kernel.h>
0027 #include <linux/netdevice.h>
0028 #include <linux/spi/spi.h>
0029
0030 #include "qca_7k.h"
0031
0032 void
0033 qcaspi_spi_error(struct qcaspi *qca)
0034 {
0035 if (qca->sync != QCASPI_SYNC_READY)
0036 return;
0037
0038 netdev_err(qca->net_dev, "spi error\n");
0039 qca->sync = QCASPI_SYNC_UNKNOWN;
0040 qca->stats.spi_err++;
0041 }
0042
0043 int
0044 qcaspi_read_register(struct qcaspi *qca, u16 reg, u16 *result)
0045 {
0046 __be16 rx_data;
0047 __be16 tx_data;
0048 struct spi_transfer transfer[2];
0049 struct spi_message msg;
0050 int ret;
0051
0052 memset(transfer, 0, sizeof(transfer));
0053
0054 spi_message_init(&msg);
0055
0056 tx_data = cpu_to_be16(QCA7K_SPI_READ | QCA7K_SPI_INTERNAL | reg);
0057 *result = 0;
0058
0059 transfer[0].tx_buf = &tx_data;
0060 transfer[0].len = QCASPI_CMD_LEN;
0061 transfer[1].rx_buf = &rx_data;
0062 transfer[1].len = QCASPI_CMD_LEN;
0063
0064 spi_message_add_tail(&transfer[0], &msg);
0065
0066 if (qca->legacy_mode) {
0067 spi_sync(qca->spi_dev, &msg);
0068 spi_message_init(&msg);
0069 }
0070 spi_message_add_tail(&transfer[1], &msg);
0071 ret = spi_sync(qca->spi_dev, &msg);
0072
0073 if (!ret)
0074 ret = msg.status;
0075
0076 if (ret)
0077 qcaspi_spi_error(qca);
0078 else
0079 *result = be16_to_cpu(rx_data);
0080
0081 return ret;
0082 }
0083
0084 static int
0085 __qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value)
0086 {
0087 __be16 tx_data[2];
0088 struct spi_transfer transfer[2];
0089 struct spi_message msg;
0090 int ret;
0091
0092 memset(&transfer, 0, sizeof(transfer));
0093
0094 spi_message_init(&msg);
0095
0096 tx_data[0] = cpu_to_be16(QCA7K_SPI_WRITE | QCA7K_SPI_INTERNAL | reg);
0097 tx_data[1] = cpu_to_be16(value);
0098
0099 transfer[0].tx_buf = &tx_data[0];
0100 transfer[0].len = QCASPI_CMD_LEN;
0101 transfer[1].tx_buf = &tx_data[1];
0102 transfer[1].len = QCASPI_CMD_LEN;
0103
0104 spi_message_add_tail(&transfer[0], &msg);
0105 if (qca->legacy_mode) {
0106 spi_sync(qca->spi_dev, &msg);
0107 spi_message_init(&msg);
0108 }
0109 spi_message_add_tail(&transfer[1], &msg);
0110 ret = spi_sync(qca->spi_dev, &msg);
0111
0112 if (!ret)
0113 ret = msg.status;
0114
0115 if (ret)
0116 qcaspi_spi_error(qca);
0117
0118 return ret;
0119 }
0120
0121 int
0122 qcaspi_write_register(struct qcaspi *qca, u16 reg, u16 value, int retry)
0123 {
0124 int ret, i = 0;
0125 u16 confirmed;
0126
0127 do {
0128 ret = __qcaspi_write_register(qca, reg, value);
0129 if (ret)
0130 return ret;
0131
0132 if (!retry)
0133 return 0;
0134
0135 ret = qcaspi_read_register(qca, reg, &confirmed);
0136 if (ret)
0137 return ret;
0138
0139 ret = confirmed != value;
0140 if (!ret)
0141 return 0;
0142
0143 i++;
0144 qca->stats.write_verify_failed++;
0145
0146 } while (i <= retry);
0147
0148 return ret;
0149 }