Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  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
 16const u8 ax88796c_rx_cmd_buf[5] = {AX_SPICMD_READ_RXQ, 0xFF, 0xFF, 0xFF, 0xFF};
 17const u8 ax88796c_tx_cmd_buf[4] = {AX_SPICMD_WRITE_TXQ, 0xFF, 0xFF, 0xFF};
 18
 19/* driver bus management functions */
 20int 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
 31int 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
 46int 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
 72int 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
 77u16 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
100int 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