1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * cxd2880_spi_device.c
4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
5 * SPI access functions
6 *
7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
8 */
9
10 #include <linux/spi/spi.h>
11
12 #include "cxd2880_spi_device.h"
13
cxd2880_spi_device_write(struct cxd2880_spi * spi,const u8 * data,u32 size)14 static 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
cxd2880_spi_device_write_read(struct cxd2880_spi * spi,const u8 * tx_data,u32 tx_size,u8 * rx_data,u32 rx_size)41 static 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
64 int
cxd2880_spi_device_initialize(struct cxd2880_spi_device * spi_device,enum cxd2880_spi_mode mode,u32 speed_hz)65 cxd2880_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
cxd2880_spi_device_create_spi(struct cxd2880_spi * spi,struct cxd2880_spi_device * spi_device)100 int 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