maa: hide and rename internal maa functions
[contrib/mraa.git] / src / maa.c
1 /*
2  * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3  * Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
4  * Copyright (c) 2014 Intel Corporation.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 #include <stddef.h>
27 #include <stdlib.h>
28
29 #include "maa.h"
30 #include "maa_internal.h"
31 #include "intel_galileo_rev_d.h"
32 #include "gpio.h"
33 #include "version.h"
34
35 //static maa_pininfo_t* pindata;
36 static maa_board_t* plat = NULL;
37
38 const char *
39 maa_get_version()
40 {
41     return gVERSION;
42 }
43
44 #ifdef SWIG
45 maa_result_t
46 maa_init()
47 #else
48 maa_result_t __attribute__((constructor))
49 maa_init()
50 #endif
51 {
52     /** Once more board definitions have been added,
53      *  A method for detecting them will need to be devised.
54      */
55     if (plat != NULL) {
56         return MAA_ERROR_PLATFORM_ALREADY_INITIALISED;
57     }
58 #ifdef SWIGPYTHON
59     // Initialise python threads, this allows use to grab the GIL when we are
60     // required to do so
61     Py_InitializeEx(0);
62     PyEval_InitThreads();
63 #endif
64     plat = maa_intel_galileo_rev_d();
65     return MAA_SUCCESS;
66 }
67
68 static maa_result_t
69 maa_setup_mux_mapped(maa_pin_t meta)
70 {
71     int mi;
72     for (mi = 0; mi < meta.mux_total; mi++) {
73         maa_gpio_context mux_i;
74         mux_i = maa_gpio_init_raw(meta.mux[mi].pin);
75         if (mux_i == NULL)
76             return MAA_ERROR_INVALID_HANDLE;
77         if (maa_gpio_dir(mux_i, MAA_GPIO_OUT) != MAA_SUCCESS)
78             return MAA_ERROR_INVALID_RESOURCE;
79         if (maa_gpio_write(mux_i, meta.mux[mi].value) != MAA_SUCCESS)
80             return MAA_ERROR_INVALID_RESOURCE;
81     }
82     return MAA_SUCCESS;
83 }
84
85 unsigned int
86 maa_setup_gpio(int pin)
87 {
88     if (plat == NULL)
89         return -1;
90
91     if (pin < 0 || pin > plat->phy_pin_count)
92         return -1;
93
94     if(plat->pins[pin].capabilites.gpio != 1)
95       return -1;
96
97     if (plat->pins[pin].gpio.mux_total > 0)
98        if (maa_setup_mux_mapped(plat->pins[pin].gpio) != MAA_SUCCESS)
99             return -1;
100     return plat->pins[pin].gpio.pinmap;
101 }
102
103 unsigned int
104 maa_setup_aio(int aio)
105 {
106     if (plat == NULL)
107         return -3;
108
109     if (aio < 0 || aio > plat->aio_count)
110         return -1;
111
112     int pin = aio + plat->gpio_count;
113
114     if (plat->pins[pin].capabilites.aio != 1)
115       return -1;
116
117     if (plat->pins[pin].aio.mux_total > 0)
118        if (maa_setup_mux_mapped(plat->pins[pin].aio) != MAA_SUCCESS)
119             return -1;
120     return plat->pins[pin].aio.pinmap;
121 }
122
123 unsigned int
124 maa_setup_i2c(int bus_s)
125 {
126     if (plat == NULL)
127         return -3;
128
129     if (plat->i2c_bus_count >! 0) {
130         fprintf(stderr, "No i2c buses defined in platform");
131         return -1;
132     }
133     int bus = 0;
134
135     int pos = plat->i2c_bus[bus].sda;
136     if (plat->pins[pos].i2c.mux_total > 0)
137         if (maa_setup_mux_mapped(plat->pins[pos].i2c) != MAA_SUCCESS)
138              return -2;
139
140     pos = plat->i2c_bus[bus].scl;
141     if (plat->pins[pos].i2c.mux_total > 0)
142         if (maa_setup_mux_mapped(plat->pins[pos].i2c) != MAA_SUCCESS)
143              return -2;
144
145     return plat->i2c_bus[bus].bus_id;
146 }
147
148 maa_spi_bus_t*
149 maa_setup_spi(int bus)
150 {
151     if (plat == NULL)
152         return NULL;
153
154     if (plat->spi_bus_count >! 0) {
155         fprintf(stderr, "No spi buses defined in platform");
156         return NULL;
157     }
158     if (bus >= plat->spi_bus_count) {
159         fprintf(stderr, "Above spi bus count");
160         return NULL;
161     }
162
163     int pos = plat->spi_bus[bus].sclk;
164     if (plat->pins[pos].spi.mux_total > 0)
165         if (maa_setup_mux_mapped(plat->pins[pos].spi) != MAA_SUCCESS)
166              return NULL;
167
168     pos = plat->spi_bus[bus].mosi;
169     if (plat->pins[pos].spi.mux_total > 0)
170         if (maa_setup_mux_mapped(plat->pins[pos].spi) != MAA_SUCCESS)
171              return NULL;
172
173     pos = plat->spi_bus[bus].miso;
174     if (plat->pins[pos].spi.mux_total > 0)
175         if (maa_setup_mux_mapped(plat->pins[pos].spi) != MAA_SUCCESS)
176              return NULL;
177
178     maa_spi_bus_t *spi = &(plat->spi_bus[bus]);
179     return spi;
180 }
181
182 maa_pin_t*
183 maa_setup_pwm(int pin)
184 {
185     if (plat == NULL)
186         return NULL;
187
188     if (plat->pins[pin].capabilites.pwm != 1)
189         return NULL;
190
191     if (plat->pins[pin].capabilites.gpio == 1) {
192         maa_gpio_context mux_i;
193         mux_i = maa_gpio_init_raw(plat->pins[pin].gpio.pinmap);
194         if (mux_i == NULL)
195             return NULL;
196         if (maa_gpio_dir(mux_i, MAA_GPIO_OUT) != MAA_SUCCESS)
197             return NULL;
198         // Current REV D quirk. //TODO GEN 2
199         if (maa_gpio_write(mux_i, 1) != MAA_SUCCESS)
200             return NULL;
201         if (maa_gpio_close(mux_i) != MAA_SUCCESS)
202             return NULL;
203     }
204
205     if (plat->pins[pin].pwm.mux_total > 0)
206        if (maa_setup_mux_mapped(plat->pins[pin].pwm) != MAA_SUCCESS)
207             return NULL;
208
209     maa_pin_t *ret;
210     ret = (maa_pin_t*) malloc(sizeof(maa_pin_t));
211     ret->pinmap = plat->pins[pin].pwm.pinmap;
212     ret->parent_id = plat->pins[pin].pwm.parent_id;
213     return ret;
214 }
215
216 void
217 maa_result_print(maa_result_t result)
218 {
219     switch (result) {
220         case MAA_SUCCESS: fprintf(stderr, "MAA: SUCCESS\n");
221                           break;
222         case MAA_ERROR_FEATURE_NOT_IMPLEMENTED:
223                           fprintf(stderr, "MAA: Feature not implemented.\n");
224                           break;
225         case MAA_ERROR_FEATURE_NOT_SUPPORTED:
226                           fprintf(stderr, "MAA: Feature not supported by Hardware.\n");
227                           break;
228         case MAA_ERROR_INVALID_VERBOSITY_LEVEL:
229                           fprintf(stderr, "MAA: Invalid verbosity level.\n");
230                           break;
231         case MAA_ERROR_INVALID_PARAMETER:
232                           fprintf(stderr, "MAA: Invalid parameter.\n");
233                           break;
234         case MAA_ERROR_INVALID_HANDLE:
235                           fprintf(stderr, "MAA: Invalid Handle.\n");
236                           break;
237         case MAA_ERROR_NO_RESOURCES:
238                           fprintf(stderr, "MAA: No resources.\n");
239                           break;
240         case MAA_ERROR_INVALID_RESOURCE:
241                           fprintf(stderr, "MAA: Invalid resource.\n");
242                           break;
243         case MAA_ERROR_INVALID_QUEUE_TYPE:
244                           fprintf(stderr, "MAA: Invalid Queue Type.\n");
245                           break;
246         case MAA_ERROR_NO_DATA_AVAILABLE:
247                           fprintf(stderr, "MAA: No Data available.\n");
248                           break;
249         case MAA_ERROR_INVALID_PLATFORM:
250                           fprintf(stderr, "MAA: Platform not recognised.\n");
251                           break;
252         case MAA_ERROR_PLATFORM_NOT_INITIALISED:
253                           fprintf(stderr, "MAA: Platform not initialised.\n");
254                           break;
255         case MAA_ERROR_PLATFORM_ALREADY_INITIALISED:
256                           fprintf(stderr, "MAA: Platform already initialised.\n");
257                           break;
258         case MAA_ERROR_UNSPECIFIED:
259                           fprintf(stderr, "MAA: Unspecified Error.\n");
260                           break;
261         default:     fprintf(stderr, "MAA: Unrecognised error.\n");
262                           break;
263     }
264 }
265
266 maa_boolean_t
267 maa_pin_mode_test(int pin, maa_pinmodes_t mode)
268 {
269     if (plat == NULL) {
270         maa_init();
271         if (plat == NULL)
272             return 0;
273     }
274     if (pin > plat->phy_pin_count || pin < 0)
275         return 0;
276
277     switch(mode) {
278         case MAA_PIN_VALID:
279             if (plat->pins[pin].capabilites.valid == 1)
280                 return 1;
281             break;
282         case MAA_PIN_GPIO:
283             if (plat->pins[pin].capabilites.gpio ==1)
284                 return 1;
285             break;
286         case MAA_PIN_PWM:
287             if (plat->pins[pin].capabilites.pwm ==1)
288                 return 1;
289             break;
290         case MAA_PIN_FAST_GPIO:
291             if (plat->pins[pin].capabilites.fast_gpio ==1)
292                 return 1;
293             break;
294         case MAA_PIN_SPI:
295             if (plat->pins[pin].capabilites.spi ==1)
296                 return 1;
297             break;
298         case MAA_PIN_I2C:
299             if (plat->pins[pin].capabilites.i2c ==1)
300                 return 1;
301             break;
302         case MAA_PIN_AIO:
303             if (pin < plat->aio_count)
304                 pin = pin + plat->gpio_count;
305             if (plat->pins[pin].capabilites.aio ==1)
306                 return 1;
307             break;
308         default: break;
309     }
310     return 0;
311 }