Private
Public Access
2
0
Files
mraa/src/x86/adlink-ipi.c

1047 lines
25 KiB
C
Raw Normal View History

/*
* Author: Dan O'Donovan <dan@emutex.com>
* Author: Santhanakumar A <santhanakumar.a@adlinktech.com>
* Copyright (c) 2019 ADLINK Technology Inc.
* SPDX-License-Identifier: MIT
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <sys/file.h>
#include <unistd.h>
#include "linux/gpio.h"
#include "mraa_internal.h"
#include <dirent.h>
#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <linux/i2c-dev.h>
#include "common.h"
#include "gpio.h"
#include "x86/intel_adlink_lec_al.h"
#include "gpio/gpio_chardev.h"
#define SYSFS_CLASS_GPIO "/sys/class/gpio"
#define PLATFORM_NAME "LEC-AL"
#define PLATFORM_NAME_AI "LEC-AL AI"
#define MRAA_LEC_AL_GPIOCOUNT 17
#define MAX_SIZE 64
#define POLL_TIMEOUT
static volatile int base1, base2, _fd;
static volatile long m_period;
static mraa_gpio_context gpio;
struct intr_list {
volatile int pin;
unsigned char curr;
char valuepath[50];
void (*fptr)(void*);
void* args;
struct intr_list *next;
};
static unsigned char regIon[16] = {0x2A, 0x2D, 0x30, 0x33, 0x36, 0x3B, 0x40, 0x45, 0x4A, 0x4D, 0x50, 0x53, 0x56, 0x5B, 0x60, 0x65};
static struct intr_list *list;
mraa_result_t gpio_intr_init_pre(int pin);
static int sx150x_pwm_init(int pin);
static mraa_result_t pwm_init_raw_replace(mraa_pwm_context dev, int pin)
{
char buffer[100] = {0};
int i, fd;
if(pin < 9)
{
if(sx150x_pwm_init(pin))
{
return MRAA_ERROR_NO_RESOURCES;
}
if((fd = open("/sys/class/gpio/export", O_WRONLY)) != -1)
{
i = sprintf(buffer,"%d",base2 + pin);
write(fd, buffer, i);
close(fd);
sprintf(buffer,"/sys/class/gpio/gpio%d/direction",base2 + pin);
if((fd = open(buffer, O_WRONLY)) != -1)
{
write(fd, "out", 3);
close(fd);
sprintf(buffer,"/sys/class/gpio/gpio%d/value",base2 + pin);
if((fd = open(buffer, O_WRONLY)) != -1)
{
write(fd, "0", 1);
close(fd);
}
}
}
else
{
return MRAA_ERROR_NO_RESOURCES;
}
}
return MRAA_SUCCESS;
}
static mraa_result_t pwm_period_replace(mraa_pwm_context dev, int period)
{
m_period = period;
return MRAA_SUCCESS;
}
static float pwm_read_replace(mraa_pwm_context dev)
{
unsigned char rx_tx_buf[3] = {0};
if(dev->pin < 9)
{
if(_fd == -1)
{
return 0;
}
rx_tx_buf[0] = regIon[dev->pin];
if(write(_fd, &(rx_tx_buf[0]), 1) == 1)
{
if(read(_fd, &(rx_tx_buf[1]), 1) == 1)
{
return ((rx_tx_buf[1] / 2.55)* 2000);
}
}
}
return 0;
}
static mraa_result_t pwm_write_replace(mraa_pwm_context dev, float duty)
{
unsigned char rx_tx_buf[3] = {0};
duty = duty / 2000;
if(dev->pin < 9)
{
duty = duty * 2.55;
if(_fd == -1)
{
return MRAA_ERROR_INVALID_RESOURCE;
}
rx_tx_buf[0] = regIon[dev->pin];
rx_tx_buf[1] = duty;
if(write(_fd, &(rx_tx_buf[0]), 2) != 2)
{
return MRAA_ERROR_NO_RESOURCES;
}
return MRAA_SUCCESS;
}
return MRAA_ERROR_NO_RESOURCES;
}
static mraa_result_t pwm_enable_replace(mraa_pwm_context dev, int enable)
{
int pin = dev->pin;
if(9 > pin && 0 <= pin)
{
if(_fd != -1)
{
unsigned char rx_tx_buf[3] = {0};
if(_fd == -1)
{
return MRAA_ERROR_NO_RESOURCES;
}
rx_tx_buf[0] = regIon[pin];
rx_tx_buf[1] = 0xFF;
if(write(_fd, &(rx_tx_buf[0]), 2) != 2)
{
return MRAA_ERROR_NO_RESOURCES;
}
}
else
{
return MRAA_ERROR_NO_RESOURCES;
}
return MRAA_SUCCESS;
}
return MRAA_ERROR_NO_RESOURCES;
}
static void
gpio_close_event_handles_sysfs(int fds[], int num_fds)
{
if ((fds == NULL) || (num_fds <= 0)) {
syslog(LOG_CRIT, "failed to close and free sysfs event handles");
return;
}
for (int i = 0; i < num_fds; ++i) {
close(fds[i]);
}
free(fds);
}
static mraa_timestamp_t
gpio_get_timestamp_sysfs()
{
struct timeval time;
gettimeofday(&time, NULL);
return (time.tv_sec * 1e6 + time.tv_usec);
}
//clearing all interrupts
void clear_sx1509x_intr(void)
{
uint8_t rx_tx_buf[10] = {0};
rx_tx_buf[0] = 0x18;
rx_tx_buf[1] = 0xFF;
rx_tx_buf[2] = 0xFF;
write(_fd, rx_tx_buf, 3);
}
static mraa_result_t gpio_wait_interrupt(int fds[], int num_fds, mraa_gpio_events_t events)
{
unsigned char c;
struct pollfd pfd[num_fds];
pfd[0].fd = fds[0];
// setup poll on POLLPRI
pfd[0].events = POLLPRI;
// do an initial read to clear interrupt
lseek(fds[0], 0, SEEK_SET);
read(fds[0], &c, 1);
clear_sx1509x_intr();
// Wait for it forever or until pthread_cancel
// poll is a cancelable point like sleep()
poll(pfd, num_fds, -1);
clear_sx1509x_intr();
if (pfd[0].revents & POLLPRI) {
read(fds[0], &c, 1);
events[0].id = 0;
events[0].timestamp = gpio_get_timestamp_sysfs();
} else
events[0].id = -1;
return MRAA_SUCCESS;
}
static void*
gpio_interrupt_handler(void* arg)
{
if (arg == NULL) {
syslog(LOG_ERR, "gpio: interrupt_handler: context is invalid");
return NULL;
}
mraa_result_t ret;
mraa_gpio_context dev = (mraa_gpio_context) arg;
int idx = 0;
int *fps = malloc(dev->num_pins * sizeof(int));
if (!fps) {
syslog(LOG_ERR, "mraa_gpio_interrupt_handler_multiple() malloc error");
return NULL;
}
mraa_gpio_context it = dev;
char bu[MAX_SIZE];
snprintf(bu, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/value", it->pin);
fps[idx] = open(bu, O_RDONLY);
if (fps[idx] < 0) {
syslog(LOG_ERR, "gpio%i: interrupt_handler: failed to open 'value' : %s", it->pin,
strerror(errno));
gpio_close_event_handles_sysfs(fps, idx);
return NULL;
}
idx++;
for (;;) {
ret = gpio_wait_interrupt(fps, idx, dev->events);
if (ret == MRAA_SUCCESS && !dev->isr_thread_terminating) {
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if(dev->isr != NULL)
{
(dev->isr)(dev->isr_args);
}
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
}
}
}
static void internal_isr(void*args)
{
struct intr_list *it = list;
int fps;
unsigned char c;
/* Is this pin on a subplatform? Do nothing... */
while (it) {
// open gpio value with open(3)
fps = open(it->valuepath, O_RDONLY);
if (fps > 0) {
read(fps, &c, 1);
close(fps);
if(it->curr != c)
{
(it->fptr)(it->args);
it->curr = c;
}
}
it = it->next;
}
}
// configuring main interrupt line for sx1509q it will create common isr routine for all gpio's
static mraa_result_t intr_init()
{
int fd;
char bu[MAX_SIZE];
int length;
char filepath[MAX_SIZE];
gpio = (mraa_gpio_context) calloc(1, sizeof(struct _gpio));
if (gpio == NULL) {
syslog(LOG_CRIT, "gpio%i: Failed to allocate memory for context", 456);
return MRAA_ERROR_INVALID_RESOURCE;
}
gpio->advance_func = NULL;
gpio->pin = 434 + 22;
gpio->value_fp = -1;
gpio->isr_value_fp = -1;
gpio->isr_thread_terminating = 0;
gpio->owner = 1;
gpio->num_pins = 1;
gpio->next = NULL;
gpio->events = NULL;
if((fd = open("/sys/class/gpio/export", O_WRONLY)) != -1)
{
write(fd,"456",3);
sprintf(bu,"%d",base1 + 12);
write(fd,bu,3);
close(fd);
}
else
{
return MRAA_ERROR_INVALID_RESOURCE;
}
sprintf(bu,"/sys/class/gpio/gpio%d/direction",456);
if((fd = open(bu, O_WRONLY)) != -1)
{
write(fd, "in", 2);
close(fd);
}
else
{
return MRAA_ERROR_INVALID_RESOURCE;
}
sprintf(bu,"/sys/class/gpio/gpio%d/direction",base1 + 12);
if((fd = open(bu, O_WRONLY)) != -1)
{
write(fd, "in", 2);
close(fd);
}
else
{
return MRAA_ERROR_INVALID_RESOURCE;
}
// we only allow one isr per mraa_gpio_context
if (gpio->thread_id != 0) {
return MRAA_ERROR_NO_RESOURCES;
}
gpio->events = malloc(gpio->num_pins * sizeof(mraa_gpio_event));
if (gpio->events == NULL) {
syslog(LOG_ERR, "mraa_gpio_edge_mode() malloc error");
return MRAA_ERROR_NO_RESOURCES;
}
gpio->events[0].id = -1;
snprintf(filepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/edge", gpio->pin);
int edge = open(filepath, O_RDWR);
if (edge == -1) {
syslog(LOG_ERR, "gpio%i: edge_mode: Failed to open 'edge' for writing: %s", gpio->pin,
strerror(errno));
return MRAA_ERROR_INVALID_RESOURCE;
}
length = snprintf(bu, sizeof(bu), "both");
if (write(edge, bu, length * sizeof(char)) == -1) {
syslog(LOG_ERR, "gpio%i: edge_mode: Failed to write to 'edge': %s", gpio->pin, strerror(errno));
close(edge);
return MRAA_ERROR_UNSPECIFIED;
}
close(edge);
gpio->isr = internal_isr;
gpio->isr_args = NULL;
pthread_create(&gpio->thread_id, NULL, gpio_interrupt_handler, (void*) gpio);
return MRAA_SUCCESS;
}
// it will clean the resources, MRAA created by advanced callback functions
static mraa_result_t gpio_close_pre(mraa_gpio_context dev)
{
struct intr_list *ptr, *last;
ptr = last = list;
char gpio_path[50] = {0};
int fd, length;
if(list == NULL)
{
return MRAA_SUCCESS;
}
while(ptr)
{
if(ptr->pin == dev->pin)
{
break;
}
last = ptr;
ptr = ptr->next;
}
if(ptr)
{
if(ptr == list)
{
list = ptr->next;
}
else
{
last->next = ptr->next;
}
}
if(list == NULL && gpio != NULL)
{
mraa_gpio_isr_exit(gpio);
if((fd = open("/sys/class/gpio/unexport", O_WRONLY)) != -1)
{
length = sprintf(gpio_path,"%d",gpio->pin);
write(fd, gpio_path, length);
length = sprintf(gpio_path,"%d",base1 + 12);
write(fd, gpio_path, length);
close(fd);
}
free(gpio);
gpio = NULL;
}
return MRAA_SUCCESS;
}
//callb ack routine for isr registration
static mraa_result_t gpio_isr_replace(mraa_gpio_context dev, mraa_gpio_edge_t mode, void (*fptr)(void*), void* args)
{
struct intr_list *node = list;
int fps;
node = list;
if(list == NULL)
{
intr_init();
}
gpio_intr_init_pre(dev->pin);
struct intr_list *ptr = list;
while(ptr)
{
if(ptr->pin == dev->pin)
{
return MRAA_ERROR_NO_RESOURCES;
}
ptr = ptr->next;
}
list = (struct intr_list*)calloc(1, sizeof(struct intr_list));
if(list == NULL)
{
return MRAA_ERROR_INVALID_RESOURCE;
}
list->fptr = fptr;
list->args = args;
list->pin = dev->pin;
list->next = node;
snprintf(list->valuepath, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/value", list->pin);
fps = open(list->valuepath, O_RDONLY);
if (fps > 0) {
read(fps, &(list->curr), 1);
close(fps);
}
return MRAA_SUCCESS;
}
//configuring extra registers as pwm for extended gpio
static int sx150x_pwm_init(int pin)
{
int i;
int add = (pin < 8) ? 1 : 0;
unsigned char rx_tx_buf[] = {0x0 + add, 0, 0x6 + add, 0, 0xE + add, 0, 0x20 + add, 0, 0x10 + add, 0};
if(_fd == -1)
{
return -1;
}
for(i = 0; i < 9; i += 2)
{
if(write(_fd, &(rx_tx_buf[i]), 1) != 1)
{
return -1;
}
if(read(_fd, &(rx_tx_buf[i + 1]), 1) != 1)
{
return -1;
}
if((i == 2) || (i == 6))
rx_tx_buf[i+1] |= (1 << (pin % 8));
else
rx_tx_buf[i+1] &= ~(1 << (pin % 8));
if(write(_fd, &(rx_tx_buf[i]), 2) != 2)
{
return -1;
}
}
return 0;
}
//configuring extra registers as interrupt for extended gpio
mraa_result_t gpio_intr_init_pre(int pin)
{
int i;
if(base2 + 17 > pin && (base2 - 1) < pin)
{
pin = (pin - base2);
int index = pin % 8;
unsigned char rx_tx_buf[] = {0x12, 0, 0, 0x14, 0, 0, 0x16, 0, 0, 0x18, 0, 0};
if(_fd == -1)
{
return MRAA_ERROR_NO_RESOURCES;
}
for(i = 0; i < 10; i+=3)
{
if(write(_fd, &(rx_tx_buf[i]), 1) != 1)
{
return MRAA_ERROR_NO_RESOURCES;
}
if(read(_fd, &(rx_tx_buf[i + 1]), 2) != 2)
{
return MRAA_ERROR_NO_RESOURCES;
}
if(rx_tx_buf[i] == 0x12)
{
if(pin < 8)
rx_tx_buf[i + 2] &= ~(1 << index);
else
rx_tx_buf[i + 1] &= ~(1 << index);
}
else
{
if(rx_tx_buf[i] == 0x14 && pin < 8)
{
if(index < 4)
rx_tx_buf[i + 2] |= (3 << ((index % 4) * 2));
else
rx_tx_buf[i + 1] |= (3 << ((index % 4) * 2));
}
else if(rx_tx_buf[i] == 0x16)
{
if(index < 4)
rx_tx_buf[i + 2] |= (3 << ((index % 4) * 2));
else
rx_tx_buf[i + 1] |= (3 << ((index % 4) * 2));
}
else
{
if(pin < 8)
rx_tx_buf[i + 2] |= (1 << index);
else
rx_tx_buf[i + 1] |= (1 << index);
}
}
if(write(_fd, &(rx_tx_buf[i]), 3) != 3)
{
return MRAA_ERROR_NO_RESOURCES;
}
}
}
return MRAA_SUCCESS;
}
static int sx150x_init(int bus_num)
{
char rx_tx_buf[20] = {0};
sprintf(rx_tx_buf, "/dev/i2c-%d",bus_num);
if((_fd = open(rx_tx_buf, O_RDWR)) < 0)
{
return -1;
}
if(ioctl(_fd, I2C_SLAVE_FORCE, 0x3E) < 0)
{
return -1;
}
/*
// resetting sx1509q
rx_tx_buf[0] = 0x7d;
rx_tx_buf[1] = 0x12;
if(write(_fd, &(rx_tx_buf[0]), 2) == 2)
{
rx_tx_buf[1] = 0x34;
if(write(_fd, &(rx_tx_buf[0]), 2) != 2)
{
return -1;
}
}
*/
// configuring clock and misc register for PWM feature
rx_tx_buf[0] = 0x1E;
if(write(_fd, &(rx_tx_buf[0]), 1) == 1)
{
if(read(_fd, &(rx_tx_buf[1]), 1) == 1)
{
rx_tx_buf[1] |= (1 << 6);
rx_tx_buf[1] |= ~(1 << 5);
if(write(_fd, &(rx_tx_buf[0]), 2) != 2)
{
return -1;
}
}
}
else
{
return -1;
}
rx_tx_buf[0] = 0x1F;
if(write(_fd, &(rx_tx_buf[0]), 1) == 1)
{
if(read(_fd, &(rx_tx_buf[1]), 1) == 1)
{
rx_tx_buf[1] &= ~(1 << 7);
rx_tx_buf[1] &= ~(1 << 3);
rx_tx_buf[1] &= ~((0x7) << 4);
rx_tx_buf[1] |= ((1 & 0x7) << 4);
if(write(_fd, &(rx_tx_buf[0]), 2) == 2)
{
return 0;
}
}
}
return -1;
}
// utility function to setup pin mapping of boards
static mraa_result_t mraa_lec_al_set_pininfo(mraa_board_t* board, int mraa_index, char* name,
mraa_pincapabilities_t caps, int sysfs_pin)
{
if (mraa_index < board->phy_pin_count) {
mraa_pininfo_t* pin_info = &board->pins[mraa_index];
strncpy(pin_info->name, name, MRAA_PIN_NAME_SIZE);
pin_info->capabilities = caps;
if (caps.gpio) {
pin_info->gpio.pinmap = sysfs_pin;
pin_info->gpio.mux_total = 0;
}
if (caps.i2c) {
pin_info->i2c.pinmap = 1;
pin_info->i2c.mux_total = 0;
}
if (caps.uart) {
pin_info->uart.mux_total = 0;
}
if (caps.spi) {
pin_info->spi.mux_total = 0;
}
return MRAA_SUCCESS;
}
return MRAA_ERROR_INVALID_RESOURCE;
}
static mraa_result_t mraa_lec_al_get_pin_index(mraa_board_t* board, char* name, int* pin_index)
{
int i;
for (i = 0; i < board->phy_pin_count; ++i) {
if (strncmp(name, board->pins[i].name, MRAA_PIN_NAME_SIZE) == 0) {
*pin_index = i;
return MRAA_SUCCESS;
}
}
syslog(LOG_CRIT, "lec_al: Failed to find pin name %s", name);
return MRAA_ERROR_INVALID_RESOURCE;
}
static mraa_result_t gpio_init_pre(int pin)
{
unsigned char rx_tx_buf[3] = {0};
int fd, i;
char buffer[50] = {0};
if(pin == base1 + 6)
{
for(i = 0; i < 100; i++)
{
sprintf(buffer, "/sys/class/hwmon/hwmon%d/device/fan1_enable", i);
if((fd = open(buffer, O_RDWR)) == -1)
{
continue;
}
if((write(fd, "1", 1)) != 1)
{
close(fd);
return MRAA_ERROR_NO_RESOURCES;
}
close(fd);
}
}
if(base2 + 17 > pin && (base2 - 1) < pin)
{
pin = pin - base2;
int add = (pin < 8) ? 1 : 0;
if(_fd == -1)
{
return MRAA_ERROR_INVALID_RESOURCE;
}
rx_tx_buf[0] = regIon[pin];
rx_tx_buf[1] = -1;
if(write(_fd, &(rx_tx_buf[0]), 2) != 2)
{
return MRAA_ERROR_NO_RESOURCES;
}
rx_tx_buf[0] = 0x0 + add;
if(write(_fd, &(rx_tx_buf[0]), 1) == 1)
{
if(read(_fd, &(rx_tx_buf[1]), 1) == 1)
{
rx_tx_buf[1] &= ~(1 < (pin % 8));
write(_fd, &rx_tx_buf[0], 2);
}
}
rx_tx_buf[0] = 0x20 + add;
if(write(_fd, &(rx_tx_buf[0]), 1) == 1)
{
if(read(_fd, &(rx_tx_buf[1]), 1) == 1)
{
rx_tx_buf[1] &= ~(1 < (pin % 8));
write(_fd, &rx_tx_buf[0], 2);
if((fd = open("/sys/class/gpio/unexport", O_WRONLY)) != -1)
{
i = sprintf(buffer,"%d",base2 + pin);
write(fd, buffer, i);
close(fd);
}
return MRAA_SUCCESS;
}
}
return MRAA_ERROR_INVALID_RESOURCE;
}
return MRAA_SUCCESS;
}
mraa_board_t* mraa_lec_al_board()
{
int i, fd, i2c_bus_num;
char buffer[60] = {0}, *line = NULL;
FILE *fh;
size_t len;
mraa_board_t* b = (mraa_board_t*) calloc(1, sizeof (mraa_board_t));
if (b == NULL) {
return NULL;
}
if((fh = fopen("/sys/devices/virtual/dmi/id/product_name", "r")) != NULL) {
if (getline(&line, &len, fh) != -1) {
line[strcspn(line, "\r\n")] = 0;
if ((strncasecmp(line, "LEC-ALAI", strlen("LEC-ALAI") + 1) == 0)) {
b->platform_name = PLATFORM_NAME_AI;
}
else
{
b->platform_name = PLATFORM_NAME;
}
}
fclose(fh);
}
b->phy_pin_count = MRAA_LEC_AL_PINCOUNT;
b->gpio_count = MRAA_LEC_AL_GPIOCOUNT;
b->chardev_capable = 0;
b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * MRAA_LEC_AL_PINCOUNT);
if (b->pins == NULL) {
goto error;
}
b->adv_func = (mraa_adv_func_t *) calloc(1, sizeof (mraa_adv_func_t));
if (b->adv_func == NULL) {
free(b->pins);
goto error;
}
b->adv_func->gpio_isr_replace = gpio_isr_replace;
b->adv_func->gpio_close_pre = gpio_close_pre;
b->adv_func->gpio_init_pre = gpio_init_pre;
// initializations of pwm functions
b->adv_func->pwm_init_raw_replace = pwm_init_raw_replace;
b->adv_func->pwm_period_replace = pwm_period_replace;
b->adv_func->pwm_read_replace = pwm_read_replace;
b->adv_func->pwm_write_replace = pwm_write_replace;
b->adv_func->pwm_enable_replace = pwm_enable_replace;
for(i = 0; i < 999; i++)
{
sprintf(buffer,"/sys/class/gpio/gpiochip%d/device/name",i);
if((fd = open(buffer, O_RDONLY)) != -1)
{
int count = read(fd,buffer,7);
if(count != 0)
{
if(strncmp(buffer, "sx1509q", count) == 0)
{
base2 = i;
}
if(strncmp(buffer, "pca9535", count) == 0)
{
base1 = i;
}
}
close(fd);
}
}
syslog(LOG_NOTICE, "lec_al: base1 %d base2 %d\n", base1, base2);
// Configure PWM
b->pwm_dev_count = 0;
b->pwm_default_period = 5000;
b->pwm_max_period = 218453;
b->pwm_min_period = 1;
mraa_lec_al_set_pininfo(b, 1, "3v3", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 2, "5v", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 3, "I2C0_DAT", (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 1, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 4, "5v", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 5, "I2C0_CK", (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 1, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 6, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 7, "GPIO04", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 4);
mraa_lec_al_set_pininfo(b, 8, "UART_TXD", (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 1 }, -1);
mraa_lec_al_set_pininfo(b, 9, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 10, "UART_RXD", (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 0, 0, 1 }, -1);
mraa_lec_al_set_pininfo(b, 11, "GPIO05", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 6);
mraa_lec_al_set_pininfo(b, 12, "GPIO06", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 5);
b->pins[12].pwm.parent_id = 0;
b->pins[12].pwm.pinmap = 9;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 13, "GPIO07", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 7);
mraa_lec_al_set_pininfo(b, 14, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 15, "GPIO08", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 8);
mraa_lec_al_set_pininfo(b, 16, "GPIO09", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 9);
mraa_lec_al_set_pininfo(b, 17, "3v3", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 18, "GPIO10", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 10);
mraa_lec_al_set_pininfo(b, 19, "SPI_0_MOSI", (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 20, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 21, "SPI_0_MISO", (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 22, "GPIO11", (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 }, base1 + 11);
mraa_lec_al_set_pininfo(b, 23, "SPI_0_SCLK", (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 24, "SPI_0_CE0", (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 25, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 26, "SPI_0_CE1", (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 27, "I2C1_DAT", (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 1, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 28, "I2C1_CK", (mraa_pincapabilities_t){ 1, 0, 0, 0, 0, 1, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 29, "GPIO1_0", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 0);
b->pins[29].pwm.parent_id = 1;
b->pins[29].pwm.pinmap = 0;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 30, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 31, "GPIO1_1", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 1);
b->pins[31].pwm.parent_id = 1;
b->pins[31].pwm.pinmap = 1;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 32, "GPIO1_2", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 2);
b->pins[32].pwm.parent_id = 1;
b->pins[32].pwm.pinmap = 2;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 33, "GPIO1_3", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 3);
b->pins[33].pwm.parent_id = 1;
b->pins[33].pwm.pinmap = 3;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 34, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 35, "GPIO1_4", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 4);
b->pins[35].pwm.parent_id = 1;
b->pins[35].pwm.pinmap = 4;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 36, "GPIO1_5", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 5);
b->pins[36].pwm.parent_id = 1;
b->pins[36].pwm.pinmap = 5;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 37, "GPIO1_6", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 6);
b->pins[37].pwm.parent_id = 1;
b->pins[37].pwm.pinmap = 6;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 38, "GPIO1_7", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 7);
b->pins[38].pwm.parent_id = 1;
b->pins[38].pwm.pinmap = 7;
b->pwm_dev_count++;
mraa_lec_al_set_pininfo(b, 39, "GND", (mraa_pincapabilities_t){ -1, 0, 0, 0, 0, 0, 0, 0 }, -1);
mraa_lec_al_set_pininfo(b, 40, "GPIO2_8", (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 }, base2 + 8);
b->pins[40].pwm.parent_id = 1;
b->pins[40].pwm.pinmap = 8;
b->pwm_dev_count++;
// Configure UART #1 (default)
b->uart_dev_count = 1;
mraa_lec_al_get_pin_index(b, "UART_RXD", &(b->uart_dev[0].rx));
mraa_lec_al_get_pin_index(b, "UART_TXD", &(b->uart_dev[0].tx));
b->uart_dev[0].device_path = "/dev/ttyS4";
b->def_uart_dev = 0;
// Configure SPI #0 CS1
b->spi_bus_count = 0;
b->spi_bus[b->spi_bus_count].bus_id = 1;
b->spi_bus[b->spi_bus_count].slave_s = 0;
mraa_lec_al_get_pin_index(b, "SPI_0_CE0", &(b->spi_bus[b->spi_bus_count].cs));
mraa_lec_al_get_pin_index(b, "SPI_0_MOSI", &(b->spi_bus[b->spi_bus_count].mosi));
mraa_lec_al_get_pin_index(b, "SPI_0_MISO", &(b->spi_bus[b->spi_bus_count].miso));
mraa_lec_al_get_pin_index(b, "SPI_0_SCLK", &(b->spi_bus[b->spi_bus_count].sclk));
b->spi_bus_count++;
b->spi_bus[b->spi_bus_count].bus_id = 1;
b->spi_bus[b->spi_bus_count].slave_s = 1;
mraa_lec_al_get_pin_index(b, "SPI_0_CE1", &(b->spi_bus[b->spi_bus_count].cs));
mraa_lec_al_get_pin_index(b, "SPI_0_MOSI", &(b->spi_bus[b->spi_bus_count].mosi));
mraa_lec_al_get_pin_index(b, "SPI_0_MISO", &(b->spi_bus[b->spi_bus_count].miso));
mraa_lec_al_get_pin_index(b, "SPI_0_SCLK", &(b->spi_bus[b->spi_bus_count].sclk));
b->spi_bus_count++;
// Set number of i2c adaptors usable from userspace
b->i2c_bus_count = 0;
b->def_i2c_bus = 0;
i2c_bus_num = mraa_find_i2c_bus_pci("0000:00", "0000:00:16.1", "i2c_designware.1");
if (i2c_bus_num != -1) {
if(sx150x_init(i2c_bus_num) < 0)
{
_fd = -1;
}
b->i2c_bus[0].bus_id = i2c_bus_num;
mraa_lec_al_get_pin_index(b, "I2C1_DAT", (int*) &(b->i2c_bus[1].sda));
mraa_lec_al_get_pin_index(b, "I2C1_CK", (int*) &(b->i2c_bus[1].scl));
b->i2c_bus_count++;
}
i2c_bus_num = mraa_find_i2c_bus_pci("0000:00", "0000:00:1f.1", ".");
if (i2c_bus_num != -1) {
b->i2c_bus[1].bus_id = i2c_bus_num;
mraa_lec_al_get_pin_index(b, "I2C0_DAT", (int*) &(b->i2c_bus[0].sda));
mraa_lec_al_get_pin_index(b, "I2C0_CK", (int*) &(b->i2c_bus[0].scl));
b->i2c_bus_count++;
}
const char* pinctrl_path = "/sys/bus/platform/drivers/broxton-pinctrl";
int have_pinctrl = access(pinctrl_path, F_OK) != -1;
syslog(LOG_NOTICE, "lec_al: kernel pinctrl driver %savailable", have_pinctrl ? "" : "un");
return b;
error:
syslog(LOG_CRIT, "lec_al: Platform failed to initialise");
free(b);
close(_fd);
return NULL;
}