34e777c74956259fb0e14115ae8cb48c9dfad1ac
[platform/core/api/peripheral-io.git] / src / peripheral_spi.c
1 /*
2  * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "peripheral_io.h"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <system_info.h>
23
24 #include "peripheral_io.h"
25 #include "peripheral_gdbus_spi.h"
26 #include "peripheral_common.h"
27 #include "peripheral_internal.h"
28
29 #define PERIPHERAL_IO_SPI_FEATURE "http://tizen.org/feature/peripheral_io.spi"
30
31 #define SPI_FEATURE_UNKNOWN -1
32 #define SPI_FEATURE_FALSE    0
33 #define SPI_FEATURE_TRUE     1
34
35 static int spi_feature = SPI_FEATURE_UNKNOWN;
36
37 static bool __is_feature_supported()
38 {
39         int ret = SYSTEM_INFO_ERROR_NONE;
40         bool feature = false;
41
42         if (spi_feature == SPI_FEATURE_UNKNOWN) {
43                 ret = system_info_get_platform_bool(PERIPHERAL_IO_SPI_FEATURE, &feature);
44                 RETVM_IF(ret != SYSTEM_INFO_ERROR_NONE, false, "Failed to get system info");
45
46                 spi_feature = (feature ? SPI_FEATURE_TRUE : SPI_FEATURE_FALSE);
47         }
48
49         return (spi_feature == SPI_FEATURE_TRUE ? true : false);
50 }
51
52 int peripheral_spi_open(int bus, int cs, peripheral_spi_h *spi)
53 {
54         peripheral_spi_h handle;
55         int ret = PERIPHERAL_ERROR_NONE;
56
57         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
58         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid spi handle");
59         RETVM_IF(bus < 0 || cs < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter");
60
61         /* Initialize */
62         handle = (peripheral_spi_h)calloc(1, sizeof(struct _peripheral_spi_s));
63
64         if (handle == NULL) {
65                 _E("Failed to allocate peripheral_spi_h");
66                 return PERIPHERAL_ERROR_OUT_OF_MEMORY;
67         }
68
69         spi_proxy_init();
70
71         ret = peripheral_gdbus_spi_open(handle, bus, cs);
72
73         if (ret != PERIPHERAL_ERROR_NONE) {
74                 _E("SPI open error (%d, %d)", bus, cs);
75                 free(handle);
76                 handle = NULL;
77         }
78         *spi = handle;
79
80         return ret;
81 }
82
83 int peripheral_spi_close(peripheral_spi_h spi)
84 {
85         int ret = PERIPHERAL_ERROR_NONE;
86
87         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
88         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
89
90         ret = peripheral_gdbus_spi_close(spi);
91         if (ret < PERIPHERAL_ERROR_NONE)
92                 _E("Failed to close SPI device, continuing anyway, ret : %d", ret);
93
94         spi_proxy_deinit();
95         free(spi);
96
97         return ret;
98 }
99
100 int peripheral_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode)
101 {
102         int ret;
103
104         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
105         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
106         RETVM_IF((mode < PERIPHERAL_SPI_MODE_0) || (mode > PERIPHERAL_SPI_MODE_3), PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid spi mode parameter");
107
108         ret = peripheral_gdbus_spi_set_mode(spi, mode);
109         if (ret != PERIPHERAL_ERROR_NONE)
110                 _E("Failed to set mode, ret : %d", ret);
111
112         return ret;
113 }
114
115 int peripheral_spi_set_bit_order(peripheral_spi_h spi, peripheral_spi_bit_order_e bit_order)
116 {
117         int ret;
118
119         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
120         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
121         RETVM_IF((bit_order < PERIPHERAL_SPI_BIT_ORDER_MSB) || (bit_order > PERIPHERAL_SPI_BIT_ORDER_LSB), PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid bit order parameter");
122
123         bool lsb = (bit_order == PERIPHERAL_SPI_BIT_ORDER_LSB) ? true : false;
124         ret = peripheral_gdbus_spi_set_bit_order(spi, lsb);
125         if (ret != PERIPHERAL_ERROR_NONE)
126                 _E("Failed to set lsb first, ret : %d", ret);
127
128         return ret;
129 }
130
131 int peripheral_spi_set_bits_per_word(peripheral_spi_h spi, uint8_t bits)
132 {
133         int ret;
134
135         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
136         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
137
138         ret = peripheral_gdbus_spi_set_bits_per_word(spi, (unsigned char)bits);
139         if (ret != PERIPHERAL_ERROR_NONE)
140                 _E("Failed to set bits per word, ret : %d", ret);
141
142         return ret;
143 }
144
145 int peripheral_spi_set_frequency(peripheral_spi_h spi, uint32_t freq_hz)
146 {
147         int ret;
148
149         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
150         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
151
152         ret = peripheral_gdbus_spi_set_frequency(spi, (unsigned int)freq_hz);
153         if (ret != PERIPHERAL_ERROR_NONE)
154                 _E("Failed to set frequency, ret : %d", ret);
155
156         return ret;
157 }
158
159 int peripheral_spi_read(peripheral_spi_h spi, uint8_t *data, uint32_t length)
160 {
161         int ret;
162
163         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
164         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
165         RETVM_IF(data == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter");
166
167         ret = peripheral_gdbus_spi_read(spi, data, (int)length);
168         if (ret != PERIPHERAL_ERROR_NONE)
169                 _E("Failed to read from spi device, ret : %d", ret);
170
171         return ret;
172 }
173
174 int peripheral_spi_write(peripheral_spi_h spi, uint8_t *data, uint32_t length)
175 {
176         int ret;
177
178         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
179         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
180         RETVM_IF(data == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter");
181
182         ret = peripheral_gdbus_spi_write(spi, data, (int)length);
183         if (ret != PERIPHERAL_ERROR_NONE)
184                 _E("Failed to write to spi device, ret : %d", ret);
185
186         return ret;
187 }
188
189 int peripheral_spi_transfer(peripheral_spi_h spi, uint8_t *txdata, uint8_t *rxdata, uint32_t length)
190 {
191         int ret;
192
193         RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported");
194         RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL");
195         RETVM_IF(txdata == NULL || rxdata == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter");
196
197         ret = peripheral_gdbus_spi_transfer(spi, txdata, rxdata, (int)length);
198         if (ret != PERIPHERAL_ERROR_NONE)
199                 _E("Failed to read and write, ret : %d", ret);
200
201         return ret;
202 }