1 /*
2  * Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
3  *         Brendan Le Foll <brendan.le.foll@intel.com>
4  * Copyright (c) 2014-2016 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/stat.h>
29 #include <sys/mman.h>
30 #include <sys/ioctl.h>
31 #include <linux/spi/spidev.h>
32 
33 #include "common.h"
34 #include "x86/intel_edison_fab_c.h"
35 
36 #define PLATFORM_NAME "Intel Edison"
37 #define SYSFS_CLASS_GPIO "/sys/class/gpio"
38 #define DEBUGFS_PINMODE_PATH "/sys/kernel/debug/gpio_debug/gpio"
39 #define MAX_SIZE 64
40 #define MAX_MODE_SIZE 8
41 
42 // This is an absolute path to a resource file found within sysfs.
43 // Might not always be correct. First thing to check if mmap stops
44 // working. Check the device for 0x1199 and Intel Vendor (0x8086)
45 #define MMAP_PATH "/sys/devices/pci0000:00/0000:00:0c.0/resource0"
46 #define UART_DEV_PATH "/dev/ttyMFD1"
47 
48 typedef struct {
49     int sysfs;
50     int mode;
51 } mraa_intel_edision_pindef_t;
52 
53 typedef struct {
54     mraa_intel_edision_pindef_t gpio;
55     mraa_intel_edision_pindef_t pwm;
56     mraa_intel_edision_pindef_t i2c;
57     mraa_intel_edision_pindef_t spi;
58     mraa_intel_edision_pindef_t uart;
59 } mraa_intel_edison_pinmodes_t;
60 
61 static mraa_gpio_context tristate;
62 
63 static mraa_intel_edison_pinmodes_t pinmodes[MRAA_INTEL_EDISON_PINCOUNT];
64 static unsigned int outputen[] = { 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
65                                    258, 259, 260, 261, 232, 233, 234, 235, 236, 237 };
66 static mraa_gpio_context agpioOutputen[sizeof(outputen) / sizeof(outputen[0])];
67 
68 static unsigned int pullup_map[] = { 216, 217, 218, 219, 220, 221, 222, 223, 224, 225,
69                                      226, 227, 228, 229, 208, 209, 210, 211, 212, 213 };
70 static int miniboard = 0;
71 
72 // MMAP
73 static uint8_t* mmap_reg = NULL;
74 static int mmap_fd = 0;
75 static int mmap_size;
76 static unsigned int mmap_count = 0;
77 
78 mraa_result_t
mraa_intel_edison_spi_lsbmode_replace(mraa_spi_context dev,mraa_boolean_t lsb)79 mraa_intel_edison_spi_lsbmode_replace(mraa_spi_context dev, mraa_boolean_t lsb)
80 {
81     uint8_t lsb_mode = (uint8_t) lsb;
82 
83     // Edison doesn't support LSB_FIRST, we need to react appropriately
84     if (!lsb) {
85         if (ioctl(dev->devfd, SPI_IOC_WR_LSB_FIRST, &lsb_mode) < 0) {
86             syslog(LOG_ERR, "spi: Failed to set bit order");
87             return MRAA_ERROR_INVALID_RESOURCE;
88         }
89         if (ioctl(dev->devfd, SPI_IOC_RD_LSB_FIRST, &lsb_mode) < 0) {
90             syslog(LOG_ERR, "spi: Failed to set bit order");
91             return MRAA_ERROR_INVALID_RESOURCE;
92         }
93     } else {
94         return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
95     }
96 
97     dev->lsb = lsb;
98     return MRAA_SUCCESS;
99 }
100 
101 static mraa_result_t
mraa_intel_edison_pinmode_change(int sysfs,int mode)102 mraa_intel_edison_pinmode_change(int sysfs, int mode)
103 {
104     if (mode < 0) {
105         return MRAA_SUCCESS;
106     }
107 
108     char buffer[MAX_SIZE];
109     int useDebugFS = 0;
110 
111     mraa_gpio_context mode_gpio = mraa_gpio_init_raw(sysfs);
112     if (mode_gpio == NULL) {
113         return MRAA_ERROR_NO_RESOURCES;
114     }
115 
116     // first try SYSFS_CLASS_GPIO path
117     snprintf(buffer, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%i/pinmux", sysfs);
118     int modef = open(buffer, O_WRONLY);
119     if (modef == -1) {
120         snprintf(buffer, MAX_SIZE, DEBUGFS_PINMODE_PATH "%i/current_pinmux", sysfs);
121         modef = open(buffer, O_WRONLY);
122         useDebugFS = 1;
123     }
124 
125     if (modef == -1) {
126         syslog(LOG_ERR, "edison: Failed to open SoC pinmode for opening");
127         mraa_gpio_close(mode_gpio);
128         return MRAA_ERROR_INVALID_RESOURCE;
129     }
130 
131     mraa_result_t ret = MRAA_SUCCESS;
132     char mode_buf[MAX_MODE_SIZE];
133     int length = snprintf(mode_buf, MAX_MODE_SIZE, "%s%u", useDebugFS ? "mode" : "", mode);
134     if (write(modef, mode_buf, length * sizeof(char)) == -1) {
135         ret = MRAA_ERROR_INVALID_RESOURCE;
136     }
137     close(modef);
138     mraa_gpio_close(mode_gpio);
139 
140     return ret;
141 }
142 
143 mraa_result_t
mraa_intel_edison_gpio_dir_pre(mraa_gpio_context dev,mraa_gpio_dir_t dir)144 mraa_intel_edison_gpio_dir_pre(mraa_gpio_context dev, mraa_gpio_dir_t dir)
145 {
146 
147     if (dev->phy_pin >= 0) {
148         if (mraa_gpio_write(tristate, 0) != MRAA_SUCCESS) {
149             // call can sometimes fail, this does not actually mean much except
150             // that the kernel drivers don't always behave very well
151             syslog(LOG_NOTICE, "edison: Failed to write to tristate");
152         }
153         int pin = dev->phy_pin;
154 
155         if (!agpioOutputen[pin]) {
156             agpioOutputen[pin] = mraa_gpio_init_raw(outputen[pin]);
157             if (agpioOutputen[pin] == NULL) {
158                 return MRAA_ERROR_INVALID_RESOURCE;
159             }
160             if (mraa_gpio_dir(agpioOutputen[pin], MRAA_GPIO_OUT) != MRAA_SUCCESS) {
161                 return MRAA_ERROR_INVALID_RESOURCE;
162             }
163         }
164         int output_val = 0;
165         if (dir == MRAA_GPIO_OUT) {
166             output_val = 1;
167         }
168         if (mraa_gpio_write(agpioOutputen[pin], output_val) != MRAA_SUCCESS) {
169             return MRAA_ERROR_INVALID_RESOURCE;
170         }
171     }
172 
173     return MRAA_SUCCESS;
174 }
175 
176 mraa_result_t
mraa_intel_edison_gpio_dir_post(mraa_gpio_context dev,mraa_gpio_dir_t dir)177 mraa_intel_edison_gpio_dir_post(mraa_gpio_context dev, mraa_gpio_dir_t dir)
178 {
179     if (dev->phy_pin >= 0) {
180         return mraa_gpio_write(tristate, 1);
181     }
182     return MRAA_SUCCESS;
183 }
184 
185 mraa_result_t
mraa_intel_edison_gpio_init_post(mraa_gpio_context dev)186 mraa_intel_edison_gpio_init_post(mraa_gpio_context dev)
187 {
188     if (dev == NULL) {
189         return MRAA_ERROR_INVALID_RESOURCE;
190     }
191 
192     int sysfs, mode;
193     if (miniboard == 1) {
194         sysfs = dev->pin;
195         mode = 0;
196     } else {
197         sysfs = pinmodes[dev->phy_pin].gpio.sysfs;
198         mode = pinmodes[dev->phy_pin].gpio.mode;
199     }
200 
201     return mraa_intel_edison_pinmode_change(sysfs, mode);
202 }
203 
204 mraa_result_t
mraa_intel_edison_gpio_close_pre(mraa_gpio_context dev)205 mraa_intel_edison_gpio_close_pre(mraa_gpio_context dev)
206 {
207     if (dev->phy_pin >= 0) {
208         int pin = dev->phy_pin;
209         if (agpioOutputen[pin]) {
210             mraa_gpio_close(agpioOutputen[pin]);
211             agpioOutputen[pin] = NULL;
212         }
213     }
214     return MRAA_SUCCESS;
215 }
216 
217 mraa_result_t
mraa_intel_edison_i2c_init_pre(unsigned int bus)218 mraa_intel_edison_i2c_init_pre(unsigned int bus)
219 {
220     if (miniboard == 0) {
221         if (bus != 6) {
222             syslog(LOG_ERR, "edison: You can't use that bus, switching to bus 6");
223             bus = 6;
224         }
225         mraa_gpio_write(tristate, 0);
226         mraa_gpio_context io18_gpio = mraa_gpio_init_raw(14);
227         mraa_gpio_context io19_gpio = mraa_gpio_init_raw(165);
228         mraa_gpio_dir(io18_gpio, MRAA_GPIO_IN);
229         mraa_gpio_dir(io19_gpio, MRAA_GPIO_IN);
230         mraa_gpio_close(io18_gpio);
231         mraa_gpio_close(io19_gpio);
232 
233         mraa_gpio_context io18_enable = mraa_gpio_init_raw(236);
234         mraa_gpio_context io19_enable = mraa_gpio_init_raw(237);
235         mraa_gpio_dir(io18_enable, MRAA_GPIO_OUT);
236         mraa_gpio_dir(io19_enable, MRAA_GPIO_OUT);
237         mraa_gpio_write(io18_enable, 0);
238         mraa_gpio_write(io19_enable, 0);
239         mraa_gpio_close(io18_enable);
240         mraa_gpio_close(io19_enable);
241 
242         mraa_gpio_context io18_pullup = mraa_gpio_init_raw(212);
243         mraa_gpio_context io19_pullup = mraa_gpio_init_raw(213);
244         mraa_gpio_dir(io18_pullup, MRAA_GPIO_IN);
245         mraa_gpio_dir(io19_pullup, MRAA_GPIO_IN);
246         mraa_gpio_close(io18_pullup);
247         mraa_gpio_close(io19_pullup);
248 
249         mraa_intel_edison_pinmode_change(28, 1);
250         mraa_intel_edison_pinmode_change(27, 1);
251 
252         mraa_gpio_write(tristate, 1);
253     } else {
254         if (bus != 6 && bus != 1) {
255             syslog(LOG_ERR, "edison: You can't use that bus, switching to bus 6");
256             bus = 6;
257         }
258         int scl = plat->pins[plat->i2c_bus[bus].scl].gpio.pinmap;
259         int sda = plat->pins[plat->i2c_bus[bus].sda].gpio.pinmap;
260         mraa_intel_edison_pinmode_change(sda, 1);
261         mraa_intel_edison_pinmode_change(scl, 1);
262     }
263 
264     return MRAA_SUCCESS;
265 }
266 
267 static mraa_result_t
mraa_intel_edison_misc_spi()268 mraa_intel_edison_misc_spi()
269 {
270     // These arrays must have same length
271     static const int gpio_pin_list[] = {263, 240, 262, 241, 242, 243};
272     static int pin_num = sizeof(gpio_pin_list) / sizeof(int);
273     static const int gpio_val_list[] = {1, 0, 1, 0, 0, 0};
274     static const int gpio_dir_list[] = {MRAA_GPIO_OUT, MRAA_GPIO_OUT,
275                                         MRAA_GPIO_OUT, MRAA_GPIO_OUT,
276                                         MRAA_GPIO_OUT, MRAA_GPIO_OUT};
277     int i;
278     mraa_result_t ret;
279 
280     MRAA_RETURN_FOR_ERROR(mraa_gpio_write(tristate, 0));
281 
282     for (i = 0; i < pin_num; i++) {
283         mraa_gpio_context io = mraa_gpio_init_raw(gpio_pin_list[i]);
284         if (io != NULL) {
285             ret = mraa_gpio_dir(io, gpio_dir_list[i]);
286             if (ret == MRAA_SUCCESS) {
287                 ret = mraa_gpio_write(io, gpio_val_list[i]);
288             }
289 
290             //Don't care return value of close()
291             mraa_gpio_close(io);
292             MRAA_RETURN_FOR_ERROR(ret);
293         } else {
294           syslog(LOG_ERR, "edison: Failed to init raw gpio %d!",gpio_pin_list[i]);
295           return MRAA_ERROR_NO_RESOURCES;
296         }
297     }
298 
299     MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(115, 1));
300     MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(114, 1));
301     MRAA_RETURN_FOR_ERROR(mraa_intel_edison_pinmode_change(109, 1));
302     MRAA_RETURN_FOR_ERROR(mraa_gpio_write(tristate, 1));
303 
304     return MRAA_SUCCESS;
305 }
306 
307 mraa_result_t
mraa_intel_edison_aio_get_fp(mraa_aio_context dev)308 mraa_intel_edison_aio_get_fp(mraa_aio_context dev)
309 {
310     char file_path[64] = "";
311 
312     snprintf(file_path, 64, "/sys/bus/iio/devices/iio:device1/in_voltage%d_raw", dev->channel);
313 
314     dev->adc_in_fp = open(file_path, O_RDONLY);
315     if (dev->adc_in_fp == -1) {
316         syslog(LOG_ERR, "edison: Failed to open Analog input raw file %s for "
317                         "reading!",
318                file_path);
319         return MRAA_ERROR_INVALID_RESOURCE;
320     }
321 
322     return MRAA_SUCCESS;
323 }
324 
325 mraa_result_t
mraa_intel_edison_aio_init_pre(unsigned int aio)326 mraa_intel_edison_aio_init_pre(unsigned int aio)
327 {
328     if (aio > plat->aio_count) {
329         syslog(LOG_ERR, "edison: Invalid analog input channel");
330         return MRAA_ERROR_INVALID_RESOURCE;
331     }
332 
333     int pin = 14 + aio;
334     mraa_gpio_context output_e;
335     output_e = mraa_gpio_init_raw(outputen[pin]);
336     if (output_e == NULL) {
337         return MRAA_ERROR_INVALID_RESOURCE;
338     }
339     if (mraa_gpio_dir(output_e, MRAA_GPIO_OUT) != MRAA_SUCCESS) {
340         mraa_gpio_close(output_e);
341         return MRAA_ERROR_INVALID_RESOURCE;
342     }
343     if (mraa_gpio_write(output_e, 0) != MRAA_SUCCESS) {
344         mraa_gpio_close(output_e);
345         return MRAA_ERROR_INVALID_RESOURCE;
346     }
347     mraa_gpio_close(output_e);
348 
349     mraa_gpio_context pullup_pin;
350     pullup_pin = mraa_gpio_init_raw(pullup_map[pin]);
351     if (pullup_pin == NULL) {
352         return MRAA_ERROR_INVALID_RESOURCE;
353     }
354     if (mraa_gpio_dir(pullup_pin, MRAA_GPIO_IN) != MRAA_SUCCESS) {
355         mraa_gpio_close(pullup_pin);
356         return MRAA_ERROR_INVALID_RESOURCE;
357     }
358     mraa_gpio_close(pullup_pin);
359 
360     return MRAA_SUCCESS;
361 }
362 
363 mraa_result_t
mraa_intel_edison_aio_init_post(mraa_aio_context dev)364 mraa_intel_edison_aio_init_post(mraa_aio_context dev)
365 {
366     return mraa_gpio_write(tristate, 1);
367 }
368 
369 mraa_result_t
mraa_intel_edison_pwm_init_pre(int pin)370 mraa_intel_edison_pwm_init_pre(int pin)
371 {
372     if (miniboard == 1) {
373         return mraa_intel_edison_pinmode_change(plat->pins[pin].gpio.pinmap, 1);
374     }
375     if (pin < 0 || pin > 19) {
376         return MRAA_ERROR_INVALID_RESOURCE;
377     }
378 
379     if (!plat->pins[pin].capabilites.pwm) {
380         return MRAA_ERROR_INVALID_RESOURCE;
381     }
382 
383     mraa_gpio_context output_e;
384     output_e = mraa_gpio_init_raw(outputen[pin]);
385     if (output_e == NULL) {
386         return MRAA_ERROR_INVALID_RESOURCE;
387     }
388     if (mraa_gpio_dir(output_e, MRAA_GPIO_OUT) != MRAA_SUCCESS) {
389         mraa_gpio_close(output_e);
390         return MRAA_ERROR_INVALID_RESOURCE;
391     }
392     if (mraa_gpio_write(output_e, 1) != MRAA_SUCCESS) {
393         mraa_gpio_close(output_e);
394         return MRAA_ERROR_INVALID_RESOURCE;
395     }
396     mraa_gpio_close(output_e);
397 
398     mraa_gpio_context pullup_pin;
399     pullup_pin = mraa_gpio_init_raw(pullup_map[pin]);
400     if (pullup_pin == NULL) {
401         return MRAA_ERROR_INVALID_RESOURCE;
402     }
403     if (mraa_gpio_dir(pullup_pin, MRAA_GPIO_IN) != MRAA_SUCCESS) {
404         mraa_gpio_close(pullup_pin);
405         return MRAA_ERROR_INVALID_RESOURCE;
406     }
407     mraa_gpio_close(pullup_pin);
408     mraa_intel_edison_pinmode_change(plat->pins[pin].gpio.pinmap, 1);
409 
410     return MRAA_SUCCESS;
411 }
412 
413 mraa_result_t
mraa_intel_edison_pwm_init_post(mraa_pwm_context pwm)414 mraa_intel_edison_pwm_init_post(mraa_pwm_context pwm)
415 {
416     return mraa_gpio_write(tristate, 1);
417 }
418 
419 mraa_result_t
mraa_intel_edison_spi_init_pre(int bus)420 mraa_intel_edison_spi_init_pre(int bus)
421 {
422     if (miniboard == 1) {
423         mraa_intel_edison_pinmode_change(115, 1);
424         mraa_intel_edison_pinmode_change(114, 1);
425         mraa_intel_edison_pinmode_change(109, 1);
426         return MRAA_SUCCESS;
427     }
428     mraa_gpio_write(tristate, 0);
429 
430     mraa_gpio_context io10_out = mraa_gpio_init_raw(258);
431     mraa_gpio_context io11_out = mraa_gpio_init_raw(259);
432     mraa_gpio_context io12_out = mraa_gpio_init_raw(260);
433     mraa_gpio_context io13_out = mraa_gpio_init_raw(261);
434     mraa_gpio_dir(io10_out, MRAA_GPIO_OUT);
435     mraa_gpio_dir(io11_out, MRAA_GPIO_OUT);
436     mraa_gpio_dir(io12_out, MRAA_GPIO_OUT);
437     mraa_gpio_dir(io13_out, MRAA_GPIO_OUT);
438 
439     mraa_gpio_write(io10_out, 1);
440     mraa_gpio_write(io11_out, 1);
441     mraa_gpio_write(io12_out, 0);
442     mraa_gpio_write(io13_out, 1);
443 
444     mraa_gpio_close(io10_out);
445     mraa_gpio_close(io11_out);
446     mraa_gpio_close(io12_out);
447     mraa_gpio_close(io13_out);
448 
449     mraa_gpio_context io10_pull = mraa_gpio_init_raw(226);
450     mraa_gpio_context io11_pull = mraa_gpio_init_raw(227);
451     mraa_gpio_context io12_pull = mraa_gpio_init_raw(228);
452     mraa_gpio_context io13_pull = mraa_gpio_init_raw(229);
453 
454     mraa_gpio_dir(io10_pull, MRAA_GPIO_IN);
455     mraa_gpio_dir(io11_pull, MRAA_GPIO_IN);
456     mraa_gpio_dir(io12_pull, MRAA_GPIO_IN);
457     mraa_gpio_dir(io13_pull, MRAA_GPIO_IN);
458 
459     mraa_gpio_close(io10_pull);
460     mraa_gpio_close(io11_pull);
461     mraa_gpio_close(io12_pull);
462     mraa_gpio_close(io13_pull);
463 
464     return MRAA_SUCCESS;
465 }
466 
467 mraa_result_t
mraa_intel_edison_spi_init_post(mraa_spi_context spi)468 mraa_intel_edison_spi_init_post(mraa_spi_context spi)
469 {
470     return mraa_gpio_write(tristate, 1);
471 }
472 
473 mraa_result_t
mraa_intel_edison_gpio_mode_replace(mraa_gpio_context dev,mraa_gpio_mode_t mode)474 mraa_intel_edison_gpio_mode_replace(mraa_gpio_context dev, mraa_gpio_mode_t mode)
475 {
476     if (dev->value_fp != -1) {
477         if (close(dev->value_fp) != 0) {
478             return MRAA_ERROR_INVALID_RESOURCE;
479         }
480         dev->value_fp = -1;
481     }
482 
483     mraa_gpio_context pullup_e;
484     pullup_e = mraa_gpio_init_raw(pullup_map[dev->phy_pin]);
485     if (pullup_e == NULL) {
486         return MRAA_ERROR_INVALID_RESOURCE;
487     }
488     if (mraa_gpio_dir(pullup_e, MRAA_GPIO_IN) != MRAA_SUCCESS) {
489         syslog(LOG_ERR, "edison: Failed to set gpio mode-pullup");
490         mraa_gpio_close(pullup_e);
491         return MRAA_ERROR_INVALID_RESOURCE;
492     }
493 
494     int value = -1;
495     switch (mode) {
496         case MRAA_GPIO_STRONG:
497             break;
498         case MRAA_GPIO_PULLUP:
499             value = 1;
500             break;
501         case MRAA_GPIO_PULLDOWN:
502             value = 0;
503             break;
504         case MRAA_GPIO_HIZ:
505             return MRAA_SUCCESS;
506             break;
507         default:
508             return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED;
509     }
510     if (value != -1) {
511         if (mraa_gpio_dir(pullup_e, MRAA_GPIO_OUT) != MRAA_SUCCESS) {
512             syslog(LOG_ERR, "edison: Error setting pullup");
513             mraa_gpio_close(pullup_e);
514             return MRAA_ERROR_INVALID_RESOURCE;
515         }
516         if (mraa_gpio_write(pullup_e, value) != MRAA_SUCCESS) {
517             syslog(LOG_ERR, "edison: Error setting pullup");
518             mraa_gpio_close(pullup_e);
519             return MRAA_ERROR_INVALID_RESOURCE;
520         }
521     }
522 
523     return mraa_gpio_close(pullup_e);
524 }
525 
526 mraa_result_t
mraa_intel_edsion_mb_gpio_mode(mraa_gpio_context dev,mraa_gpio_mode_t mode)527 mraa_intel_edsion_mb_gpio_mode(mraa_gpio_context dev, mraa_gpio_mode_t mode)
528 {
529     if (dev->value_fp != -1) {
530         if (close(dev->value_fp) != 0) {
531             return MRAA_ERROR_INVALID_RESOURCE;
532         }
533         dev->value_fp = -1;
534     }
535 
536     char filepath[MAX_SIZE];
537 
538     mraa_gpio_context mode_gpio = mraa_gpio_init_raw(dev->pin);
539     if (mode_gpio == NULL) {
540         return MRAA_ERROR_NO_RESOURCES;
541     }
542 
543     // first try SYSFS_CLASS_GPIO path
544     snprintf(filepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/pullmode", dev->pin);
545     int drive = open(filepath, O_WRONLY);
546 
547     if (drive == -1) {
548         snprintf(filepath, MAX_SIZE, DEBUGFS_PINMODE_PATH "%d/current_pullmode", dev->pin);
549         drive = open(filepath, O_WRONLY);
550     }
551 
552     if (drive == -1) {
553         syslog(LOG_ERR, "edison: Failed to open drive for writing");
554         mraa_gpio_close(mode_gpio);
555         return MRAA_ERROR_INVALID_RESOURCE;
556     }
557 
558     char bu[MAX_SIZE];
559     int length;
560     switch (mode) {
561         case MRAA_GPIO_STRONG:
562             mraa_gpio_close(mode_gpio);
563             close(drive);
564             return MRAA_SUCCESS;
565         case MRAA_GPIO_PULLUP:
566             length = snprintf(bu, sizeof(bu), "pullup");
567             break;
568         case MRAA_GPIO_PULLDOWN:
569             length = snprintf(bu, sizeof(bu), "pulldown");
570             break;
571         case MRAA_GPIO_HIZ:
572             length = snprintf(bu, sizeof(bu), "nopull");
573             break;
574         default:
575             mraa_gpio_close(mode_gpio);
576             close(drive);
577             return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED;
578     }
579     if (write(drive, bu, length * sizeof(char)) == -1) {
580         syslog(LOG_ERR, "edison: Failed to write to drive mode");
581         mraa_gpio_close(mode_gpio);
582         close(drive);
583         return MRAA_ERROR_INVALID_RESOURCE;
584     }
585 
586     mraa_gpio_close(mode_gpio);
587     if (close(drive) != 0) {
588         return MRAA_ERROR_INVALID_RESOURCE;
589     }
590     return MRAA_SUCCESS;
591 }
592 
593 mraa_result_t
mraa_intel_edison_uart_init_pre(int index)594 mraa_intel_edison_uart_init_pre(int index)
595 {
596     if (index != 0) {
597         syslog(LOG_ERR, "edison: Failed to write to drive mode");
598         return MRAA_ERROR_INVALID_RESOURCE;
599     }
600     if (miniboard == 0) {
601         mraa_gpio_write(tristate, 0);
602         mraa_gpio_context io0_output = mraa_gpio_init_raw(248);
603         mraa_gpio_context io0_pullup = mraa_gpio_init_raw(216);
604         mraa_gpio_context io1_output = mraa_gpio_init_raw(249);
605         mraa_gpio_context io1_pullup = mraa_gpio_init_raw(217);
606         mraa_gpio_dir(io0_output, MRAA_GPIO_OUT);
607         mraa_gpio_dir(io0_pullup, MRAA_GPIO_OUT);
608         mraa_gpio_dir(io1_output, MRAA_GPIO_OUT);
609         mraa_gpio_dir(io1_pullup, MRAA_GPIO_IN);
610 
611         mraa_gpio_write(io0_output, 0);
612         mraa_gpio_write(io0_pullup, 0);
613         mraa_gpio_write(io1_output, 1);
614 
615         mraa_gpio_close(io0_output);
616         mraa_gpio_close(io0_pullup);
617         mraa_gpio_close(io1_output);
618         mraa_gpio_close(io1_pullup);
619     }
620     mraa_result_t ret;
621     ret = mraa_intel_edison_pinmode_change(130, 1); // IO0 RX
622     ret = mraa_intel_edison_pinmode_change(131, 1); // IO1 TX
623     return ret;
624 }
625 
626 mraa_result_t
mraa_intel_edison_uart_init_post(mraa_uart_context uart)627 mraa_intel_edison_uart_init_post(mraa_uart_context uart)
628 {
629     return mraa_gpio_write(tristate, 1);
630 }
631 
632 static mraa_result_t
mraa_intel_edsion_mmap_unsetup()633 mraa_intel_edsion_mmap_unsetup()
634 {
635     if (mmap_reg == NULL) {
636         syslog(LOG_ERR, "edison mmap: null register cant unsetup");
637         return MRAA_ERROR_INVALID_RESOURCE;
638     }
639     munmap(mmap_reg, mmap_size);
640     mmap_reg = NULL;
641     if (close(mmap_fd) != 0) {
642         return MRAA_ERROR_INVALID_RESOURCE;
643     }
644     return MRAA_SUCCESS;
645 }
646 
647 mraa_result_t
mraa_intel_edison_mmap_write(mraa_gpio_context dev,int value)648 mraa_intel_edison_mmap_write(mraa_gpio_context dev, int value)
649 {
650     uint8_t offset = ((dev->pin / 32) * sizeof(uint32_t));
651     uint8_t valoff;
652 
653     if (value) {
654         valoff = 0x34;
655     } else {
656         valoff = 0x4c;
657     }
658 
659     *(volatile uint32_t*) (mmap_reg + offset + valoff) = (uint32_t)(1 << (dev->pin % 32));
660 
661     return MRAA_SUCCESS;
662 }
663 
664 int
mraa_intel_edison_mmap_read(mraa_gpio_context dev)665 mraa_intel_edison_mmap_read(mraa_gpio_context dev)
666 {
667     uint8_t offset = ((dev->pin / 32) * sizeof(uint32_t));
668     uint32_t value;
669 
670     value = *(volatile uint32_t*) (mmap_reg + 0x04 + offset);
671     if (value & (uint32_t)(1 << (dev->pin % 32))) {
672         return 1;
673     }
674     return 0;
675 }
676 
677 mraa_result_t
mraa_intel_edison_mmap_setup(mraa_gpio_context dev,mraa_boolean_t en)678 mraa_intel_edison_mmap_setup(mraa_gpio_context dev, mraa_boolean_t en)
679 {
680     if (dev == NULL) {
681         syslog(LOG_ERR, "edison mmap: context not valid");
682         return MRAA_ERROR_INVALID_HANDLE;
683     }
684 
685     if (en == 0) {
686         if (dev->mmap_write == NULL && dev->mmap_read == NULL) {
687             syslog(LOG_ERR, "edison mmap: can't disable disabled mmap gpio");
688             return MRAA_ERROR_INVALID_PARAMETER;
689         }
690         dev->mmap_write = NULL;
691         dev->mmap_read = NULL;
692         mmap_count--;
693         if (mmap_count == 0) {
694             return mraa_intel_edsion_mmap_unsetup();
695         }
696         return MRAA_SUCCESS;
697     }
698 
699     if (dev->mmap_write != NULL && dev->mmap_read != NULL) {
700         syslog(LOG_ERR, "edison mmap: can't enable enabled mmap gpio");
701         return MRAA_ERROR_INVALID_PARAMETER;
702     }
703 
704     // Might need to make some elements of this thread safe.
705     // For example only allow one thread to enter the following block
706     // to prevent mmap'ing twice.
707     if (mmap_reg == NULL) {
708         if ((mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) {
709             syslog(LOG_ERR, "edison map: unable to open resource0 file");
710             return MRAA_ERROR_INVALID_HANDLE;
711         }
712 
713         struct stat fd_stat;
714         if (fstat(mmap_fd, &fd_stat) != 0) {
715             syslog(LOG_ERR, "edison map: unable to access resource0 file");
716             return MRAA_ERROR_INVALID_HANDLE;
717         }
718         mmap_size = fd_stat.st_size;
719 
720         mmap_reg =
721         (uint8_t*) mmap(NULL, fd_stat.st_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, mmap_fd, 0);
722         if (mmap_reg == MAP_FAILED) {
723             syslog(LOG_ERR, "edison mmap: failed to mmap");
724             mmap_reg = NULL;
725             close(mmap_fd);
726             return MRAA_ERROR_NO_RESOURCES;
727         }
728     }
729     dev->mmap_write = &mraa_intel_edison_mmap_write;
730     dev->mmap_read = &mraa_intel_edison_mmap_read;
731     mmap_count++;
732 
733     return MRAA_SUCCESS;
734 }
735 
736 mraa_result_t
mraa_intel_edison_i2c_freq(mraa_i2c_context dev,mraa_i2c_mode_t mode)737 mraa_intel_edison_i2c_freq(mraa_i2c_context dev, mraa_i2c_mode_t mode)
738 {
739     int sysnode = -1;
740 
741     switch (dev->busnum) {
742         case 1:
743             sysnode = open("/sys/devices/pci0000:00/0000:00:08.0/i2c_dw_sysnode/mode", O_RDWR);
744             break;
745         case 6:
746             sysnode = open("/sys/devices/pci0000:00/0000:00:09.1/i2c_dw_sysnode/mode", O_RDWR);
747             break;
748         default:
749             syslog(LOG_NOTICE, "i2c bus selected does not support frequency changes");
750             return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
751     }
752     if (sysnode == -1) {
753         return MRAA_ERROR_INVALID_RESOURCE;
754     }
755 
756     char bu[5];
757     int length;
758     switch (mode) {
759         case MRAA_I2C_STD:
760             length = snprintf(bu, sizeof(bu), "std");
761             break;
762         case MRAA_I2C_FAST:
763             length = snprintf(bu, sizeof(bu), "fast");
764             break;
765         case MRAA_I2C_HIGH:
766             length = snprintf(bu, sizeof(bu), "high");
767             break;
768         default:
769             syslog(LOG_ERR, "Invalid i2c mode selected");
770             close(sysnode);
771             return MRAA_ERROR_INVALID_PARAMETER;
772     }
773     if (write(sysnode, bu, length * sizeof(char)) == -1) {
774         close(sysnode);
775         return MRAA_ERROR_INVALID_RESOURCE;
776     }
777     close(sysnode);
778     return MRAA_SUCCESS;
779 }
780 
781 mraa_result_t
mraa_intel_edison_miniboard(mraa_board_t * b)782 mraa_intel_edison_miniboard(mraa_board_t* b)
783 {
784     miniboard = 1;
785     b->phy_pin_count = 56;
786     b->gpio_count = 56; // A bit of a hack I suppose
787     b->aio_count = 0;
788     b->pwm_default_period = 5000;
789     b->pwm_max_period = 218453;
790     b->pwm_min_period = 1;
791 
792     b->pins = (mraa_pininfo_t*) calloc(b->phy_pin_count, sizeof(mraa_pininfo_t));
793     if (b->pins == NULL) {
794         return MRAA_ERROR_UNSPECIFIED;
795     }
796 
797     b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
798     if (b->adv_func == NULL) {
799         free(b->pins);
800         return MRAA_ERROR_UNSPECIFIED;
801     }
802     b->adv_func->gpio_init_post = &mraa_intel_edison_gpio_init_post;
803     b->adv_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre;
804     b->adv_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre;
805     b->adv_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq;
806     b->adv_func->spi_init_pre = &mraa_intel_edison_spi_init_pre;
807     b->adv_func->gpio_mode_replace = &mraa_intel_edsion_mb_gpio_mode;
808     b->adv_func->uart_init_pre = &mraa_intel_edison_uart_init_pre;
809     b->adv_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup;
810 
811     int pos = 0;
812     strncpy(b->pins[pos].name, "J17-1", 8);
813     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
814     b->pins[pos].gpio.pinmap = 182;
815     b->pins[pos].gpio.mux_total = 0;
816     b->pins[pos].pwm.pinmap = 2;
817     b->pins[pos].pwm.parent_id = 0;
818     b->pins[pos].pwm.mux_total = 0;
819     pos++;
820 
821     strncpy(b->pins[pos].name, "J17-2", 8);
822     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
823     pos++;
824     strncpy(b->pins[pos].name, "J17-3", 8);
825     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
826     pos++;
827     strncpy(b->pins[pos].name, "J17-4", 8);
828     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
829     pos++;
830 
831     strncpy(b->pins[pos].name, "J17-5", 8);
832     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
833     b->pins[pos].gpio.pinmap = 135;
834     b->pins[pos].gpio.mux_total = 0;
835     pos++;
836 
837     strncpy(b->pins[pos].name, "J17-6", 8);
838     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
839     pos++;
840 
841     strncpy(b->pins[pos].name, "J17-7", 8);
842     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
843     b->pins[pos].gpio.pinmap = 27;
844     b->pins[pos].gpio.mux_total = 0;
845     b->pins[pos].i2c.pinmap = 1;
846     b->pins[pos].i2c.mux_total = 0;
847     pos++;
848 
849     strncpy(b->pins[pos].name, "J17-8", 8);
850     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
851     b->pins[pos].gpio.pinmap = 20;
852     b->pins[pos].gpio.mux_total = 0;
853     b->pins[pos].i2c.pinmap = 1;
854     b->pins[pos].i2c.mux_total = 0;
855     pos++;
856 
857     strncpy(b->pins[pos].name, "J17-9", 8);
858     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
859     b->pins[pos].gpio.pinmap = 28;
860     b->pins[pos].gpio.mux_total = 0;
861     b->pins[pos].i2c.pinmap = 1;
862     b->pins[pos].i2c.mux_total = 0;
863     pos++;
864 
865     strncpy(b->pins[pos].name, "J17-10", 8);
866     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
867     b->pins[pos].gpio.pinmap = 111;
868     b->pins[pos].gpio.mux_total = 0;
869     b->pins[pos].spi.pinmap = 5;
870     b->pins[pos].spi.mux_total = 0;
871     pos++;
872 
873     strncpy(b->pins[pos].name, "J17-11", 8);
874     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
875     b->pins[pos].gpio.pinmap = 109;
876     b->pins[pos].gpio.mux_total = 0;
877     b->pins[pos].spi.pinmap = 5;
878     b->pins[pos].spi.mux_total = 0;
879     pos++;
880 
881     strncpy(b->pins[pos].name, "J17-12", 8);
882     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
883     b->pins[pos].gpio.pinmap = 115;
884     b->pins[pos].gpio.mux_total = 0;
885     b->pins[pos].spi.pinmap = 5;
886     b->pins[pos].spi.mux_total = 0;
887     pos++;
888     strncpy(b->pins[pos].name, "J17-13", 8);
889     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
890     pos++;
891 
892     strncpy(b->pins[pos].name, "J17-14", 8);
893     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
894     b->pins[pos].gpio.pinmap = 128;
895     b->pins[pos].gpio.parent_id = 0;
896     b->pins[pos].gpio.mux_total = 0;
897     pos++;
898 
899     strncpy(b->pins[pos].name, "J18-1", 8);
900     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
901     b->pins[pos].gpio.pinmap = 13;
902     b->pins[pos].gpio.mux_total = 0;
903     b->pins[pos].pwm.pinmap = 1;
904     b->pins[pos].pwm.parent_id = 0;
905     b->pins[pos].pwm.mux_total = 0;
906     pos++;
907 
908     strncpy(b->pins[pos].name, "J18-2", 8);
909     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
910     b->pins[pos].gpio.pinmap = 165;
911     b->pins[pos].gpio.mux_total = 0;
912     pos++;
913     strncpy(b->pins[pos].name, "J18-3", 8);
914     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
915     pos++;
916     strncpy(b->pins[pos].name, "J18-4", 8);
917     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
918     pos++;
919     strncpy(b->pins[pos].name, "J18-5", 8);
920     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
921     pos++;
922 
923     strncpy(b->pins[pos].name, "J18-6", 8);
924     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
925     b->pins[pos].gpio.pinmap = 19;
926     b->pins[pos].gpio.mux_total = 0;
927     b->pins[pos].i2c.pinmap = 1;
928     b->pins[pos].i2c.mux_total = 0;
929     pos++;
930 
931     strncpy(b->pins[pos].name, "J18-7", 8);
932     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
933     b->pins[pos].gpio.pinmap = 12;
934     b->pins[pos].gpio.mux_total = 0;
935     b->pins[pos].pwm.pinmap = 0;
936     b->pins[pos].pwm.parent_id = 0;
937     b->pins[pos].pwm.mux_total = 0;
938     pos++;
939 
940     strncpy(b->pins[pos].name, "J18-8", 8);
941     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
942     b->pins[pos].gpio.pinmap = 183;
943     b->pins[pos].gpio.mux_total = 0;
944     b->pins[pos].pwm.pinmap = 3;
945     b->pins[pos].pwm.parent_id = 0;
946     b->pins[pos].pwm.mux_total = 0;
947     pos++;
948     strncpy(b->pins[pos].name, "J18-9", 8);
949     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
950     pos++;
951 
952     strncpy(b->pins[pos].name, "J18-10", 8);
953     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
954     b->pins[pos].gpio.pinmap = 110;
955     b->pins[pos].gpio.mux_total = 0;
956     b->pins[pos].spi.pinmap = 5;
957     b->pins[pos].spi.mux_total = 0;
958     pos++;
959     strncpy(b->pins[pos].name, "J18-11", 8);
960     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
961     b->pins[pos].gpio.pinmap = 114;
962     b->pins[pos].gpio.mux_total = 0;
963     b->pins[pos].spi.pinmap = 5;
964     b->pins[pos].spi.mux_total = 0;
965     pos++;
966 
967     strncpy(b->pins[pos].name, "J18-12", 8);
968     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
969     b->pins[pos].gpio.pinmap = 129;
970     b->pins[pos].gpio.mux_total = 0;
971     pos++;
972     strncpy(b->pins[pos].name, "J18-13", 8);
973     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
974     b->pins[pos].gpio.pinmap = 130;
975     b->pins[pos].gpio.mux_total = 0;
976     b->pins[pos].uart.pinmap = 0;
977     b->pins[pos].uart.parent_id = 0;
978     b->pins[pos].uart.mux_total = 0;
979 
980     pos++;
981     strncpy(b->pins[pos].name, "J18-14", 8);
982     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
983     pos++;
984 
985     strncpy(b->pins[pos].name, "J19-1", 8);
986     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
987     pos++;
988     strncpy(b->pins[pos].name, "J19-2", 8);
989     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
990     pos++;
991     strncpy(b->pins[pos].name, "J19-3", 8);
992     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
993     pos++;
994 
995     strncpy(b->pins[pos].name, "J19-4", 8);
996     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
997     b->pins[pos].gpio.pinmap = 44;
998     b->pins[pos].gpio.mux_total = 0;
999     pos++;
1000     strncpy(b->pins[pos].name, "J19-5", 8);
1001     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1002     b->pins[pos].gpio.pinmap = 46;
1003     b->pins[pos].gpio.mux_total = 0;
1004     pos++;
1005     strncpy(b->pins[pos].name, "J19-6", 8);
1006     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1007     b->pins[pos].gpio.pinmap = 48;
1008     b->pins[pos].gpio.mux_total = 0;
1009     pos++;
1010 
1011     strncpy(b->pins[pos].name, "J19-7", 8);
1012     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
1013     pos++;
1014 
1015     strncpy(b->pins[pos].name, "J19-8", 8);
1016     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
1017     b->pins[pos].gpio.pinmap = 131;
1018     b->pins[pos].gpio.mux_total = 0;
1019     b->pins[pos].uart.pinmap = 0;
1020     b->pins[pos].uart.parent_id = 0;
1021     b->pins[pos].uart.mux_total = 0;
1022     pos++;
1023 
1024     strncpy(b->pins[pos].name, "J19-9", 8);
1025     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1026     b->pins[pos].gpio.pinmap = 14;
1027     b->pins[pos].gpio.mux_total = 0;
1028     pos++;
1029 
1030     strncpy(b->pins[pos].name, "J19-10", 8);
1031     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1032     b->pins[pos].gpio.pinmap = 40;
1033     b->pins[pos].gpio.mux_total = 0;
1034     pos++;
1035     strncpy(b->pins[pos].name, "J19-11", 8);
1036     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1037     b->pins[pos].gpio.pinmap = 43;
1038     b->pins[pos].gpio.mux_total = 0;
1039     pos++;
1040     strncpy(b->pins[pos].name, "J19-12", 8);
1041     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1042     b->pins[pos].gpio.pinmap = 77;
1043     b->pins[pos].gpio.mux_total = 0;
1044     pos++;
1045     strncpy(b->pins[pos].name, "J19-13", 8);
1046     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1047     b->pins[pos].gpio.pinmap = 82;
1048     b->pins[pos].gpio.mux_total = 0;
1049     pos++;
1050     strncpy(b->pins[pos].name, "J19-14", 8);
1051     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1052     b->pins[pos].gpio.pinmap = 83;
1053     b->pins[pos].gpio.mux_total = 0;
1054     pos++;
1055 
1056     strncpy(b->pins[pos].name, "J20-1", 8);
1057     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
1058     pos++;
1059     strncpy(b->pins[pos].name, "J20-2", 8);
1060     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
1061     pos++;
1062     strncpy(b->pins[pos].name, "J20-3", 8);
1063     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 0 };
1064     pos++;
1065     strncpy(b->pins[pos].name, "J20-4", 8);
1066     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1067     b->pins[pos].gpio.pinmap = 45;
1068     b->pins[pos].gpio.mux_total = 0;
1069     pos++;
1070     strncpy(b->pins[pos].name, "J20-5", 8);
1071     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1072     b->pins[pos].gpio.pinmap = 47;
1073     b->pins[pos].gpio.mux_total = 0;
1074     pos++;
1075     strncpy(b->pins[pos].name, "J20-6", 8);
1076     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1077     b->pins[pos].gpio.pinmap = 49;
1078     b->pins[pos].gpio.mux_total = 0;
1079     pos++;
1080     strncpy(b->pins[pos].name, "J20-7", 8);
1081     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1082     b->pins[pos].gpio.pinmap = 15;
1083     b->pins[pos].gpio.mux_total = 0;
1084     pos++;
1085     strncpy(b->pins[pos].name, "J20-8", 8);
1086     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1087     b->pins[pos].gpio.pinmap = 84;
1088     b->pins[pos].gpio.mux_total = 0;
1089     pos++;
1090     strncpy(b->pins[pos].name, "J20-9", 8);
1091     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1092     b->pins[pos].gpio.pinmap = 42;
1093     b->pins[pos].gpio.mux_total = 0;
1094     pos++;
1095     strncpy(b->pins[pos].name, "J20-10", 8);
1096     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1097     b->pins[pos].gpio.pinmap = 41;
1098     b->pins[pos].gpio.mux_total = 0;
1099     pos++;
1100     strncpy(b->pins[pos].name, "J20-11", 8);
1101     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1102     b->pins[pos].gpio.pinmap = 78;
1103     b->pins[pos].gpio.mux_total = 0;
1104     pos++;
1105     strncpy(b->pins[pos].name, "J20-12", 8);
1106     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1107     b->pins[pos].gpio.pinmap = 79;
1108     b->pins[pos].gpio.mux_total = 0;
1109     pos++;
1110     strncpy(b->pins[pos].name, "J20-13", 8);
1111     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1112     b->pins[pos].gpio.pinmap = 80;
1113     b->pins[pos].gpio.mux_total = 0;
1114     pos++;
1115     strncpy(b->pins[pos].name, "J20-14", 8);
1116     b->pins[pos].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
1117     b->pins[pos].gpio.pinmap = 81;
1118     b->pins[pos].gpio.mux_total = 0;
1119     pos++;
1120 
1121     // BUS DEFINITIONS
1122     b->i2c_bus_count = 9;
1123     b->def_i2c_bus = 1;
1124     int ici;
1125     for (ici = 0; ici < 9; ici++) {
1126         b->i2c_bus[ici].bus_id = -1;
1127     }
1128     b->i2c_bus[1].bus_id = 1;
1129     b->i2c_bus[1].sda = 7;
1130     b->i2c_bus[1].scl = 19;
1131 
1132     b->i2c_bus[6].bus_id = 6;
1133     b->i2c_bus[6].sda = 8;
1134     b->i2c_bus[6].scl = 6;
1135 
1136     b->spi_bus_count = 1;
1137     b->def_spi_bus = 0;
1138     b->spi_bus[0].bus_id = 5;
1139     b->spi_bus[0].slave_s = 1;
1140     b->spi_bus[0].cs = 23;
1141     b->spi_bus[0].mosi = 11;
1142     b->spi_bus[0].miso = 24;
1143     b->spi_bus[0].sclk = 10;
1144 
1145     b->uart_dev_count = 1;
1146     b->def_uart_dev = 0;
1147     b->uart_dev[0].rx = 26;
1148     b->uart_dev[0].tx = 35;
1149     b->uart_dev[0].device_path = UART_DEV_PATH;
1150 
1151     return MRAA_SUCCESS;
1152 }
1153 
1154 mraa_board_t*
mraa_intel_edison_fab_c()1155 mraa_intel_edison_fab_c()
1156 {
1157     mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t));
1158     if (b == NULL) {
1159         return NULL;
1160     }
1161 
1162     b->platform_name = PLATFORM_NAME;
1163     // This seciton will also check if the arduino board is there
1164     tristate = mraa_gpio_init_raw(214);
1165     if (tristate == NULL) {
1166         syslog(LOG_INFO, "edison: Failed to initialise Arduino board TriState,\
1167                 assuming Intel Edison Miniboard\n");
1168         if (mraa_intel_edison_miniboard(b) != MRAA_SUCCESS) {
1169             goto error;
1170         }
1171         return b;
1172     }
1173     // Now Assuming the edison is attached to the Arduino board.
1174     b->phy_pin_count = 20;
1175     b->gpio_count = 14;
1176     b->aio_count = 6;
1177     b->platform_version = "arduino";
1178 
1179     b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
1180     if (b->adv_func == NULL) {
1181         goto error;
1182     }
1183     b->adv_func->gpio_dir_pre = &mraa_intel_edison_gpio_dir_pre;
1184     b->adv_func->gpio_init_post = &mraa_intel_edison_gpio_init_post;
1185     b->adv_func->gpio_close_pre = &mraa_intel_edison_gpio_close_pre;
1186     b->adv_func->gpio_dir_post = &mraa_intel_edison_gpio_dir_post;
1187     b->adv_func->i2c_init_pre = &mraa_intel_edison_i2c_init_pre;
1188     b->adv_func->i2c_set_frequency_replace = &mraa_intel_edison_i2c_freq;
1189     b->adv_func->aio_get_valid_fp = &mraa_intel_edison_aio_get_fp;
1190     b->adv_func->aio_init_pre = &mraa_intel_edison_aio_init_pre;
1191     b->adv_func->aio_init_post = &mraa_intel_edison_aio_init_post;
1192     b->adv_func->pwm_init_pre = &mraa_intel_edison_pwm_init_pre;
1193     b->adv_func->pwm_init_post = &mraa_intel_edison_pwm_init_post;
1194     b->adv_func->spi_init_pre = &mraa_intel_edison_spi_init_pre;
1195     b->adv_func->spi_init_post = &mraa_intel_edison_spi_init_post;
1196     b->adv_func->gpio_mode_replace = &mraa_intel_edison_gpio_mode_replace;
1197     b->adv_func->uart_init_pre = &mraa_intel_edison_uart_init_pre;
1198     b->adv_func->uart_init_post = &mraa_intel_edison_uart_init_post;
1199     b->adv_func->gpio_mmap_setup = &mraa_intel_edison_mmap_setup;
1200     b->adv_func->spi_lsbmode_replace = &mraa_intel_edison_spi_lsbmode_replace;
1201 
1202     b->pins = (mraa_pininfo_t*) calloc(MRAA_INTEL_EDISON_PINCOUNT, sizeof(mraa_pininfo_t));
1203     if (b->pins == NULL) {
1204         free(b->adv_func);
1205         goto error;
1206     }
1207 
1208     mraa_gpio_dir(tristate, MRAA_GPIO_OUT);
1209     mraa_intel_edison_misc_spi();
1210 
1211     b->adc_raw = 12;
1212     b->adc_supported = 10;
1213     b->pwm_default_period = 5000;
1214     b->pwm_max_period = 218453;
1215     b->pwm_min_period = 1;
1216 
1217     strncpy(b->pins[0].name, "IO0", 8);
1218     b->pins[0].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
1219     b->pins[0].gpio.pinmap = 130;
1220     b->pins[0].gpio.parent_id = 0;
1221     b->pins[0].gpio.mux_total = 0;
1222     b->pins[0].uart.pinmap = 0;
1223     b->pins[0].uart.parent_id = 0;
1224     b->pins[0].uart.mux_total = 0;
1225 
1226     strncpy(b->pins[1].name, "IO1", 8);
1227     b->pins[1].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
1228     b->pins[1].gpio.pinmap = 131;
1229     b->pins[1].gpio.parent_id = 0;
1230     b->pins[1].gpio.mux_total = 0;
1231     b->pins[1].uart.pinmap = 0;
1232     b->pins[1].uart.parent_id = 0;
1233     b->pins[1].uart.mux_total = 0;
1234 
1235     strncpy(b->pins[2].name, "IO2", 8);
1236     b->pins[2].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
1237     b->pins[2].gpio.pinmap = 128;
1238     b->pins[2].gpio.parent_id = 0;
1239     b->pins[2].gpio.mux_total = 0;
1240 
1241     strncpy(b->pins[3].name, "IO3", 8);
1242     b->pins[3].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0 };
1243     b->pins[3].gpio.pinmap = 12;
1244     b->pins[3].gpio.parent_id = 0;
1245     b->pins[3].gpio.mux_total = 0;
1246     b->pins[3].pwm.pinmap = 0;
1247     b->pins[3].pwm.parent_id = 0;
1248     b->pins[3].pwm.mux_total = 0;
1249 
1250     strncpy(b->pins[4].name, "IO4", 8);
1251     b->pins[4].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
1252     b->pins[4].gpio.pinmap = 129;
1253     b->pins[4].gpio.parent_id = 0;
1254     b->pins[4].gpio.mux_total = 0;
1255 
1256     strncpy(b->pins[5].name, "IO5", 8);
1257     b->pins[5].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
1258     b->pins[5].gpio.pinmap = 13;
1259     b->pins[5].gpio.parent_id = 0;
1260     b->pins[5].gpio.mux_total = 0;
1261     b->pins[5].pwm.pinmap = 1;
1262     b->pins[5].pwm.parent_id = 0;
1263     b->pins[5].pwm.mux_total = 0;
1264 
1265     strncpy(b->pins[6].name, "IO6", 8);
1266     b->pins[6].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
1267     b->pins[6].gpio.pinmap = 182;
1268     b->pins[6].gpio.parent_id = 0;
1269     b->pins[6].gpio.mux_total = 0;
1270     b->pins[6].pwm.pinmap = 2;
1271     b->pins[6].pwm.parent_id = 0;
1272     b->pins[6].pwm.mux_total = 0;
1273 
1274     strncpy(b->pins[7].name, "IO7", 8);
1275     b->pins[7].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
1276     b->pins[7].gpio.pinmap = 48;
1277     b->pins[7].gpio.parent_id = 0;
1278     b->pins[7].gpio.mux_total = 0;
1279 
1280     strncpy(b->pins[8].name, "IO8", 8);
1281     b->pins[8].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0 };
1282     b->pins[8].gpio.pinmap = 49;
1283     b->pins[8].gpio.parent_id = 0;
1284     b->pins[8].gpio.mux_total = 0;
1285 
1286     strncpy(b->pins[9].name, "IO9", 8);
1287     b->pins[9].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
1288     b->pins[9].gpio.pinmap = 183;
1289     b->pins[9].gpio.parent_id = 0;
1290     b->pins[9].gpio.mux_total = 0;
1291     b->pins[9].pwm.pinmap = 3;
1292     b->pins[9].pwm.parent_id = 0;
1293     b->pins[9].pwm.mux_total = 0;
1294 
1295     strncpy(b->pins[10].name, "IO10", 8);
1296     b->pins[10].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
1297     b->pins[10].gpio.pinmap = 41;
1298     b->pins[10].gpio.parent_id = 0;
1299     b->pins[10].gpio.mux_total = 2;
1300     b->pins[10].gpio.mux[0].pin = 263;
1301     b->pins[10].gpio.mux[0].value = 1;
1302     b->pins[10].gpio.mux[1].pin = 240;
1303     b->pins[10].gpio.mux[1].value = 0;
1304     b->pins[10].spi.pinmap = 5;
1305     b->pins[10].spi.mux_total = 2;
1306     b->pins[10].spi.mux[0].pin = 263;
1307     b->pins[10].spi.mux[0].value = 1;
1308     b->pins[10].spi.mux[1].pin = 240;
1309     b->pins[10].spi.mux[1].value = 1;
1310 
1311     strncpy(b->pins[11].name, "IO11", 8);
1312     b->pins[11].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
1313     b->pins[11].gpio.pinmap = 43;
1314     b->pins[11].gpio.parent_id = 0;
1315     b->pins[11].gpio.mux_total = 2;
1316     b->pins[11].gpio.mux[0].pin = 262;
1317     b->pins[11].gpio.mux[0].value = 1;
1318     b->pins[11].gpio.mux[1].pin = 241;
1319     b->pins[11].gpio.mux[1].value = 0;
1320     b->pins[11].spi.pinmap = 5;
1321     b->pins[11].spi.mux_total = 2;
1322     b->pins[11].spi.mux[0].pin = 262;
1323     b->pins[11].spi.mux[0].value = 1;
1324     b->pins[11].spi.mux[1].pin = 241;
1325     b->pins[11].spi.mux[1].value = 1;
1326 
1327     strncpy(b->pins[12].name, "IO12", 8);
1328     b->pins[12].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
1329     b->pins[12].gpio.pinmap = 42;
1330     b->pins[12].gpio.parent_id = 0;
1331     b->pins[12].gpio.mux_total = 1;
1332     b->pins[12].gpio.mux[0].pin = 242;
1333     b->pins[12].gpio.mux[0].value = 0;
1334     b->pins[12].spi.pinmap = 5;
1335     b->pins[12].spi.mux_total = 1;
1336     b->pins[12].spi.mux[0].pin = 242;
1337     b->pins[12].spi.mux[0].value = 1;
1338 
1339     strncpy(b->pins[13].name, "IO13", 8);
1340     b->pins[13].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
1341     b->pins[13].gpio.pinmap = 40;
1342     b->pins[13].gpio.parent_id = 0;
1343     b->pins[13].gpio.mux_total = 1;
1344     b->pins[13].gpio.mux[0].pin = 243;
1345     b->pins[13].gpio.mux[0].value = 0;
1346     b->pins[13].spi.pinmap = 5;
1347     b->pins[13].spi.mux_total = 1;
1348     b->pins[13].spi.mux[0].pin = 243;
1349     b->pins[13].spi.mux[0].value = 1;
1350 
1351     strncpy(b->pins[14].name, "A0", 8);
1352     b->pins[14].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
1353     b->pins[14].aio.pinmap = 0;
1354     b->pins[14].aio.mux_total = 1;
1355     b->pins[14].aio.mux[0].pin = 200;
1356     b->pins[14].aio.mux[0].value = 1;
1357     b->pins[14].gpio.pinmap = 44;
1358     b->pins[14].gpio.mux_total = 1;
1359     b->pins[14].gpio.mux[0].pin = 200;
1360     b->pins[14].gpio.mux[0].value = 0;
1361 
1362     strncpy(b->pins[15].name, "A1", 8);
1363     b->pins[15].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
1364     b->pins[15].aio.pinmap = 1;
1365     b->pins[15].aio.mux_total = 1;
1366     b->pins[15].aio.mux[0].pin = 201;
1367     b->pins[15].aio.mux[0].value = 1;
1368     b->pins[15].gpio.pinmap = 45;
1369     b->pins[15].gpio.mux_total = 1;
1370     b->pins[15].gpio.mux[0].pin = 201;
1371     b->pins[15].gpio.mux[0].value = 0;
1372 
1373     strncpy(b->pins[16].name, "A2", 8);
1374     b->pins[16].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
1375     b->pins[16].aio.pinmap = 2;
1376     b->pins[16].aio.mux_total = 1;
1377     b->pins[16].aio.mux[0].pin = 202;
1378     b->pins[16].aio.mux[0].value = 1;
1379     b->pins[16].gpio.pinmap = 46;
1380     b->pins[16].gpio.mux_total = 1;
1381     b->pins[16].gpio.mux[0].pin = 202;
1382     b->pins[16].gpio.mux[0].value = 0;
1383 
1384     strncpy(b->pins[17].name, "A3", 8);
1385     b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
1386     b->pins[17].aio.pinmap = 3;
1387     b->pins[17].aio.mux_total = 1;
1388     b->pins[17].aio.mux[0].pin = 203;
1389     b->pins[17].aio.mux[0].value = 1;
1390     b->pins[17].gpio.pinmap = 47;
1391     b->pins[17].gpio.mux_total = 1;
1392     b->pins[17].gpio.mux[0].pin = 203;
1393     b->pins[17].gpio.mux[0].value = 0;
1394 
1395     strncpy(b->pins[18].name, "A4", 8);
1396     b->pins[18].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 1, 0 };
1397     b->pins[18].i2c.pinmap = 1;
1398     b->pins[18].i2c.mux_total = 1;
1399     b->pins[18].i2c.mux[0].pin = 204;
1400     b->pins[18].i2c.mux[0].value = 0;
1401     b->pins[18].aio.pinmap = 4;
1402     b->pins[18].aio.mux_total = 1;
1403     b->pins[18].aio.mux[0].pin = 204;
1404     b->pins[18].aio.mux[0].value = 1;
1405     b->pins[18].gpio.pinmap = 14;
1406     b->pins[18].gpio.mux_total = 1;
1407     b->pins[18].gpio.mux[0].pin = 204;
1408     b->pins[18].gpio.mux[0].value = 0;
1409 
1410     strncpy(b->pins[19].name, "A5", 8);
1411     b->pins[19].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 1, 0 };
1412     b->pins[19].i2c.pinmap = 1;
1413     b->pins[19].i2c.mux_total = 1;
1414     b->pins[19].i2c.mux[0].pin = 205;
1415     b->pins[19].i2c.mux[0].value = 0;
1416     b->pins[19].aio.pinmap = 5;
1417     b->pins[19].aio.mux_total = 1;
1418     b->pins[19].aio.mux[0].pin = 205;
1419     b->pins[19].aio.mux[0].value = 1;
1420     b->pins[19].gpio.pinmap = 165;
1421     b->pins[19].gpio.mux_total = 1;
1422     b->pins[19].gpio.mux[0].pin = 205;
1423     b->pins[19].gpio.mux[0].value = 0;
1424 
1425     // BUS DEFINITIONS
1426     b->i2c_bus_count = 9;
1427     b->def_i2c_bus = 6;
1428     int ici;
1429     for (ici = 0; ici < 9; ici++) {
1430         b->i2c_bus[ici].bus_id = -1;
1431     }
1432     b->i2c_bus[6].bus_id = 6;
1433     b->i2c_bus[6].sda = 18;
1434     b->i2c_bus[6].scl = 19;
1435 
1436     b->spi_bus_count = 1;
1437     b->def_spi_bus = 0;
1438     b->spi_bus[0].bus_id = 5;
1439     b->spi_bus[0].slave_s = 1;
1440     b->spi_bus[0].cs = 10;
1441     b->spi_bus[0].mosi = 11;
1442     b->spi_bus[0].miso = 12;
1443     b->spi_bus[0].sclk = 13;
1444 
1445     b->uart_dev_count = 1;
1446     b->def_uart_dev = 0;
1447     b->uart_dev[0].rx = 0;
1448     b->uart_dev[0].tx = 1;
1449     b->uart_dev[0].device_path = UART_DEV_PATH;
1450 
1451     int il;
1452     for (il = 0; il < MRAA_INTEL_EDISON_PINCOUNT; il++) {
1453         pinmodes[il].gpio.sysfs = -1;
1454         pinmodes[il].gpio.mode = -1;
1455         pinmodes[il].pwm.sysfs = -1;
1456         pinmodes[il].pwm.mode = -1;
1457         pinmodes[il].i2c.sysfs = -1;
1458         pinmodes[il].i2c.mode = -1;
1459         pinmodes[il].spi.sysfs = -1;
1460         pinmodes[il].spi.mode = -1;
1461         pinmodes[il].uart.sysfs = -1;
1462         pinmodes[il].uart.mode = -1;
1463     }
1464     pinmodes[0].gpio.sysfs = 130;
1465     pinmodes[0].gpio.mode = 0;
1466     pinmodes[0].uart.sysfs = 130;
1467     pinmodes[0].uart.mode = 1;
1468     pinmodes[1].gpio.sysfs = 131;
1469     pinmodes[1].gpio.mode = 0;
1470     pinmodes[1].uart.sysfs = 131;
1471     pinmodes[1].uart.mode = 1;
1472     pinmodes[2].gpio.sysfs = 128;
1473     pinmodes[2].gpio.mode = 0;
1474     pinmodes[2].uart.sysfs = 128;
1475     pinmodes[2].uart.mode = 1;
1476     pinmodes[3].gpio.sysfs = 12;
1477     pinmodes[3].gpio.mode = 0;
1478     pinmodes[3].pwm.sysfs = 12;
1479     pinmodes[3].pwm.mode = 1;
1480 
1481     pinmodes[4].gpio.sysfs = 129;
1482     pinmodes[4].gpio.mode = 0;
1483     pinmodes[4].uart.sysfs = 129;
1484     pinmodes[4].uart.mode = 1;
1485     pinmodes[5].gpio.sysfs = 13;
1486     pinmodes[5].gpio.mode = 0;
1487     pinmodes[5].pwm.sysfs = 13;
1488     pinmodes[5].pwm.mode = 1;
1489     pinmodes[6].gpio.sysfs = 182;
1490     pinmodes[6].gpio.mode = 0;
1491     pinmodes[6].pwm.sysfs = 182;
1492     pinmodes[6].pwm.mode = 1;
1493 
1494     // 7 and 8 are provided by something on i2c, very simplepinmodes[3].gpio.sysfs = 12;
1495     pinmodes[9].gpio.sysfs = 183;
1496     pinmodes[9].gpio.mode = 0;
1497     pinmodes[9].pwm.sysfs = 183;
1498     pinmodes[9].pwm.mode = 1;
1499 
1500     pinmodes[10].gpio.sysfs = 41;
1501     pinmodes[10].gpio.mode = 0;
1502     pinmodes[10].spi.sysfs = 111; // Different pin provides, switched at mux level.
1503     pinmodes[10].spi.mode = 1;
1504 
1505     pinmodes[11].gpio.sysfs = 43;
1506     pinmodes[11].gpio.mode = 0;
1507     pinmodes[11].spi.sysfs = 115; // Different pin provides, switched at mux level.
1508     pinmodes[11].spi.mode = 1;
1509 
1510     pinmodes[12].gpio.sysfs = 42;
1511     pinmodes[12].gpio.mode = 0;
1512     pinmodes[12].spi.sysfs = 114; // Different pin provides, switched at mux level.
1513     pinmodes[12].spi.mode = 1;
1514 
1515     pinmodes[13].gpio.sysfs = 40;
1516     pinmodes[13].gpio.mode = 0;
1517     pinmodes[13].spi.sysfs = 109; // Different pin provides, switched at mux level.
1518     pinmodes[13].spi.mode = 1;
1519     // Everything else but A4 A5 LEAVE
1520     pinmodes[18].gpio.sysfs = 14;
1521     pinmodes[18].gpio.mode = 0;
1522     pinmodes[18].i2c.sysfs = 28;
1523     pinmodes[18].i2c.mode = 1;
1524 
1525     pinmodes[19].gpio.sysfs = 165;
1526     pinmodes[19].gpio.mode = 0;
1527     pinmodes[19].i2c.sysfs = 27;
1528     pinmodes[19].i2c.mode = 1;
1529 
1530     return b;
1531 error:
1532     syslog(LOG_CRIT, "edison: Arduino board failed to initialise");
1533     free(b);
1534     return NULL;
1535 }
1536