// SPDX-License-Identifier: GPL-2.0 /* * cxd2880_spi_device.c * Sony CXD2880 DVB-T2/T tuner + demodulator driver * SPI access functions * * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation */ #include #include "cxd2880_spi_device.h" static int cxd2880_spi_device_write(struct cxd2880_spi *spi, const u8 *data, u32 size) { struct cxd2880_spi_device *spi_device = NULL; struct spi_message msg; struct spi_transfer tx; int result = 0; if (!spi || !spi->user || !data || size == 0) return -EINVAL; spi_device = spi->user; memset(&tx, 0, sizeof(tx)); tx.tx_buf = data; tx.len = size; spi_message_init(&msg); spi_message_add_tail(&tx, &msg); result = spi_sync(spi_device->spi, &msg); if (result < 0) return -EIO; return 0; } static int cxd2880_spi_device_write_read(struct cxd2880_spi *spi, const u8 *tx_data, u32 tx_size, u8 *rx_data, u32 rx_size) { struct cxd2880_spi_device *spi_device = NULL; int result = 0; if (!spi || !spi->user || !tx_data || !tx_size || !rx_data || !rx_size) return -EINVAL; spi_device = spi->user; result = spi_write_then_read(spi_device->spi, tx_data, tx_size, rx_data, rx_size); if (result < 0) return -EIO; return 0; } int cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device, enum cxd2880_spi_mode mode, u32 speed_hz) { int result = 0; struct spi_device *spi = spi_device->spi; switch (mode) { case CXD2880_SPI_MODE_0: spi->mode = SPI_MODE_0; break; case CXD2880_SPI_MODE_1: spi->mode = SPI_MODE_1; break; case CXD2880_SPI_MODE_2: spi->mode = SPI_MODE_2; break; case CXD2880_SPI_MODE_3: spi->mode = SPI_MODE_3; break; default: return -EINVAL; } spi->max_speed_hz = speed_hz; spi->bits_per_word = 8; result = spi_setup(spi); if (result != 0) { pr_err("spi_setup failed %d\n", result); return -EINVAL; } return 0; } int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi, struct cxd2880_spi_device *spi_device) { if (!spi || !spi_device) return -EINVAL; spi->read = NULL; spi->write = cxd2880_spi_device_write; spi->write_read = cxd2880_spi_device_write_read; spi->flags = 0; spi->user = spi_device; return 0; }