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