2959835d3e1250e37983536edc71123f1cbb5747
[platform/core/api/peripheral-io.git] / src / gdbus / peripheral_gdbus_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 <stdio.h>
18 #include <stdlib.h>
19 #include <gio/gunixfdlist.h>
20
21 #include "peripheral_io.h"
22 #include "peripheral_gdbus.h"
23 #include "peripheral_common.h"
24 #include "peripheral_internal.h"
25 #include "peripheral_io_gdbus.h"
26
27 #define SPI_FD_INDEX 0
28
29 static PeripheralIoGdbusSpi *spi_proxy = NULL;
30
31 void spi_proxy_init(void)
32 {
33         GError *error = NULL;
34
35         if (spi_proxy != NULL) {
36                 g_object_ref(spi_proxy);
37                 return;
38         }
39
40         spi_proxy = peripheral_io_gdbus_spi_proxy_new_for_bus_sync(
41                 G_BUS_TYPE_SYSTEM,
42                 G_DBUS_PROXY_FLAGS_NONE,
43                 PERIPHERAL_GDBUS_NAME,
44                 PERIPHERAL_GDBUS_SPI_PATH,
45                 NULL,
46                 &error);
47 }
48
49 void spi_proxy_deinit()
50 {
51         if (spi_proxy) {
52                 g_object_unref(spi_proxy);
53                 if (!G_IS_OBJECT(spi_proxy))
54                         spi_proxy = NULL;
55         }
56 }
57
58 int peripheral_gdbus_spi_open(peripheral_spi_h spi, int bus, int cs)
59 {
60         GError *error = NULL;
61         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
62         GUnixFDList *fd_list = NULL;
63
64         if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
65
66         if (peripheral_io_gdbus_spi_call_open_sync(
67                         spi_proxy,
68                         bus,
69                         cs,
70                         NULL,
71                         &spi->handle,
72                         &ret,
73                         &fd_list,
74                         NULL,
75                         &error) == FALSE) {
76                 _E("%s", error->message);
77                 g_error_free(error);
78                 return PERIPHERAL_ERROR_UNKNOWN;
79         }
80
81         spi->fd = g_unix_fd_list_get(fd_list, SPI_FD_INDEX, &error);
82         if (spi->fd < 0) {
83                 _E("Failed to get fd for spi : %s", error->message);
84                 g_error_free(error);
85                 ret = PERIPHERAL_ERROR_UNKNOWN;
86         }
87
88         g_object_unref(fd_list);
89
90         return ret;
91 }
92
93 int peripheral_gdbus_spi_close(peripheral_spi_h spi)
94 {
95         GError *error = NULL;
96         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
97
98         if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
99
100         if (peripheral_io_gdbus_spi_call_close_sync(
101                         spi_proxy,
102                         spi->handle,
103                         &ret,
104                         NULL,
105                         &error) == FALSE) {
106                 _E("%s", error->message);
107                 g_error_free(error);
108                 return PERIPHERAL_ERROR_UNKNOWN;
109         }
110
111         return ret;
112 }
113
114 int peripheral_gdbus_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode)
115 {
116         GError *error = NULL;
117         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
118
119         if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
120
121         if (peripheral_io_gdbus_spi_call_set_mode_sync(
122                         spi_proxy,
123                         spi->handle,
124                         (guchar)mode,
125                         &ret,
126                         NULL,
127                         &error) == FALSE) {
128                 _E("%s", error->message);
129                 g_error_free(error);
130                 return PERIPHERAL_ERROR_UNKNOWN;
131         }
132
133         return ret;
134 }
135
136 int peripheral_gdbus_spi_set_bit_order(peripheral_spi_h spi, bool lsb)
137 {
138         GError *error = NULL;
139         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
140
141         if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
142
143         if (peripheral_io_gdbus_spi_call_set_bit_order_sync(
144                         spi_proxy,
145                         spi->handle,
146                         lsb,
147                         &ret,
148                         NULL,
149                         &error) == FALSE) {
150                 _E("%s", error->message);
151                 g_error_free(error);
152                 return PERIPHERAL_ERROR_UNKNOWN;
153         }
154
155         return ret;
156 }
157
158 int peripheral_gdbus_spi_set_bits_per_word(peripheral_spi_h spi, unsigned char bits)
159 {
160         GError *error = NULL;
161         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
162
163         if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
164
165         if (peripheral_io_gdbus_spi_call_set_bits_per_word_sync(
166                         spi_proxy,
167                         spi->handle,
168                         bits,
169                         &ret,
170                         NULL,
171                         &error) == FALSE) {
172                 _E("%s", error->message);
173                 g_error_free(error);
174                 return PERIPHERAL_ERROR_UNKNOWN;
175         }
176
177         return ret;
178 }
179
180 int peripheral_gdbus_spi_set_frequency(peripheral_spi_h spi, unsigned int freq_hz)
181 {
182         GError *error = NULL;
183         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
184
185         if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
186
187         if (peripheral_io_gdbus_spi_call_set_frequency_sync(
188                         spi_proxy,
189                         spi->handle,
190                         freq_hz,
191                         &ret,
192                         NULL,
193                         &error) == FALSE) {
194                 _E("%s", error->message);
195                 g_error_free(error);
196                 return PERIPHERAL_ERROR_UNKNOWN;
197         }
198
199         return ret;
200 }
201
202 int peripheral_gdbus_spi_read(peripheral_spi_h spi, unsigned char *data, int length)
203 {
204         GError *error = NULL;
205         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
206         GVariant *data_array;
207         GVariantIter *iter;
208         guint8 str;
209         int i = 0;
210
211         if (spi_proxy == NULL || data == NULL) return PERIPHERAL_ERROR_UNKNOWN;
212
213         if (peripheral_io_gdbus_spi_call_read_sync(
214                         spi_proxy,
215                         spi->handle,
216                         length,
217                         &data_array,
218                         &ret,
219                         NULL,
220                         &error) == FALSE) {
221                 _E("%s", error->message);
222                 g_error_free(error);
223                 return PERIPHERAL_ERROR_UNKNOWN;
224         }
225
226         g_variant_get(data_array, "a(y)", &iter);
227         while (g_variant_iter_loop(iter, "(y)", &str)) {
228                 data[i] = str;
229                 if (i++ == length) break;
230         }
231         g_variant_iter_free(iter);
232         g_variant_unref(data_array);
233
234         return ret;
235 }
236
237 int peripheral_gdbus_spi_write(peripheral_spi_h spi, unsigned char *data, int length)
238 {
239         GError *error = NULL;
240         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
241         GVariantBuilder *builder;
242         GVariant *data_array;
243         int i = 0;
244
245         if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
246
247         builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
248
249         for (i = 0; i < length; i++)
250                 g_variant_builder_add(builder, "(y)", data[i]);
251         g_variant_builder_add(builder, "(y)", 0x00);
252
253         data_array = g_variant_new("a(y)", builder);
254         g_variant_builder_unref(builder);
255
256         if (peripheral_io_gdbus_spi_call_write_sync(
257                         spi_proxy,
258                         spi->handle,
259                         length,
260                         data_array,
261                         &ret,
262                         NULL,
263                         &error) == FALSE) {
264                 _E("%s", error->message);
265                 g_error_free(error);
266                 return PERIPHERAL_ERROR_UNKNOWN;
267         }
268
269         return ret;
270 }
271
272 int peripheral_gdbus_spi_transfer(peripheral_spi_h spi, unsigned char *tx_data, unsigned char *rx_data, int length)
273 {
274         GError *error = NULL;
275         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
276         GVariantBuilder *builder;
277         GVariant *rx_data_array;
278         GVariant *tx_data_array;
279         GVariantIter *iter;
280         guint8 str;
281         int i = 0;
282
283         if (spi_proxy == NULL || !rx_data || !tx_data) return PERIPHERAL_ERROR_UNKNOWN;
284
285         builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
286
287         for (i = 0; i < length; i++)
288                 g_variant_builder_add(builder, "(y)", tx_data[i]);
289         g_variant_builder_add(builder, "(y)", 0x00);
290
291         tx_data_array = g_variant_new("a(y)", builder);
292         g_variant_builder_unref(builder);
293
294         if (peripheral_io_gdbus_spi_call_transfer_sync(
295                         spi_proxy,
296                         spi->handle,
297                         length,
298                         tx_data_array,
299                         &rx_data_array,
300                         &ret,
301                         NULL,
302                         &error) == FALSE) {
303                 _E("%s", error->message);
304                 g_error_free(error);
305                 return PERIPHERAL_ERROR_UNKNOWN;
306         }
307
308         i = 0;
309         g_variant_get(rx_data_array, "a(y)", &iter);
310         while (g_variant_iter_loop(iter, "(y)", &str)) {
311                 rx_data[i] = str;
312                 if (i++ == length) break;
313         }
314         g_variant_iter_free(iter);
315         g_variant_unref(rx_data_array);
316
317         return ret;
318 }