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
48typedef struct {
49    int sysfs;
50    int mode;
51} mraa_intel_edision_pindef_t;
52
53typedef 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
61static mraa_gpio_context tristate;
62
63static mraa_intel_edison_pinmodes_t pinmodes[MRAA_INTEL_EDISON_PINCOUNT];
64static unsigned int outputen[] = { 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
65                                   258, 259, 260, 261, 232, 233, 234, 235, 236, 237 };
66static mraa_gpio_context agpioOutputen[sizeof(outputen) / sizeof(outputen[0])];
67
68static 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 };
70static int miniboard = 0;
71
72// MMAP
73static uint8_t* mmap_reg = NULL;
74static int mmap_fd = 0;
75static int mmap_size;
76static unsigned int mmap_count = 0;
77
78mraa_result_t
79mraa_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
101static mraa_result_t
102mraa_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
143mraa_result_t
144mraa_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
176mraa_result_t
177mraa_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
185mraa_result_t
186mraa_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
204mraa_result_t
205mraa_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
217mraa_result_t
218mraa_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
267static mraa_result_t
268mraa_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
307mraa_result_t
308mraa_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
325mraa_result_t
326mraa_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
363mraa_result_t
364mraa_intel_edison_aio_init_post(mraa_aio_context dev)
365{
366    return mraa_gpio_write(tristate, 1);
367}
368
369mraa_result_t
370mraa_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
413mraa_result_t
414mraa_intel_edison_pwm_init_post(mraa_pwm_context pwm)
415{
416    return mraa_gpio_write(tristate, 1);
417}
418
419mraa_result_t
420mraa_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
467mraa_result_t
468mraa_intel_edison_spi_init_post(mraa_spi_context spi)
469{
470    return mraa_gpio_write(tristate, 1);
471}
472
473mraa_result_t
474mraa_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
526mraa_result_t
527mraa_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
593mraa_result_t
594mraa_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
626mraa_result_t
627mraa_intel_edison_uart_init_post(mraa_uart_context uart)
628{
629    return mraa_gpio_write(tristate, 1);
630}
631
632static mraa_result_t
633mraa_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
647mraa_result_t
648mraa_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
664int
665mraa_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
677mraa_result_t
678mraa_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
736mraa_result_t
737mraa_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
781mraa_result_t
782mraa_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
1154mraa_board_t*
1155mraa_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;
1531error:
1532    syslog(LOG_CRIT, "edison: Arduino board failed to initialise");
1533    free(b);
1534    return NULL;
1535}
1536