1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2010 ASIX Electronics Corporation 4 * Copyright (c) 2020 Samsung Electronics Co., Ltd. 5 * 6 * ASIX AX88796C SPI Fast Ethernet Linux driver 7 */ 8 9 #define pr_fmt(fmt) "ax88796c: " fmt 10 11 #include <linux/string.h> 12 #include <linux/spi/spi.h> 13 14 #include "ax88796c_spi.h" 15 16 const u8 ax88796c_rx_cmd_buf[5] = {AX_SPICMD_READ_RXQ, 0xFF, 0xFF, 0xFF, 0xFF}; 17 const u8 ax88796c_tx_cmd_buf[4] = {AX_SPICMD_WRITE_TXQ, 0xFF, 0xFF, 0xFF}; 18 19 /* driver bus management functions */ 20 int axspi_wakeup(struct axspi_data *ax_spi) 21 { 22 int ret; 23 24 ax_spi->cmd_buf[0] = AX_SPICMD_EXIT_PWD; /* OP */ 25 ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 1); 26 if (ret) 27 dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 28 return ret; 29 } 30 31 int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status) 32 { 33 int ret; 34 35 /* OP */ 36 ax_spi->cmd_buf[0] = AX_SPICMD_READ_STATUS; 37 ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)&status, 3); 38 if (ret) 39 dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 40 else 41 le16_to_cpus(&status->isr); 42 43 return ret; 44 } 45 46 int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len) 47 { 48 struct spi_transfer *xfer = ax_spi->spi_rx_xfer; 49 int ret; 50 51 memcpy(ax_spi->cmd_buf, ax88796c_rx_cmd_buf, 5); 52 53 xfer->tx_buf = ax_spi->cmd_buf; 54 xfer->rx_buf = NULL; 55 xfer->len = ax_spi->comp ? 2 : 5; 56 xfer->bits_per_word = 8; 57 spi_message_add_tail(xfer, &ax_spi->rx_msg); 58 59 xfer++; 60 xfer->rx_buf = data; 61 xfer->tx_buf = NULL; 62 xfer->len = len; 63 xfer->bits_per_word = 8; 64 spi_message_add_tail(xfer, &ax_spi->rx_msg); 65 ret = spi_sync(ax_spi->spi, &ax_spi->rx_msg); 66 if (ret) 67 dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 68 69 return ret; 70 } 71 72 int axspi_write_txq(const struct axspi_data *ax_spi, void *data, int len) 73 { 74 return spi_write(ax_spi->spi, data, len); 75 } 76 77 u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg) 78 { 79 int ret; 80 int len = ax_spi->comp ? 3 : 4; 81 82 ax_spi->cmd_buf[0] = 0x03; /* OP code read register */ 83 ax_spi->cmd_buf[1] = reg; /* register address */ 84 ax_spi->cmd_buf[2] = 0xFF; /* dumy cycle */ 85 ax_spi->cmd_buf[3] = 0xFF; /* dumy cycle */ 86 ret = spi_write_then_read(ax_spi->spi, 87 ax_spi->cmd_buf, len, 88 ax_spi->rx_buf, 2); 89 if (ret) { 90 dev_err(&ax_spi->spi->dev, 91 "%s() failed: ret = %d\n", __func__, ret); 92 return 0xFFFF; 93 } 94 95 le16_to_cpus((u16 *)ax_spi->rx_buf); 96 97 return *(u16 *)ax_spi->rx_buf; 98 } 99 100 int axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value) 101 { 102 int ret; 103 104 memset(ax_spi->cmd_buf, 0, sizeof(ax_spi->cmd_buf)); 105 ax_spi->cmd_buf[0] = AX_SPICMD_WRITE_REG; /* OP code read register */ 106 ax_spi->cmd_buf[1] = reg; /* register address */ 107 ax_spi->cmd_buf[2] = value; 108 ax_spi->cmd_buf[3] = value >> 8; 109 110 ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 4); 111 if (ret) 112 dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret); 113 return ret; 114 } 115 116