Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2010 ASIX Electronics Corporation
0004  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
0005  *
0006  * ASIX AX88796C SPI Fast Ethernet Linux driver
0007  */
0008 
0009 #define pr_fmt(fmt) "ax88796c: " fmt
0010 
0011 #include <linux/string.h>
0012 #include <linux/spi/spi.h>
0013 
0014 #include "ax88796c_spi.h"
0015 
0016 const u8 ax88796c_rx_cmd_buf[5] = {AX_SPICMD_READ_RXQ, 0xFF, 0xFF, 0xFF, 0xFF};
0017 const u8 ax88796c_tx_cmd_buf[4] = {AX_SPICMD_WRITE_TXQ, 0xFF, 0xFF, 0xFF};
0018 
0019 /* driver bus management functions */
0020 int axspi_wakeup(struct axspi_data *ax_spi)
0021 {
0022     int ret;
0023 
0024     ax_spi->cmd_buf[0] = AX_SPICMD_EXIT_PWD;    /* OP */
0025     ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 1);
0026     if (ret)
0027         dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
0028     return ret;
0029 }
0030 
0031 int axspi_read_status(struct axspi_data *ax_spi, struct spi_status *status)
0032 {
0033     int ret;
0034 
0035     /* OP */
0036     ax_spi->cmd_buf[0] = AX_SPICMD_READ_STATUS;
0037     ret = spi_write_then_read(ax_spi->spi, ax_spi->cmd_buf, 1, (u8 *)status, 3);
0038     if (ret)
0039         dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
0040     else
0041         le16_to_cpus(&status->isr);
0042 
0043     return ret;
0044 }
0045 
0046 int axspi_read_rxq(struct axspi_data *ax_spi, void *data, int len)
0047 {
0048     struct spi_transfer *xfer = ax_spi->spi_rx_xfer;
0049     int ret;
0050 
0051     memcpy(ax_spi->cmd_buf, ax88796c_rx_cmd_buf, 5);
0052 
0053     xfer->tx_buf = ax_spi->cmd_buf;
0054     xfer->rx_buf = NULL;
0055     xfer->len = ax_spi->comp ? 2 : 5;
0056     xfer->bits_per_word = 8;
0057     spi_message_add_tail(xfer, &ax_spi->rx_msg);
0058 
0059     xfer++;
0060     xfer->rx_buf = data;
0061     xfer->tx_buf = NULL;
0062     xfer->len = len;
0063     xfer->bits_per_word = 8;
0064     spi_message_add_tail(xfer, &ax_spi->rx_msg);
0065     ret = spi_sync(ax_spi->spi, &ax_spi->rx_msg);
0066     if (ret)
0067         dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
0068 
0069     return ret;
0070 }
0071 
0072 int axspi_write_txq(const struct axspi_data *ax_spi, void *data, int len)
0073 {
0074     return spi_write(ax_spi->spi, data, len);
0075 }
0076 
0077 u16 axspi_read_reg(struct axspi_data *ax_spi, u8 reg)
0078 {
0079     int ret;
0080     int len = ax_spi->comp ? 3 : 4;
0081 
0082     ax_spi->cmd_buf[0] = 0x03;  /* OP code read register */
0083     ax_spi->cmd_buf[1] = reg;   /* register address */
0084     ax_spi->cmd_buf[2] = 0xFF;  /* dumy cycle */
0085     ax_spi->cmd_buf[3] = 0xFF;  /* dumy cycle */
0086     ret = spi_write_then_read(ax_spi->spi,
0087                   ax_spi->cmd_buf, len,
0088                   ax_spi->rx_buf, 2);
0089     if (ret) {
0090         dev_err(&ax_spi->spi->dev,
0091             "%s() failed: ret = %d\n", __func__, ret);
0092         return 0xFFFF;
0093     }
0094 
0095     le16_to_cpus((u16 *)ax_spi->rx_buf);
0096 
0097     return *(u16 *)ax_spi->rx_buf;
0098 }
0099 
0100 int axspi_write_reg(struct axspi_data *ax_spi, u8 reg, u16 value)
0101 {
0102     int ret;
0103 
0104     memset(ax_spi->cmd_buf, 0, sizeof(ax_spi->cmd_buf));
0105     ax_spi->cmd_buf[0] = AX_SPICMD_WRITE_REG;   /* OP code read register */
0106     ax_spi->cmd_buf[1] = reg;           /* register address */
0107     ax_spi->cmd_buf[2] = value;
0108     ax_spi->cmd_buf[3] = value >> 8;
0109 
0110     ret = spi_write(ax_spi->spi, ax_spi->cmd_buf, 4);
0111     if (ret)
0112         dev_err(&ax_spi->spi->dev, "%s() failed: ret = %d\n", __func__, ret);
0113     return ret;
0114 }
0115