114 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * cxd2880_spi_device.c4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver5 * SPI access functions6 *7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation8 */9 10#include <linux/spi/spi.h>11 12#include "cxd2880_spi_device.h"13 14static int cxd2880_spi_device_write(struct cxd2880_spi *spi,15 const u8 *data, u32 size)16{17 struct cxd2880_spi_device *spi_device = NULL;18 struct spi_message msg;19 struct spi_transfer tx;20 int result = 0;21 22 if (!spi || !spi->user || !data || size == 0)23 return -EINVAL;24 25 spi_device = spi->user;26 27 memset(&tx, 0, sizeof(tx));28 tx.tx_buf = data;29 tx.len = size;30 31 spi_message_init(&msg);32 spi_message_add_tail(&tx, &msg);33 result = spi_sync(spi_device->spi, &msg);34 35 if (result < 0)36 return -EIO;37 38 return 0;39}40 41static int cxd2880_spi_device_write_read(struct cxd2880_spi *spi,42 const u8 *tx_data,43 u32 tx_size,44 u8 *rx_data,45 u32 rx_size)46{47 struct cxd2880_spi_device *spi_device = NULL;48 int result = 0;49 50 if (!spi || !spi->user || !tx_data ||51 !tx_size || !rx_data || !rx_size)52 return -EINVAL;53 54 spi_device = spi->user;55 56 result = spi_write_then_read(spi_device->spi, tx_data,57 tx_size, rx_data, rx_size);58 if (result < 0)59 return -EIO;60 61 return 0;62}63 64int65cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device,66 enum cxd2880_spi_mode mode,67 u32 speed_hz)68{69 int result = 0;70 struct spi_device *spi = spi_device->spi;71 72 switch (mode) {73 case CXD2880_SPI_MODE_0:74 spi->mode = SPI_MODE_0;75 break;76 case CXD2880_SPI_MODE_1:77 spi->mode = SPI_MODE_1;78 break;79 case CXD2880_SPI_MODE_2:80 spi->mode = SPI_MODE_2;81 break;82 case CXD2880_SPI_MODE_3:83 spi->mode = SPI_MODE_3;84 break;85 default:86 return -EINVAL;87 }88 89 spi->max_speed_hz = speed_hz;90 spi->bits_per_word = 8;91 result = spi_setup(spi);92 if (result != 0) {93 pr_err("spi_setup failed %d\n", result);94 return -EINVAL;95 }96 97 return 0;98}99 100int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi,101 struct cxd2880_spi_device *spi_device)102{103 if (!spi || !spi_device)104 return -EINVAL;105 106 spi->read = NULL;107 spi->write = cxd2880_spi_device_write;108 spi->write_read = cxd2880_spi_device_write_read;109 spi->flags = 0;110 spi->user = spi_device;111 112 return 0;113}114