Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * cxd2880_spi_device.c
0004  * Sony CXD2880 DVB-T2/T tuner + demodulator driver
0005  * SPI access functions
0006  *
0007  * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
0008  */
0009 
0010 #include <linux/spi/spi.h>
0011 
0012 #include "cxd2880_spi_device.h"
0013 
0014 static int cxd2880_spi_device_write(struct cxd2880_spi *spi,
0015                     const u8 *data, u32 size)
0016 {
0017     struct cxd2880_spi_device *spi_device = NULL;
0018     struct spi_message msg;
0019     struct spi_transfer tx;
0020     int result = 0;
0021 
0022     if (!spi || !spi->user || !data || size == 0)
0023         return -EINVAL;
0024 
0025     spi_device = spi->user;
0026 
0027     memset(&tx, 0, sizeof(tx));
0028     tx.tx_buf = data;
0029     tx.len = size;
0030 
0031     spi_message_init(&msg);
0032     spi_message_add_tail(&tx, &msg);
0033     result = spi_sync(spi_device->spi, &msg);
0034 
0035     if (result < 0)
0036         return -EIO;
0037 
0038     return 0;
0039 }
0040 
0041 static int cxd2880_spi_device_write_read(struct cxd2880_spi *spi,
0042                      const u8 *tx_data,
0043                      u32 tx_size,
0044                      u8 *rx_data,
0045                      u32 rx_size)
0046 {
0047     struct cxd2880_spi_device *spi_device = NULL;
0048     int result = 0;
0049 
0050     if (!spi || !spi->user || !tx_data ||
0051         !tx_size || !rx_data || !rx_size)
0052         return -EINVAL;
0053 
0054     spi_device = spi->user;
0055 
0056     result = spi_write_then_read(spi_device->spi, tx_data,
0057                      tx_size, rx_data, rx_size);
0058     if (result < 0)
0059         return -EIO;
0060 
0061     return 0;
0062 }
0063 
0064 int
0065 cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device,
0066                   enum cxd2880_spi_mode mode,
0067                   u32 speed_hz)
0068 {
0069     int result = 0;
0070     struct spi_device *spi = spi_device->spi;
0071 
0072     switch (mode) {
0073     case CXD2880_SPI_MODE_0:
0074         spi->mode = SPI_MODE_0;
0075         break;
0076     case CXD2880_SPI_MODE_1:
0077         spi->mode = SPI_MODE_1;
0078         break;
0079     case CXD2880_SPI_MODE_2:
0080         spi->mode = SPI_MODE_2;
0081         break;
0082     case CXD2880_SPI_MODE_3:
0083         spi->mode = SPI_MODE_3;
0084         break;
0085     default:
0086         return -EINVAL;
0087     }
0088 
0089     spi->max_speed_hz = speed_hz;
0090     spi->bits_per_word = 8;
0091     result = spi_setup(spi);
0092     if (result != 0) {
0093         pr_err("spi_setup failed %d\n", result);
0094         return -EINVAL;
0095     }
0096 
0097     return 0;
0098 }
0099 
0100 int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi,
0101                   struct cxd2880_spi_device *spi_device)
0102 {
0103     if (!spi || !spi_device)
0104         return -EINVAL;
0105 
0106     spi->read = NULL;
0107     spi->write = cxd2880_spi_device_write;
0108     spi->write_read = cxd2880_spi_device_write_read;
0109     spi->flags = 0;
0110     spi->user = spi_device;
0111 
0112     return 0;
0113 }