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/mman.h>
28 #include <sys/ioctl.h>
29 #include <linux/spi/spidev.h>
30
31 #include "common.h"
32 #include "x86/intel_galileo_rev_d.h"
33
34 #define UIO_PATH "/dev/uio0"
35 #define PLATFORM_NAME "Intel Galileo Gen 1"
36
37 static uint8_t* mmap_reg = NULL;
38 static int mmap_fd = 0;
39 static int mmap_size = 0x1000;
40 static unsigned int mmap_count = 0;
41
42 static mraa_result_t
mraa_intel_galileo_g1_mmap_unsetup()43 mraa_intel_galileo_g1_mmap_unsetup()
44 {
45 if (mmap_reg == NULL) {
46 syslog(LOG_WARNING, "galileo1: Mmap null register nothing to unsetup");
47 return MRAA_ERROR_INVALID_RESOURCE;
48 }
49 munmap(mmap_reg, mmap_size);
50 mmap_reg = NULL;
51 close(mmap_fd);
52 return MRAA_SUCCESS;
53 }
54
55 mraa_result_t
mraa_intel_galileo_g1_mmap_write(mraa_gpio_context dev,int value)56 mraa_intel_galileo_g1_mmap_write(mraa_gpio_context dev, int value)
57 {
58 int bitpos = plat->pins[dev->phy_pin].mmap.bit_pos;
59 if (value) {
60 *((unsigned*) mmap_reg) |= (1 << bitpos);
61 return MRAA_SUCCESS;
62 }
63 *((unsigned*) mmap_reg) &= ~(1 << bitpos);
64
65 return MRAA_SUCCESS;
66 }
67
68 mraa_result_t
mraa_intel_galileo_g1_mmap_setup(mraa_gpio_context dev,mraa_boolean_t en)69 mraa_intel_galileo_g1_mmap_setup(mraa_gpio_context dev, mraa_boolean_t en)
70 {
71 if (dev == NULL) {
72 syslog(LOG_ERR, "galileo1: Gpio context not valid");
73 return MRAA_ERROR_INVALID_HANDLE;
74 }
75
76 if (mraa_pin_mode_test(dev->phy_pin, MRAA_PIN_FAST_GPIO) == 0) {
77 syslog(LOG_WARNING, "galileo1: Mmap not available on this pin");
78 return MRAA_ERROR_NO_RESOURCES;
79 }
80 if (en == 0) {
81 if (dev->mmap_write == NULL) {
82 syslog(LOG_NOTICE, "galileo1: Can't disable disabled mmap gpio");
83 return MRAA_ERROR_INVALID_PARAMETER;
84 }
85 dev->mmap_write = NULL;
86 mmap_count--;
87 if (mmap_count == 0) {
88 return mraa_intel_galileo_g1_mmap_unsetup();
89 }
90 return MRAA_SUCCESS;
91 }
92
93 if (dev->mmap_write != NULL) {
94 syslog(LOG_ERR, "galileo1: Can't enable enabled mmap gpio");
95 return MRAA_ERROR_INVALID_PARAMETER;
96 }
97 if (mmap_reg == NULL) {
98 if ((mmap_fd = open(UIO_PATH, O_RDWR)) < 0) {
99 syslog(LOG_ERR, "galileo1: Unable to open UIO device");
100 return MRAA_ERROR_INVALID_RESOURCE;
101 }
102 mmap_reg = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, mmap_fd, 0);
103
104 if (mmap_reg == MAP_FAILED) {
105 syslog(LOG_ERR, "galileo1: Mmap failed to mmap");
106 mmap_reg = NULL;
107 close(mmap_fd);
108 return MRAA_ERROR_NO_RESOURCES;
109 }
110 }
111 if (mraa_setup_mux_mapped(plat->pins[dev->phy_pin].mmap.gpio) != MRAA_SUCCESS) {
112 syslog(LOG_ERR, "galileo1: Unable to setup required multiplexers for mmap");
113 return MRAA_ERROR_INVALID_RESOURCE;
114 }
115 dev->mmap_write = &mraa_intel_galileo_g1_mmap_write;
116
117 return MRAA_SUCCESS;
118 }
119
120 mraa_result_t
mraa_intel_galileo_g1_spi_lsbmode_replace(mraa_spi_context dev,mraa_boolean_t lsb)121 mraa_intel_galileo_g1_spi_lsbmode_replace(mraa_spi_context dev, mraa_boolean_t lsb)
122 {
123 uint8_t lsb_mode = (uint8_t) lsb;
124
125 // Galileo Gen1 doesn't support LSB_FIRST, we need to react appropriately
126 if (!lsb) {
127 if (ioctl(dev->devfd, SPI_IOC_WR_LSB_FIRST, &lsb_mode) < 0) {
128 syslog(LOG_ERR, "spi: Failed to set bit order");
129 return MRAA_ERROR_INVALID_RESOURCE;
130 }
131 if (ioctl(dev->devfd, SPI_IOC_RD_LSB_FIRST, &lsb_mode) < 0) {
132 syslog(LOG_ERR, "spi: Failed to set bit order");
133 return MRAA_ERROR_INVALID_RESOURCE;
134 }
135 } else {
136 return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
137 }
138
139 dev->lsb = lsb;
140 return MRAA_SUCCESS;
141 }
142
143 mraa_board_t*
mraa_intel_galileo_rev_d()144 mraa_intel_galileo_rev_d()
145 {
146 mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof(mraa_board_t));
147 if (b == NULL) {
148 return NULL;
149 }
150
151 b->platform_name = PLATFORM_NAME;
152 b->phy_pin_count = 20;
153 b->gpio_count = 14;
154 b->aio_count = 6;
155 b->uart_dev_count = 2;
156
157 b->adc_raw = 12;
158 b->adc_supported = 10;
159 b->pwm_default_period = 500;
160 b->pwm_max_period = 7968;
161 b->pwm_min_period = 1;
162
163 b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
164 if (b->adv_func == NULL) {
165 goto error;
166 }
167 b->adv_func->gpio_mmap_setup = &mraa_intel_galileo_g1_mmap_setup;
168 b->adv_func->spi_lsbmode_replace = &mraa_intel_galileo_g1_spi_lsbmode_replace;
169
170 b->pins = (mraa_pininfo_t*) calloc(MRAA_INTEL_GALILEO_REV_D_PINCOUNT, sizeof(mraa_pininfo_t));
171 if (b->pins == NULL) {
172 free(b->adv_func);
173 goto error;
174 }
175
176 // GPIO IO0 - IO10
177 strncpy(b->pins[0].name, "IO0", 8);
178 b->pins[0].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
179 b->pins[0].gpio.pinmap = 50;
180 b->pins[0].gpio.parent_id = 0;
181 b->pins[0].gpio.mux_total = 1;
182 b->pins[0].gpio.mux[0].pin = 40;
183 b->pins[0].gpio.mux[0].value = 1;
184 b->pins[0].uart.pinmap = 0;
185 b->pins[0].uart.parent_id = 0;
186 b->pins[0].uart.mux_total = 1;
187 b->pins[0].uart.mux[0].pin = 40;
188 b->pins[0].uart.mux[0].value = 0;
189
190 strncpy(b->pins[1].name, "IO1", 8);
191 b->pins[1].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
192 b->pins[1].gpio.pinmap = 51;
193 b->pins[1].gpio.mux_total = 1;
194 b->pins[1].gpio.mux[0].pin = 41;
195 b->pins[1].gpio.mux[0].value = 1;
196 b->pins[1].uart.pinmap = 0;
197 b->pins[1].uart.parent_id = 0;
198 b->pins[1].uart.mux_total = 1;
199 b->pins[1].uart.mux[0].pin = 41;
200 b->pins[1].uart.mux[0].value = 0;
201
202 strncpy(b->pins[2].name, "IO2", 8);
203 b->pins[2].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 1, 0, 0, 0, 0 };
204 b->pins[2].gpio.pinmap = 32;
205 b->pins[2].gpio.mux_total = 1;
206 b->pins[2].gpio.mux[0].pin = 31;
207 b->pins[2].gpio.mux[0].value = 1;
208 b->pins[2].mmap.gpio.pinmap = 14;
209 strncpy(b->pins[2].mmap.mem_dev, "/dev/uio0", 12);
210 b->pins[2].mmap.gpio.mux_total = 2;
211 b->pins[2].mmap.gpio.mux[0].pin = 31;
212 b->pins[2].mmap.gpio.mux[0].value = 0;
213 b->pins[2].mmap.gpio.mux[1].pin = 14;
214 b->pins[2].mmap.gpio.mux[1].value = 0;
215 b->pins[2].mmap.mem_sz = 0x1000;
216 b->pins[2].mmap.bit_pos = 6;
217
218 strncpy(b->pins[3].name, "IO3", 8);
219 b->pins[3].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 1, 0, 0, 0, 0 };
220 b->pins[3].gpio.pinmap = 18;
221 b->pins[3].gpio.mux_total = 1;
222 b->pins[3].gpio.mux[0].pin = 30;
223 b->pins[3].gpio.mux[0].value = 1;
224 b->pins[3].mmap.gpio.pinmap = 15;
225 strncpy(b->pins[3].mmap.mem_dev, "/dev/uio0", 12);
226 b->pins[3].mmap.gpio.mux_total = 2;
227 b->pins[3].mmap.gpio.mux[0].pin = 30;
228 b->pins[3].mmap.gpio.mux[0].value = 0;
229 b->pins[3].mmap.gpio.mux[1].pin = 15;
230 b->pins[3].mmap.gpio.mux[1].value = 0;
231 b->pins[3].mmap.mem_sz = 0x1000;
232 b->pins[3].mmap.bit_pos = 7;
233 b->pins[3].pwm.pinmap = 3;
234 b->pins[3].pwm.parent_id = 0;
235 b->pins[3].pwm.mux_total = 1;
236 b->pins[3].pwm.mux[0].pin = 30;
237 b->pins[3].pwm.mux[0].value = 1;
238
239
240 strncpy(b->pins[4].name, "IO4", 8);
241 b->pins[4].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
242 b->pins[4].gpio.pinmap = 28;
243 b->pins[4].gpio.mux_total = 0;
244
245 strncpy(b->pins[5].name, "IO5", 8);
246 b->pins[5].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
247 b->pins[5].gpio.pinmap = 17;
248 b->pins[5].gpio.mux_total = 0;
249 b->pins[5].pwm.pinmap = 5;
250 b->pins[5].pwm.parent_id = 0;
251 b->pins[5].pwm.mux_total = 0;
252
253 strncpy(b->pins[6].name, "IO6", 8);
254 b->pins[6].gpio.pinmap = 24;
255 b->pins[6].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
256 b->pins[6].gpio.mux_total = 0;
257 b->pins[6].pwm.pinmap = 6;
258 b->pins[6].pwm.parent_id = 0;
259 b->pins[6].pwm.mux_total = 0;
260
261 strncpy(b->pins[7].name, "IO7", 8);
262 b->pins[7].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
263 b->pins[7].gpio.pinmap = 27;
264 b->pins[7].gpio.mux_total = 0;
265
266 strncpy(b->pins[8].name, "IO8", 8);
267 b->pins[8].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
268 b->pins[8].gpio.pinmap = 26;
269 b->pins[8].gpio.mux_total = 0;
270
271 strncpy(b->pins[9].name, "IO9", 8);
272 b->pins[9].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
273 b->pins[9].gpio.pinmap = 19;
274 b->pins[9].gpio.mux_total = 0;
275 b->pins[9].pwm.pinmap = 1;
276 b->pins[9].pwm.parent_id = 0;
277 b->pins[9].pwm.mux_total = 0;
278
279 strncpy(b->pins[10].name, "IO10", 8);
280 b->pins[10].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 1, 0, 0, 0 };
281 b->pins[10].gpio.pinmap = 16;
282 b->pins[10].gpio.mux_total = 1;
283 b->pins[10].gpio.mux[0].pin = 42;
284 b->pins[10].gpio.mux[0].value = 1;
285 b->pins[10].pwm.pinmap = 7;
286 b->pins[10].pwm.parent_id = 0;
287 b->pins[10].pwm.mux_total = 1;
288 b->pins[10].pwm.mux[0].pin = 42;
289 b->pins[10].pwm.mux[0].value = 1;
290 b->pins[10].spi.pinmap = 1;
291 b->pins[10].spi.mux_total = 1;
292 b->pins[10].spi.mux[0].pin = 42;
293 b->pins[10].spi.mux[0].value = 0;
294
295 strncpy(b->pins[11].name, "IO11", 8);
296 b->pins[11].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 1, 0, 0, 0 };
297 b->pins[11].gpio.pinmap = 25;
298 b->pins[11].gpio.mux_total = 1;
299 b->pins[11].gpio.mux[0].pin = 43;
300 b->pins[11].gpio.mux[0].value = 1;
301 b->pins[11].pwm.pinmap = 4;
302 b->pins[11].pwm.parent_id = 0;
303 b->pins[11].pwm.mux_total = 1;
304 b->pins[11].pwm.mux[0].pin = 43;
305 b->pins[11].pwm.mux[0].value = 1;
306 b->pins[11].spi.pinmap = 1;
307 b->pins[11].spi.mux_total = 1;
308 b->pins[11].spi.mux[0].pin = 43;
309 b->pins[11].spi.mux[0].value = 0;
310
311 strncpy(b->pins[12].name, "IO12", 8);
312 b->pins[12].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
313 b->pins[12].gpio.pinmap = 38;
314 b->pins[12].gpio.mux_total = 1;
315 b->pins[12].gpio.mux[0].pin = 54;
316 b->pins[12].gpio.mux[0].value = 1;
317 b->pins[12].spi.pinmap = 1;
318 b->pins[12].spi.mux_total = 1;
319 b->pins[12].spi.mux[0].pin = 54;
320 b->pins[12].spi.mux[0].value = 0;
321
322 strncpy(b->pins[13].name, "IO13", 8);
323 b->pins[13].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
324 b->pins[13].gpio.pinmap = 39;
325 b->pins[13].gpio.mux_total = 1;
326 b->pins[13].gpio.mux[0].pin = 55;
327 b->pins[13].gpio.mux[0].value = 1;
328 b->pins[13].spi.pinmap = 1;
329 b->pins[13].spi.mux_total = 1;
330 b->pins[13].spi.mux[0].pin = 55;
331 b->pins[13].spi.mux[0].value = 0;
332
333 strncpy(b->pins[14].name, "A0", 8);
334 b->pins[14].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
335 b->pins[14].gpio.pinmap = 44;
336 b->pins[14].gpio.mux_total = 1;
337 b->pins[14].gpio.mux[0].pin = 37;
338 b->pins[14].gpio.mux[0].value = 1;
339 b->pins[14].aio.pinmap = 0;
340 b->pins[14].aio.mux_total = 1;
341 b->pins[14].aio.mux[0].pin = 37;
342 b->pins[14].aio.mux[0].value = 0;
343
344 strncpy(b->pins[15].name, "A1", 8);
345 b->pins[15].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
346 b->pins[15].gpio.pinmap = 45;
347 b->pins[15].gpio.mux_total = 1;
348 b->pins[15].gpio.mux[0].pin = 36;
349 b->pins[15].gpio.mux[0].value = 1;
350 b->pins[15].aio.pinmap = 1;
351 b->pins[15].aio.mux_total = 1;
352 b->pins[15].aio.mux[0].pin = 36;
353 b->pins[15].aio.mux[0].value = 0;
354
355 strncpy(b->pins[16].name, "A2", 8);
356 b->pins[16].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
357 b->pins[16].gpio.pinmap = 46;
358 b->pins[16].gpio.mux_total = 1;
359 b->pins[16].gpio.mux[0].pin = 23;
360 b->pins[16].gpio.mux[0].value = 1;
361 b->pins[16].aio.pinmap = 2;
362 b->pins[16].aio.mux_total = 1;
363 b->pins[16].aio.mux[0].pin = 23;
364 b->pins[16].aio.mux[0].value = 0;
365
366 strncpy(b->pins[17].name, "A3", 8);
367 b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 1, 0 };
368 b->pins[17].gpio.pinmap = 47;
369 b->pins[17].gpio.mux_total = 1;
370 b->pins[17].gpio.mux[0].pin = 22;
371 b->pins[17].gpio.mux[0].value = 1;
372 b->pins[17].aio.pinmap = 3;
373 b->pins[17].aio.mux_total = 1;
374 b->pins[17].aio.mux[0].pin = 22;
375 b->pins[17].aio.mux[0].value = 0;
376
377 strncpy(b->pins[18].name, "A4", 8);
378 b->pins[18].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 1, 0 };
379 b->pins[18].gpio.pinmap = 48;
380 b->pins[18].gpio.mux_total = 2;
381 b->pins[18].gpio.mux[0].pin = 29;
382 b->pins[18].gpio.mux[0].value = 1;
383 b->pins[18].gpio.mux[1].pin = 21;
384 b->pins[18].gpio.mux[1].value = 1;
385 b->pins[18].i2c.pinmap = 1;
386 b->pins[18].i2c.mux_total = 1;
387 b->pins[18].i2c.mux[0].pin = 29;
388 b->pins[18].i2c.mux[0].value = 0;
389 b->pins[18].aio.pinmap = 4;
390 b->pins[18].aio.mux_total = 2;
391 b->pins[18].aio.mux[0].pin = 29;
392 b->pins[18].aio.mux[0].value = 1;
393 b->pins[18].aio.mux[1].pin = 21;
394 b->pins[18].aio.mux[1].value = 0;
395
396 strncpy(b->pins[19].name, "A5", 8);
397 b->pins[19].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 1, 0 };
398 b->pins[19].gpio.pinmap = 49;
399 b->pins[19].gpio.mux_total = 2;
400 b->pins[19].gpio.mux[0].pin = 29;
401 b->pins[19].gpio.mux[0].value = 1;
402 b->pins[19].gpio.mux[1].pin = 20;
403 b->pins[19].gpio.mux[1].value = 1;
404 b->pins[19].i2c.pinmap = 1;
405 b->pins[19].i2c.mux_total = 1;
406 b->pins[19].i2c.mux[0].pin = 29;
407 b->pins[19].i2c.mux[0].value = 0;
408 b->pins[19].aio.pinmap = 5;
409 b->pins[19].aio.mux_total = 2;
410 b->pins[19].aio.mux[0].pin = 29;
411 b->pins[19].aio.mux[0].value = 1;
412 b->pins[19].aio.mux[1].pin = 20;
413 b->pins[19].aio.mux[1].value = 0;
414
415 // BUS DEFINITIONS
416 b->i2c_bus_count = 1;
417 b->def_i2c_bus = 0;
418 b->i2c_bus[0].bus_id = 0;
419 b->i2c_bus[0].sda = 18;
420 b->i2c_bus[0].scl = 19;
421
422 b->spi_bus_count = 1;
423 b->def_spi_bus = 0;
424 b->spi_bus[0].bus_id = 1;
425 b->spi_bus[0].slave_s = 0;
426 b->spi_bus[0].cs = 10;
427 b->spi_bus[0].mosi = 11;
428 b->spi_bus[0].miso = 12;
429 b->spi_bus[0].sclk = 13;
430
431 b->uart_dev_count = 2;
432 b->def_uart_dev = 0;
433 b->uart_dev[0].rx = 0;
434 b->uart_dev[0].tx = 1;
435 b->uart_dev[0].device_path = "/dev/ttyS0";
436
437 b->uart_dev[1].rx = -1;
438 b->uart_dev[1].tx = -1;
439 b->uart_dev[1].device_path = "/dev/ttyS1";
440
441 return b;
442 error:
443 syslog(LOG_CRIT, "galileo1: Platform failed to initialise");
444 free(b);
445 return NULL;
446 }
447