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 <stdlib.h>
27 #include <string.h>
28 #include <sys/mman.h>
29 
30 #include "common.h"
31 #include "x86/intel_galileo_rev_g.h"
32 
33 #define MAX_SIZE 64
34 #define SYSFS_CLASS_GPIO "/sys/class/gpio"
35 #define PLATFORM_NAME "Intel Galileo Gen 2"
36 
37 #define UIO_PATH "/dev/uio0"
38 
39 static uint8_t* mmap_reg = NULL;
40 static int mmap_fd = 0;
41 static int mmap_size = 0x1000;
42 static unsigned int mmap_count = 0;
43 
44 static unsigned int pullup_map[] = { 33, 29, 35, 17, 37, 19, 21, 39, 41, 23,
45                                      27, 25, 43, 31, 49, 51, 53, 55, 57, 59 };
46 
47 static mraa_gpio_context agpioOutputen[MRAA_INTEL_GALILEO_GEN_2_PINCOUNT];
48 
49 mraa_result_t
mraa_intel_galileo_gen2_dir_pre(mraa_gpio_context dev,mraa_gpio_dir_t dir)50 mraa_intel_galileo_gen2_dir_pre(mraa_gpio_context dev, mraa_gpio_dir_t dir)
51 {
52     if (dev->phy_pin >= 0) {
53         int pin = dev->phy_pin;
54         if (plat->pins[pin].gpio.complex_cap.complex_pin != 1)
55             return MRAA_SUCCESS;
56 
57         if (plat->pins[pin].gpio.complex_cap.output_en == 1) {
58             if (!agpioOutputen[pin]) {
59                 agpioOutputen[pin] = mraa_gpio_init_raw(plat->pins[pin].gpio.output_enable);
60                 if (agpioOutputen[pin] == NULL) {
61                     return MRAA_ERROR_INVALID_RESOURCE;
62                 }
63                 if (mraa_gpio_dir(agpioOutputen[pin], MRAA_GPIO_OUT) != MRAA_SUCCESS) {
64                     return MRAA_ERROR_INVALID_RESOURCE;
65                 }
66             }
67 
68             int output_val = 1;
69             if (dir == MRAA_GPIO_OUT) {
70                 output_val = 0;
71             }
72             if (mraa_gpio_write(agpioOutputen[pin], output_val) != MRAA_SUCCESS) {
73                 return MRAA_ERROR_INVALID_RESOURCE;
74             }
75         }
76     }
77     return MRAA_SUCCESS;
78 }
79 
80 mraa_result_t
mraa_intel_galileo_gen2_gpio_close_pre(mraa_gpio_context dev)81 mraa_intel_galileo_gen2_gpio_close_pre(mraa_gpio_context dev)
82 {
83     if (dev->phy_pin >= 0) {
84         int pin = dev->phy_pin;
85         if (agpioOutputen[pin]) {
86             mraa_gpio_close(agpioOutputen[pin]);
87             agpioOutputen[pin] = NULL;
88         }
89     }
90     return MRAA_SUCCESS;
91 }
92 
93 mraa_result_t
mraa_intel_galileo_gen2_i2c_init_pre(unsigned int bus)94 mraa_intel_galileo_gen2_i2c_init_pre(unsigned int bus)
95 {
96     mraa_gpio_context io18 = mraa_gpio_init_raw(57);
97     int status = 0;
98 
99     if (io18 == NULL) {
100         return MRAA_ERROR_UNSPECIFIED;
101     }
102     status += mraa_gpio_dir(io18, MRAA_GPIO_IN);
103     status += mraa_gpio_mode(io18, MRAA_GPIO_HIZ);
104     mraa_gpio_close(io18);
105 
106     mraa_gpio_context io19 = mraa_gpio_init_raw(59);
107     if (io19 == NULL) {
108         return MRAA_ERROR_UNSPECIFIED;
109     }
110     status += mraa_gpio_dir(io19, MRAA_GPIO_IN);
111     status += mraa_gpio_mode(io19, MRAA_GPIO_HIZ);
112     mraa_gpio_close(io19);
113 
114     if (status > 0) {
115         return MRAA_ERROR_UNSPECIFIED;
116     }
117     return MRAA_SUCCESS;
118 }
119 
120 mraa_result_t
mraa_intel_galileo_gen2_pwm_period_replace(mraa_pwm_context dev,int period)121 mraa_intel_galileo_gen2_pwm_period_replace(mraa_pwm_context dev, int period)
122 {
123     char bu[MAX_SIZE];
124     snprintf(bu, MAX_SIZE, "/sys/class/pwm/pwmchip%d/device/pwm_period", dev->chipid);
125 
126     int period_f = open(bu, O_RDWR);
127     if (period_f == -1) {
128         syslog(LOG_ERR, "galileo2: Failed to open period for writing!");
129         return MRAA_ERROR_INVALID_RESOURCE;
130     }
131     char out[MAX_SIZE];
132     int length = snprintf(out, MAX_SIZE, "%d", period);
133     if (write(period_f, out, length * sizeof(char)) == -1) {
134         close(period_f);
135         return MRAA_ERROR_INVALID_RESOURCE;
136     }
137 
138     close(period_f);
139     return MRAA_SUCCESS;
140 }
141 
142 mraa_result_t
mraa_intel_galileo_gen2_gpio_mode_replace(mraa_gpio_context dev,mraa_gpio_mode_t mode)143 mraa_intel_galileo_gen2_gpio_mode_replace(mraa_gpio_context dev, mraa_gpio_mode_t mode)
144 {
145     if (dev->value_fp != -1) {
146         close(dev->value_fp);
147         dev->value_fp = -1;
148     }
149 
150     mraa_gpio_context pullup_e;
151     pullup_e = mraa_gpio_init_raw(pullup_map[dev->phy_pin]);
152     if (pullup_e == NULL) {
153         return MRAA_ERROR_INVALID_RESOURCE;
154     }
155     if (mraa_gpio_dir(pullup_e, MRAA_GPIO_IN) != MRAA_SUCCESS) {
156         mraa_gpio_close(pullup_e);
157         syslog(LOG_ERR, "galileo2: Failed to set gpio pullup");
158         return MRAA_ERROR_INVALID_RESOURCE;
159     }
160 
161     char filepath[MAX_SIZE];
162     snprintf(filepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/drive", pullup_map[dev->phy_pin]);
163 
164     int drive = open(filepath, O_WRONLY);
165     if (drive == -1) {
166         syslog(LOG_ERR, "galileo2: Failed to open drive for writing");
167         return MRAA_ERROR_INVALID_RESOURCE;
168     }
169 
170     char bu[MAX_SIZE];
171     int length;
172     int value = -1;
173     switch (mode) {
174         case MRAA_GPIO_STRONG:
175             length = snprintf(bu, sizeof(bu), "hiz");
176             break;
177         case MRAA_GPIO_PULLUP:
178             length = snprintf(bu, sizeof(bu), "strong");
179             value = 1;
180             break;
181         case MRAA_GPIO_PULLDOWN:
182             length = snprintf(bu, sizeof(bu), "pulldown");
183             value = 0;
184             break;
185         case MRAA_GPIO_HIZ:
186             close(drive);
187             return MRAA_SUCCESS;
188             break;
189         default:
190             close(drive);
191             return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED;
192     }
193     if (write(drive, bu, length * sizeof(char)) == -1) {
194         syslog(LOG_ERR, "galileo2: Failed to write to drive mode");
195         close(drive);
196         mraa_gpio_close(pullup_e);
197         return MRAA_ERROR_INVALID_RESOURCE;
198     }
199     if (value != -1) {
200         mraa_result_t ret = mraa_gpio_dir(pullup_e, MRAA_GPIO_OUT);
201         ret += mraa_gpio_write(pullup_e, value);
202         if (ret != MRAA_SUCCESS) {
203             syslog(LOG_ERR, "galileo2: Error Setting pullup");
204             close(drive);
205             return MRAA_ERROR_INVALID_RESOURCE;
206         }
207     }
208 
209     mraa_gpio_close(pullup_e);
210     close(drive);
211     return MRAA_SUCCESS;
212 }
213 
214 mraa_result_t
mraa_intel_galileo_gen2_uart_init_pre(int index)215 mraa_intel_galileo_gen2_uart_init_pre(int index)
216 {
217     mraa_gpio_context io0_output = mraa_gpio_init_raw(32);
218     if (io0_output == NULL) {
219         return MRAA_ERROR_INVALID_RESOURCE;
220     }
221     mraa_gpio_context io1_output = mraa_gpio_init_raw(28);
222     if (io1_output == NULL) {
223         mraa_gpio_close(io0_output);
224         return MRAA_ERROR_INVALID_RESOURCE;
225     }
226 
227     int status = 0;
228     status += mraa_gpio_dir(io0_output, MRAA_GPIO_OUT);
229     status += mraa_gpio_dir(io1_output, MRAA_GPIO_OUT);
230 
231     status += mraa_gpio_write(io0_output, 1);
232     status += mraa_gpio_write(io1_output, 0);
233 
234     mraa_gpio_close(io0_output);
235     mraa_gpio_close(io1_output);
236 
237     if (status > 0) {
238         return MRAA_ERROR_UNSPECIFIED;
239     }
240     return MRAA_SUCCESS;
241 }
242 
243 static mraa_result_t
mraa_intel_galileo_g2_mmap_unsetup()244 mraa_intel_galileo_g2_mmap_unsetup()
245 {
246     if (mmap_reg == NULL) {
247         syslog(LOG_ERR, "mmap: null register cant unsetup");
248         return MRAA_ERROR_INVALID_RESOURCE;
249     }
250     munmap(mmap_reg, mmap_size);
251     mmap_reg = NULL;
252     close(mmap_fd);
253     return MRAA_SUCCESS;
254 }
255 
256 mraa_result_t
mraa_intel_galileo_g2_mmap_write(mraa_gpio_context dev,int value)257 mraa_intel_galileo_g2_mmap_write(mraa_gpio_context dev, int value)
258 {
259     int bitpos = plat->pins[dev->phy_pin].mmap.bit_pos;
260     if (value) {
261         *((unsigned*) mmap_reg) |= (1 << bitpos);
262         return MRAA_SUCCESS;
263     }
264     *((unsigned*) mmap_reg) &= ~(1 << bitpos);
265 
266     return MRAA_SUCCESS;
267 }
268 
269 mraa_result_t
mraa_intel_galileo_g2_mmap_setup(mraa_gpio_context dev,mraa_boolean_t en)270 mraa_intel_galileo_g2_mmap_setup(mraa_gpio_context dev, mraa_boolean_t en)
271 {
272     if (dev == NULL) {
273         syslog(LOG_ERR, "Galileo mmap: context not valid");
274         return MRAA_ERROR_INVALID_HANDLE;
275     }
276 
277     if (mraa_pin_mode_test(dev->phy_pin, MRAA_PIN_FAST_GPIO) == 0) {
278         syslog(LOG_ERR, "Galileo mmap: mmap not on this pin");
279         return MRAA_ERROR_NO_RESOURCES;
280     }
281     if (en == 0) {
282         if (dev->mmap_write == NULL) {
283             syslog(LOG_ERR, "mmap: can't disable disabled mmap gpio");
284             return MRAA_ERROR_INVALID_PARAMETER;
285         }
286         dev->mmap_write = NULL;
287         mmap_count--;
288         if (mmap_count == 0) {
289             return mraa_intel_galileo_g2_mmap_unsetup();
290         }
291         return MRAA_SUCCESS;
292     }
293 
294     if (dev->mmap_write != NULL) {
295         syslog(LOG_ERR, "mmap: can't enable enabled mmap gpio");
296         return MRAA_ERROR_INVALID_PARAMETER;
297     }
298     if (mmap_reg == NULL) {
299         if ((mmap_fd = open(UIO_PATH, O_RDWR)) < 0) {
300             syslog(LOG_ERR, "mmap: Unable to open UIO device");
301             return MRAA_ERROR_INVALID_RESOURCE;
302         }
303         mmap_reg = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, mmap_fd, 0);
304 
305         if (mmap_reg == MAP_FAILED) {
306             syslog(LOG_ERR, "mmap: failed to mmap");
307             mmap_reg = NULL;
308             close(mmap_fd);
309             return MRAA_ERROR_NO_RESOURCES;
310         }
311     }
312     if (mraa_setup_mux_mapped(plat->pins[dev->phy_pin].mmap.gpio) != MRAA_SUCCESS) {
313         syslog(LOG_ERR, "mmap: unable to setup required multiplexers");
314         return MRAA_ERROR_INVALID_RESOURCE;
315     }
316     dev->mmap_write = &mraa_intel_galileo_g2_mmap_write;
317     return MRAA_SUCCESS;
318 }
319 
320 mraa_board_t*
mraa_intel_galileo_gen2()321 mraa_intel_galileo_gen2()
322 {
323     mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t));
324     if (b == NULL) {
325         return NULL;
326     }
327 
328     b->platform_name = PLATFORM_NAME;
329     b->phy_pin_count = 20;
330     b->gpio_count = 14;
331     b->aio_count = 6;
332     b->adc_raw = 12;
333     b->adc_supported = 10;
334     b->pwm_default_period = 5000;
335     b->pwm_max_period = 41666;
336     b->pwm_min_period = 666;
337 
338     b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
339     if (b->adv_func == NULL) {
340         goto error;
341     }
342     b->adv_func->gpio_close_pre = &mraa_intel_galileo_gen2_gpio_close_pre;
343     b->adv_func->gpio_dir_pre = &mraa_intel_galileo_gen2_dir_pre;
344     b->adv_func->i2c_init_pre = &mraa_intel_galileo_gen2_i2c_init_pre;
345     b->adv_func->pwm_period_replace = &mraa_intel_galileo_gen2_pwm_period_replace;
346     b->adv_func->gpio_mode_replace = &mraa_intel_galileo_gen2_gpio_mode_replace;
347     b->adv_func->uart_init_pre = &mraa_intel_galileo_gen2_uart_init_pre;
348     b->adv_func->gpio_mmap_setup = &mraa_intel_galileo_g2_mmap_setup;
349 
350     b->pins = (mraa_pininfo_t*) calloc(MRAA_INTEL_GALILEO_GEN_2_PINCOUNT, sizeof(mraa_pininfo_t));
351     if (b->pins == NULL) {
352         free(b->adv_func);
353         goto error;
354     }
355 
356     strncpy(b->pins[0].name, "IO0", 8);
357     b->pins[0].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 1, 0, 0, 0, 1 };
358     b->pins[0].gpio.pinmap = 11;
359     b->pins[0].gpio.parent_id = 0;
360     b->pins[0].gpio.mux_total = 0;
361     b->pins[0].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
362     b->pins[0].gpio.output_enable = 32;
363     b->pins[0].gpio.pullup_enable = 33;
364     b->pins[0].mmap.gpio.pinmap = 11;
365     strncpy(b->pins[0].mmap.mem_dev, "/dev/uio0", 12);
366     b->pins[0].mmap.gpio.mux_total = 2;
367     b->pins[0].mmap.gpio.mux[0].pin = 32;
368     b->pins[0].mmap.gpio.mux[0].value = 0;
369     b->pins[0].mmap.gpio.mux[1].pin = 11;
370     b->pins[0].mmap.gpio.mux[1].value = 0;
371     b->pins[0].mmap.mem_sz = 0x1000;
372     b->pins[0].mmap.bit_pos = 3;
373     b->pins[0].uart.parent_id = 0;
374     b->pins[0].uart.mux_total = 0;
375 
376     strncpy(b->pins[1].name, "IO1", 8);
377     b->pins[1].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 1, 0, 0, 0, 1 };
378     b->pins[1].gpio.pinmap = 12;
379     b->pins[1].gpio.parent_id = 0;
380     b->pins[1].gpio.mux_total = 1;
381     b->pins[1].gpio.mux[0].pin = 45;
382     b->pins[1].gpio.mux[0].value = 0;
383     b->pins[1].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
384     b->pins[1].gpio.output_enable = 28;
385     b->pins[1].gpio.pullup_enable = 29;
386     b->pins[1].mmap.gpio.pinmap = 12;
387     strncpy(b->pins[1].mmap.mem_dev, "/dev/uio0", 12);
388     b->pins[1].mmap.gpio.mux_total = 3;
389     b->pins[1].mmap.gpio.mux[0].pin = 45;
390     b->pins[1].mmap.gpio.mux[0].value = 0;
391     b->pins[1].mmap.gpio.mux[1].pin = 28;
392     b->pins[1].mmap.gpio.mux[1].value = 0;
393     b->pins[1].mmap.gpio.mux[2].pin = 12;
394     b->pins[1].mmap.gpio.mux[2].value = 0;
395     b->pins[1].mmap.mem_sz = 0x1000;
396     b->pins[1].mmap.bit_pos = 4;
397     b->pins[1].uart.parent_id = 0;
398     b->pins[1].uart.mux_total = 1;
399     b->pins[1].uart.mux[0].pin = 45;
400     b->pins[1].uart.mux[0].value = 1;
401 
402     strncpy(b->pins[2].name, "IO2", 8);
403     b->pins[2].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 1, 0, 0, 0 };
404     b->pins[2].gpio.pinmap = 13;
405     b->pins[2].gpio.parent_id = 0;
406     b->pins[2].gpio.mux_total = 1;
407     b->pins[2].gpio.mux[0].pin = 77;
408     b->pins[2].gpio.mux[0].value = 0;
409     b->pins[2].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
410     b->pins[2].gpio.output_enable = 34;
411     b->pins[2].gpio.pullup_enable = 35;
412     b->pins[2].mmap.gpio.pinmap = 13;
413     strncpy(b->pins[2].mmap.mem_dev, "/dev/uio0", 12);
414     b->pins[2].mmap.gpio.mux_total = 3;
415     b->pins[2].mmap.gpio.mux[0].pin = 77;
416     b->pins[2].mmap.gpio.mux[0].value = 0;
417     b->pins[2].mmap.gpio.mux[1].pin = 34;
418     b->pins[2].mmap.gpio.mux[1].value = 0;
419     b->pins[2].mmap.gpio.mux[2].pin = 13;
420     b->pins[2].mmap.gpio.mux[2].value = 0;
421     b->pins[2].mmap.mem_sz = 0x1000;
422     b->pins[2].mmap.bit_pos = 5;
423 
424     strncpy(b->pins[3].name, "IO3", 8);
425     b->pins[3].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 1, 0, 0, 0 };
426     b->pins[3].gpio.pinmap = 14;
427     b->pins[3].gpio.parent_id = 0;
428     b->pins[3].gpio.mux_total = 2;
429     b->pins[3].gpio.mux[0].pin = 76;
430     b->pins[3].gpio.mux[0].value = 0;
431     b->pins[3].gpio.mux[1].pin = 64;
432     b->pins[3].gpio.mux[1].value = 0;
433     b->pins[3].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
434     b->pins[3].gpio.output_enable = 16;
435     b->pins[3].gpio.pullup_enable = 17;
436     b->pins[3].pwm.pinmap = 1;
437     b->pins[3].pwm.parent_id = 0;
438     b->pins[3].pwm.mux_total = 3;
439     b->pins[3].pwm.mux[0].pin = 76;
440     b->pins[3].pwm.mux[0].value = 0;
441     b->pins[3].pwm.mux[1].pin = 64;
442     b->pins[3].pwm.mux[1].value = 1;
443     b->pins[3].pwm.mux[2].pin = 16;
444     b->pins[3].pwm.mux[2].value = 0;
445     b->pins[3].mmap.gpio.pinmap = 14;
446     strncpy(b->pins[3].mmap.mem_dev, "/dev/uio0", 12);
447     b->pins[3].mmap.gpio.mux_total = 4;
448     b->pins[3].mmap.gpio.mux[0].pin = 76;
449     b->pins[3].mmap.gpio.mux[0].value = 0;
450     b->pins[3].mmap.gpio.mux[1].pin = 64;
451     b->pins[3].mmap.gpio.mux[1].value = 0;
452     b->pins[3].mmap.gpio.mux[2].pin = 16;
453     b->pins[3].mmap.gpio.mux[2].value = 0;
454     b->pins[3].mmap.gpio.mux[3].pin = 14;
455     b->pins[3].mmap.gpio.mux[3].value = 0;
456     b->pins[3].mmap.mem_sz = 0x1000;
457     b->pins[3].mmap.bit_pos = 6;
458 
459     strncpy(b->pins[4].name, "IO4", 8);
460     b->pins[4].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
461     b->pins[4].gpio.pinmap = 6;
462     b->pins[4].gpio.parent_id = 0;
463     b->pins[4].gpio.mux_total = 0;
464     b->pins[4].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
465     b->pins[4].gpio.output_enable = 36;
466     b->pins[4].gpio.pullup_enable = 37;
467 
468     strncpy(b->pins[5].name, "IO5", 8);
469     b->pins[5].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
470     b->pins[5].gpio.pinmap = 0;
471     b->pins[5].gpio.parent_id = 0;
472     b->pins[5].gpio.mux_total = 1;
473     b->pins[5].gpio.mux[0].pin = 66;
474     b->pins[5].gpio.mux[0].value = 0;
475     b->pins[5].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
476     b->pins[5].gpio.output_enable = 18;
477     b->pins[5].gpio.pullup_enable = 19;
478     b->pins[5].pwm.pinmap = 3;
479     b->pins[5].pwm.parent_id = 0;
480     b->pins[5].pwm.mux_total = 2;
481     b->pins[5].pwm.mux[0].pin = 66;
482     b->pins[5].pwm.mux[0].value = 1;
483     b->pins[5].pwm.mux[1].pin = 18;
484     b->pins[5].pwm.mux[1].value = 0;
485 
486     strncpy(b->pins[6].name, "IO6", 8);
487     b->pins[6].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
488     b->pins[6].gpio.pinmap = 1;
489     b->pins[6].gpio.parent_id = 0;
490     b->pins[6].gpio.mux_total = 1;
491     b->pins[6].gpio.mux[0].pin = 68;
492     b->pins[6].gpio.mux[0].value = 0;
493     b->pins[6].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
494     b->pins[6].gpio.output_enable = 20;
495     b->pins[6].gpio.pullup_enable = 21;
496     b->pins[6].pwm.pinmap = 5;
497     b->pins[6].pwm.parent_id = 0;
498     b->pins[6].pwm.mux_total = 2;
499     b->pins[6].pwm.mux[0].pin = 68;
500     b->pins[6].pwm.mux[0].value = 1;
501     b->pins[6].pwm.mux[1].pin = 20;
502     b->pins[6].pwm.mux[1].value = 0;
503 
504     strncpy(b->pins[7].name, "IO7", 8);
505     b->pins[7].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
506     b->pins[7].gpio.pinmap = 38;
507     b->pins[7].gpio.parent_id = 0;
508     b->pins[7].gpio.mux_total = 0;
509     b->pins[7].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
510     b->pins[7].gpio.pullup_enable = 39;
511 
512     strncpy(b->pins[8].name, "IO8", 8);
513     b->pins[8].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
514     b->pins[8].gpio.pinmap = 40;
515     b->pins[8].gpio.parent_id = 0;
516     b->pins[8].gpio.mux_total = 0;
517     b->pins[8].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
518     b->pins[8].gpio.pullup_enable = 41;
519 
520     strncpy(b->pins[9].name, "IO9", 8);
521     b->pins[9].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
522     b->pins[9].gpio.pinmap = 4;
523     b->pins[9].gpio.parent_id = 0;
524     b->pins[9].gpio.mux_total = 1;
525     b->pins[9].gpio.mux[0].pin = 70;
526     b->pins[9].gpio.mux[0].value = 0;
527     b->pins[9].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
528     b->pins[9].gpio.output_enable = 22;
529     b->pins[9].gpio.pullup_enable = 23;
530     b->pins[9].pwm.pinmap = 7;
531     b->pins[9].pwm.parent_id = 0;
532     b->pins[9].pwm.mux_total = 2;
533     b->pins[9].pwm.mux[0].pin = 70;
534     b->pins[9].pwm.mux[0].value = 1;
535     b->pins[9].pwm.mux[1].pin = 22;
536     b->pins[9].pwm.mux[1].value = 0;
537 
538     strncpy(b->pins[10].name, "IO10", 8);
539     b->pins[10].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 1, 1, 0, 0 };
540     b->pins[10].gpio.pinmap = 10;
541     b->pins[10].gpio.parent_id = 0;
542     b->pins[10].gpio.mux_total = 1;
543     b->pins[10].gpio.mux[0].pin = 74;
544     b->pins[10].gpio.mux[0].value = 0;
545     b->pins[10].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
546     b->pins[10].gpio.output_enable = 26;
547     b->pins[10].gpio.pullup_enable = 27;
548     b->pins[10].pwm.pinmap = 11;
549     b->pins[10].pwm.parent_id = 0;
550     b->pins[10].pwm.mux_total = 2;
551     b->pins[10].pwm.mux[0].pin = 74;
552     b->pins[10].pwm.mux[0].value = 1;
553     b->pins[10].pwm.mux[1].pin = 26;
554     b->pins[10].pwm.mux[1].value = 0;
555     b->pins[10].mmap.gpio.pinmap = 10;
556     strncpy(b->pins[10].mmap.mem_dev, "/dev/uio0", 12);
557     b->pins[10].mmap.gpio.mux_total = 3;
558     b->pins[10].mmap.gpio.mux[0].pin = 74;
559     b->pins[10].mmap.gpio.mux[0].value = 0;
560     b->pins[10].mmap.gpio.mux[1].pin = 26;
561     b->pins[10].mmap.gpio.mux[1].value = 0;
562     b->pins[10].mmap.gpio.mux[2].pin = 10;
563     b->pins[10].mmap.gpio.mux[2].value = 0;
564     b->pins[10].mmap.mem_sz = 0x1000;
565     b->pins[10].mmap.bit_pos = 2;
566     b->pins[10].spi.parent_id = 1;
567     b->pins[10].spi.mux_total = 1;
568     b->pins[10].spi.mux[0].pin = 74;
569     b->pins[10].spi.mux[0].value = 0;
570 
571     strncpy(b->pins[11].name, "IO11", 8);
572     b->pins[11].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 1, 0, 0 };
573     b->pins[11].gpio.pinmap = 5;
574     b->pins[11].gpio.parent_id = 0;
575     b->pins[11].gpio.mux_total = 2;
576     b->pins[11].gpio.mux[0].pin = 72;
577     b->pins[11].gpio.mux[0].value = 0;
578     b->pins[11].gpio.mux[1].pin = 44;
579     b->pins[11].gpio.mux[1].value = 0;
580     b->pins[11].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
581     b->pins[11].gpio.output_enable = 24;
582     b->pins[11].gpio.pullup_enable = 25;
583     b->pins[11].pwm.pinmap = 9;
584     b->pins[11].pwm.parent_id = 0;
585     b->pins[11].pwm.mux_total = 3;
586     b->pins[11].pwm.mux[0].pin = 72;
587     b->pins[11].pwm.mux[0].value = 1;
588     b->pins[11].pwm.mux[1].pin = 44;
589     b->pins[11].pwm.mux[1].value = 0;
590     b->pins[11].pwm.mux[2].pin = 24;
591     b->pins[11].pwm.mux[2].value = 0;
592     b->pins[11].spi.pinmap = 1;
593     b->pins[11].spi.mux_total = 3;
594     b->pins[11].spi.mux[0].pin = 72;
595     b->pins[11].spi.mux[0].value = 0;
596     b->pins[11].spi.mux[1].pin = 44;
597     b->pins[11].spi.mux[1].value = 1;
598     b->pins[11].spi.mux[2].pin = 24;
599     b->pins[11].spi.mux[2].value = 0;
600 
601     strncpy(b->pins[12].name, "IO12", 8);
602     b->pins[12].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 1, 1, 0, 0 };
603     b->pins[12].gpio.pinmap = 15;
604     b->pins[12].gpio.parent_id = 0;
605     b->pins[12].gpio.mux_total = 0;
606     b->pins[12].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
607     b->pins[12].gpio.output_enable = 42;
608     b->pins[12].gpio.pullup_enable = 43;
609     b->pins[12].spi.pinmap = 1;
610     b->pins[12].spi.mux_total = 1;
611     b->pins[12].spi.mux[0].pin = 42;
612     b->pins[12].spi.mux[0].value = 1;
613     b->pins[12].mmap.gpio.pinmap = 15;
614     strncpy(b->pins[12].mmap.mem_dev, "/dev/uio0", 12);
615     b->pins[12].mmap.gpio.mux_total = 2;
616     b->pins[12].mmap.gpio.mux[0].pin = 42;
617     b->pins[12].mmap.gpio.mux[0].value = 0;
618     b->pins[12].mmap.gpio.mux[1].pin = 15;
619     b->pins[12].mmap.gpio.mux[1].value = 0;
620     b->pins[12].mmap.mem_sz = 0x1000;
621     b->pins[12].mmap.bit_pos = 7;
622 
623     strncpy(b->pins[13].name, "IO13", 8);
624     b->pins[13].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0 };
625     b->pins[13].gpio.pinmap = 7;
626     b->pins[13].gpio.parent_id = 0;
627     b->pins[13].gpio.mux_total = 1;
628     b->pins[13].gpio.mux[0].pin = 46;
629     b->pins[13].gpio.mux[0].value = 0;
630     b->pins[13].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 1, 0, 1, 1 };
631     b->pins[13].gpio.output_enable = 30;
632     b->pins[13].gpio.pullup_enable = 31;
633     b->pins[13].spi.pinmap = 1;
634     b->pins[13].spi.mux_total = 2;
635     b->pins[13].spi.mux[0].pin = 46;
636     b->pins[13].spi.mux[0].value = 1;
637     b->pins[13].spi.mux[1].pin = 30;
638     b->pins[13].spi.mux[1].value = 0;
639 
640     // ANALOG
641     strncpy(b->pins[14].name, "A0", 8);
642     b->pins[14].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1 };
643     b->pins[14].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
644     b->pins[14].gpio.pullup_enable = 49;
645     b->pins[14].aio.pinmap = 0;
646     b->pins[14].aio.mux_total = 1;
647     b->pins[14].aio.mux[0].pin = 49;
648     b->pins[14].aio.mux[0].value = 1;
649     b->pins[14].gpio.pinmap = 48;
650     b->pins[14].gpio.mux_total = 0;
651 
652     strncpy(b->pins[15].name, "A1", 8);
653     b->pins[15].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1 };
654     b->pins[15].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
655     b->pins[15].gpio.pullup_enable = 51;
656     b->pins[15].aio.pinmap = 1;
657     b->pins[15].aio.mux[0].pin = 51;
658     b->pins[15].aio.mux[0].value = 1;
659     b->pins[15].aio.mux_total = 0;
660     b->pins[15].gpio.pinmap = 50;
661     b->pins[15].gpio.mux_total = 0;
662 
663     strncpy(b->pins[16].name, "A2", 8);
664     b->pins[16].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1 };
665     b->pins[16].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
666     b->pins[16].gpio.pullup_enable = 53;
667     b->pins[16].aio.pinmap = 2;
668     b->pins[16].aio.mux_total = 1;
669     b->pins[16].aio.mux[0].pin = 53;
670     b->pins[16].aio.mux[0].value = 1;
671     b->pins[16].gpio.pinmap = 52;
672     b->pins[16].gpio.mux_total = 0;
673 
674     strncpy(b->pins[17].name, "A3", 8);
675     b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1 };
676     b->pins[17].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
677     b->pins[17].gpio.pullup_enable = 55;
678     b->pins[17].aio.pinmap = 3;
679     b->pins[17].aio.mux_total = 1;
680     b->pins[17].aio.mux[0].pin = 55;
681     b->pins[17].aio.mux[0].value = 1;
682     b->pins[17].gpio.pinmap = 54;
683     b->pins[17].gpio.mux_total = 0;
684 
685     strncpy(b->pins[18].name, "A4", 8);
686     b->pins[18].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 1 };
687     b->pins[18].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
688     b->pins[18].gpio.pullup_enable = 57;
689     b->pins[18].i2c.pinmap = 1;
690     b->pins[18].i2c.mux_total = 1;
691     b->pins[18].i2c.mux[0].pin = 60;
692     b->pins[18].i2c.mux[0].value = 0;
693     b->pins[18].aio.pinmap = 4;
694     b->pins[18].aio.mux_total = 3;
695     b->pins[18].aio.mux[0].pin = 60;
696     b->pins[18].aio.mux[0].value = 1;
697     b->pins[18].aio.mux[1].pin = 78;
698     b->pins[18].aio.mux[1].value = 0;
699     b->pins[18].aio.mux[2].pin = 57;
700     b->pins[18].aio.mux[2].value = 0;
701     b->pins[18].gpio.pinmap = 56;
702     b->pins[18].gpio.mux_total = 2;
703     b->pins[18].gpio.mux[0].pin = 60;
704     b->pins[18].gpio.mux[0].value = 1;
705     b->pins[18].gpio.mux[1].pin = 78;
706     b->pins[18].gpio.mux[1].value = 1;
707 
708     strncpy(b->pins[19].name, "A5", 8);
709     b->pins[19].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 1 };
710     b->pins[19].gpio.complex_cap = (mraa_pin_cap_complex_t){ 1, 0, 0, 1, 1 };
711     b->pins[19].gpio.pullup_enable = 59;
712     b->pins[19].i2c.pinmap = 1;
713     b->pins[19].i2c.mux_total = 1;
714     b->pins[19].i2c.mux[0].pin = 60;
715     b->pins[19].i2c.mux[0].value = 0;
716     b->pins[19].aio.pinmap = 5;
717     b->pins[19].aio.mux_total = 3;
718     b->pins[19].aio.mux[0].pin = 60;
719     b->pins[19].aio.mux[0].value = 1;
720     b->pins[19].aio.mux[1].pin = 79;
721     b->pins[19].aio.mux[1].value = 0;
722     b->pins[19].aio.mux[2].pin = 59;
723     b->pins[19].aio.mux[2].value = 1;
724     b->pins[19].gpio.pinmap = 58;
725     b->pins[19].gpio.mux_total = 2;
726     b->pins[19].gpio.mux[0].pin = 60;
727     b->pins[19].gpio.mux[0].value = 1;
728     b->pins[19].gpio.mux[1].pin = 79;
729     b->pins[19].gpio.mux[1].value = 1;
730 
731     // BUS DEFINITIONS
732     b->i2c_bus_count = 1;
733     b->def_i2c_bus = 0;
734     b->i2c_bus[0].bus_id = 0;
735     b->i2c_bus[0].sda = 18;
736     b->i2c_bus[0].scl = 19;
737 
738     b->spi_bus_count = 1;
739     b->def_spi_bus = 0;
740     b->spi_bus[0].bus_id = 1;
741     b->spi_bus[0].slave_s = 0;
742     b->spi_bus[0].cs = 10;
743     b->spi_bus[0].mosi = 11;
744     b->spi_bus[0].miso = 12;
745     b->spi_bus[0].sclk = 13;
746 
747     b->uart_dev_count = 2;
748     b->def_uart_dev = 0;
749     b->uart_dev[0].rx = 0;
750     b->uart_dev[0].tx = 1;
751     b->uart_dev[0].device_path = "/dev/ttyS0";
752     b->uart_dev[1].rx = -1;
753     b->uart_dev[1].tx = -1;
754     b->uart_dev[1].device_path = "/dev/ttyS1";
755 
756     return b;
757 error:
758     syslog(LOG_CRIT, "galileo2: Platform failed to initialise");
759     free(b);
760     return NULL;
761 }
762