summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Klug <john.klug@multitech.com>2016-09-30 17:22:00 -0500
committerJohn Klug <john.klug@multitech.com>2016-09-30 17:22:00 -0500
commitcf9e2ae0c4193f784138e098c929a36a9aaa8854 (patch)
treea9b66d291b8d852c4e5ed71b709fdabe7d154322
parent670c959a9bdfd4aaae25a6d0c30e31d29b6761de (diff)
downloadmts-io-cf9e2ae0c4193f784138e098c929a36a9aaa8854.tar.gz
mts-io-cf9e2ae0c4193f784138e098c929a36a9aaa8854.tar.bz2
mts-io-cf9e2ae0c4193f784138e098c929a36a9aaa8854.zip
mts-io driver for Lora-H and additional resets
-rw-r--r--io-module/gpio.c16
-rw-r--r--io-module/mtac_gpiob.c6
-rw-r--r--io-module/mtac_lora.c82
-rw-r--r--io-module/mtcdt.c102
-rw-r--r--io-module/mts_io.c12
-rw-r--r--io-module/mts_io.h1
-rw-r--r--io-module/mts_io.mod.c23
7 files changed, 212 insertions, 30 deletions
diff --git a/io-module/gpio.c b/io-module/gpio.c
index 4a2d963..9e643a4 100644
--- a/io-module/gpio.c
+++ b/io-module/gpio.c
@@ -13,6 +13,22 @@ struct gpio_pin *gpio_pin_by_name(const char *name) {
return NULL;
}
+// A GPIO pin number must only occur once.
+struct gpio_pin *gpio_pin_by_num(unsigned num) {
+ int ipin = 0;
+ while(*(gpio_pins[ipin].name)) {
+ if (gpio_pins[ipin].pin.gpio == num) {
+ return &(gpio_pins[ipin]);
+ }
+ ipin++;
+ }
+
+ log_error("pin numbered %u not found", num);
+
+ return NULL;
+}
+
+
struct gpio_pin *gpio_pin_by_attr_name(const char *name) {
struct gpio_pin *pin;
diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c
index 0485494..3dbd828 100644
--- a/io-module/mtac_gpiob.c
+++ b/io-module/mtac_gpiob.c
@@ -154,7 +154,7 @@ static char* gpiob_gpio_pin_name_by_attr_name(const char* name, int port) {
} else if (! strcmp(name, "reset")) {
return "ap1-reset";
} else {
- log_error("attirbute name [%s] is invalid for GPIOB in port %d", name, port);
+ log_error("attribute name [%s] is invalid for GPIOB in port %d", name, port);
return "";
}
@@ -168,10 +168,12 @@ static char* gpiob_gpio_pin_name_by_attr_name(const char* name, int port) {
} else if (! strcmp(name, "reset")) {
return "ap2-reset";
} else {
- log_error("attirbute name [%s] is invalid for GPIOB in port %d", name, port);
+ log_error("attribute name [%s] is invalid for GPIOB in port %d", name, port);
return "";
}
}
+ log_error("gpiob: Invalid port number");
+ return "";
}
static ssize_t mts_attr_show_ap_din(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
diff --git a/io-module/mtac_lora.c b/io-module/mtac_lora.c
index 29e37ff..a0907c8 100644
--- a/io-module/mtac_lora.c
+++ b/io-module/mtac_lora.c
@@ -3,16 +3,24 @@ static char* lora_gpio_pin_name_by_attr_name(const char* name, int port) {
case port_1:
if (! strcmp(name, "reset")) {
return "ap1-reset";
+ } else if (!strcmp(name,"cdone")) {
+ return "ap1-cdone";
+ } else if (!strcmp(name,"creset")) {
+ return "ap1-creset";
} else {
- log_error("attirbute name [%s] is invalid for LORA in port %d", name, port);
+ log_error("attribute name [%s] is invalid for LORA in port %d", name, port);
return "";
}
case port_2:
if (! strcmp(name, "reset")) {
return "ap2-reset";
+ } else if (!strcmp(name,"cdone")) {
+ return "ap2-cdone";
+ } else if (!strcmp(name,"creset")) {
+ return "ap2-creset";
} else {
- log_error("attirbute name [%s] is invalid for LORA in port %d", name, port);
+ log_error("attribute name [%s] is invalid for LORA in port %d", name, port);
return "";
}
}
@@ -24,9 +32,10 @@ static char* lora_gpio_pin_name_by_attr_name(const char* name, int port) {
// 1 device-id
// 1 hw-version
// 1 eui
-// 1 reset
+// 1 cdone
+// 1 creset
// NULL
-static size_t ap_lora_attrs_size = 8;
+static size_t ap_lora_attrs_size = 9;
// Set the hardware version if the ROM string matches one of the valid
// hardware versions.
@@ -77,7 +86,8 @@ static bool lora_setup(enum ap port) {
ret = sysfs_create_link(ap_subdirs[port_index]->parent, ap_subdirs[port_index], buf);
if (ret) {
log_error("failed to link [%s] to [%s], %d", buf, ap_subdirs[port_index]->name, ret);
- }
+ } else
+ log_info("created link [%s] to [%s], success:%d", buf, ap_subdirs[port_index]->name, ret);
attrs = kzalloc(sizeof(struct attribute*) * ap_lora_attrs_size, GFP_KERNEL);
if (! attrs) {
@@ -110,17 +120,73 @@ static bool lora_setup(enum ap port) {
attr->store = mts_attr_store_ap_gpio_pin;
attrs[index++] = &attr->attr;
}
+ else if (lora_hw_version == MTAC_LORA_1_5) {
+ // Substitute pins for this port
+ log_info("Substitute pins");
+ int ipin = 0;
+ while(*(lora_h[port_index][ipin].name)) {
+ struct gpio_pin *p;
+ p = gpio_pin_by_num(lora_h[port_index][ipin].pin.gpio);
+ if(p) {
+ log_info("LORA H: Replace name %s with name %s",p->name,lora_h[port_index][ipin].name);
+ log_info("LORA H: Replace pin number %u with number %u",p->pin.gpio,lora_h[port_index][ipin].pin.gpio);
+ *p = lora_h[port_index][ipin];
+ }
+ ipin++;
+ }
+
+ //add support for reset
+ sprintf(buf, "reset");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ log_error("failed to create attribute [%s] for LORA in port %d", buf, port);
+ kfree(attrs);
+ return false;
+ }
+ attr->show = mts_attr_show_ap_gpio_pin;
+ attr->store = mts_attr_store_ap_gpio_pin;
+ attrs[index++] = &attr->attr;
+
+ //GPIO1 - cdone on FPGA - input to CPU
+ sprintf(buf, "cdone");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RO);
+ if (! attr) {
+ log_error("failed to create attribute [%s] for LORA in port %d", buf, port);
+ kfree(attrs);
+ return false;
+ }
+ attr->show = mts_attr_show_ap_gpio_pin;
+ attrs[index++] = &attr->attr;
+
+ //GPIO2 reset on FPGA - output from CPU
+ sprintf(buf, "creset");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ log_error("failed to create attribute [%s] for LORA in port %d", buf, port);
+ kfree(attrs);
+ return false;
+ }
+ attr->show = mts_attr_show_ap_gpio_pin;
+ attr->store = mts_attr_store_ap_gpio_pin;
+ attrs[index++] = &attr->attr;
+ if(index >= ap_lora_attrs_size) {
+ panic("Internal error, too many attributes on the LORA card index %d >= %d",
+ index,ap_lora_attrs_size);
+ }
+ }
// add attributes for eeprom contents
ret = ap_add_product_info_attributes(port, lora_hw_version, attrs, &index);
- attrs[index] = NULL;
- ap_attr_groups[port_index].attrs = attrs;
+
+ attrs[index] = NULL; // Terminate the array.
+ ap_attr_groups[port_index].attrs = attrs; // attrs available for teardown.
if (!ret) {
log_error("failed to add product info attributes for LORA in port %d", port);
return false;
}
-
+ log_info("ap_subdirs[port_index=%d] = %p ap_subdirs[port_index=%d]=%p",
+ port_index,ap_subdirs[port_index],port_index,&ap_attr_groups[port_index]);
if (sysfs_create_group(ap_subdirs[port_index], &ap_attr_groups[port_index])) {
log_error("sysfs_create_group failed for LORA in port %d", port);
return false;
diff --git a/io-module/mtcdt.c b/io-module/mtcdt.c
index 156bd27..21edcfe 100644
--- a/io-module/mtcdt.c
+++ b/io-module/mtcdt.c
@@ -1,3 +1,8 @@
+/*
+ * Within a struct gpio_pin, there is only one
+ * occurance of each pin, so there is only one
+ * pin label set for each gpio pin.
+ */
static struct gpio_pin gpio_pins_mtcdt_0_0[] = {
{
.name = "RADIO_RESET",
@@ -436,7 +441,7 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
}
},
- // gpio pins for Accessory Card 2
+ // gpio pin for Accessory Card 2
{
.name = "AP2_RESET",
.pin = {
@@ -446,6 +451,15 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
}
},
{
+ .name = "ETH_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC4,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "eth-reset",
+ }
+ },
+ // gpio pin for Accessory Card 2
+ {
.name = "AP2_GPIO1",
.pin = {
.gpio = AT91_PIN_PC20,
@@ -500,7 +514,8 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
.gpio = AT91_PIN_PA0,
.flags = GPIOF_IN,
.label = "wifi-bt-ulpwkup",
- }
+ },
+ .capability = CAPA_WIFI_BT,
},
{
.name = "WIFI_BT_LPWKUP",
@@ -508,7 +523,8 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
.gpio = AT91_PIN_PA6,
.flags = GPIOF_IN,
.label = "wifi-bt-lpwkup",
- }
+ },
+ .capability = CAPA_WIFI_BT,
},
{
.name = "WIFI_BT_INT",
@@ -516,7 +532,8 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
.gpio = AT91_PIN_PB11,
.flags = GPIOF_IN,
.label = "wifi-bt-int",
- }
+ },
+ .capability = CAPA_WIFI_BT,
},
{
.name = "WIFI_BT_RESET",
@@ -524,15 +541,8 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
.gpio = AT91_PIN_PD14,
.flags = GPIOF_OUT_INIT_HIGH,
.label = "wifi-bt-reset",
- }
- },
- {
- .name = "WIFI_BT_LPMODE",
- .pin = {
- .gpio = AT91_PIN_PD20,
- .flags = GPIOF_IN,
- .label = "wifi-bt-lpmode",
- }
+ },
+ .capability = CAPA_WIFI_BT,
},
{
.name = "GNSS_RESET",
@@ -540,7 +550,8 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
.gpio = AT91_PIN_PD15,
.flags = GPIOF_OUT_INIT_HIGH,
.label = "gnss-reset",
- }
+ },
+ .capability = CAPA_GNSS,
},
{
.name = "SECURE_RESET",
@@ -572,10 +583,63 @@ static struct gpio_pin gpio_pins_mtcdt_0_1[] = {
.gpio = AT91_PIN_PD19,
.flags = GPIOF_OUT_INIT_HIGH,
.label = "gnss-int",
- }
+ },
+ .capability = CAPA_GNSS,
},
+ {
+ .name = "WIFI_BT_LPMODE",
+ .pin = {
+ .gpio = AT91_PIN_PD20,
+ .flags = GPIOF_IN,
+ .label = "wifi-bt-lpmode",
+ },
+ .capability = CAPA_WIFI_BT,
+ },
+ { },
+};
+// LORA H or 1.5, AP1
+static struct gpio_pin lora_h[3 /* Port */][3 /* Pin */] = {
+ { // port 1 of 2
+ { // gpio 1 for LORA H
+ .name = "AP1_CDONE",
+ .pin = {
+ .gpio = AT91_PIN_PC6,
+ .flags = GPIOF_IN,
+ .label = "ap1-cdone",
+ },
+ },
+ { // gpio 2 for LORA H
+ .name = "AP1_CRESET",
+ .pin = {
+ .gpio = AT91_PIN_PC7,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "ap1-creset",
+ }
+ },
{ },
+ }, // End of port 1
+// LORA H or 1.5, AP2
+ { // Port 2 of 2
+ { // gpio 1 for LORA H
+ .name = "AP2_CDONE",
+ .pin = {
+ .gpio = AT91_PIN_PC20,
+ .flags = GPIOF_IN,
+ .label = "ap2-cdone",
+ },
+ },
+ { // gpio 2 for LORA H
+ .name = "AP2_CRESET",
+ .pin = {
+ .gpio = AT91_PIN_PC21,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "ap2-creset",
+ }
+ },
+ { },
+ }, // End of port 2
+ { },
};
static DEVICE_ATTR_MTS(dev_attr_wifi_bt_lpwkup, "wifi-bt-lpwkup",
@@ -592,6 +656,12 @@ static DEVICE_ATTR_MTS(dev_attr_gnss_reset, "gnss-reset",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
static DEVICE_ATTR_MTS(dev_attr_usbhub_reset, "usbhub-reset",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+static DEVICE_ATTR_MTS(dev_attr_eth_reset, "eth-reset",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+static DEVICE_ATTR_MTS(dev_attr_gnss_int, "gnss-int",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+
static struct attribute *mtcdt_platform_attributes[] = {
&dev_attr_vendor_id.attr,
@@ -659,7 +729,9 @@ static struct attribute *mtcdt_0_1_platform_attributes[] = {
&dev_attr_wifi_bt_lpmode.attr,
&dev_attr_wifi_bt_int,
&dev_attr_gnss_reset.attr,
+ &dev_attr_gnss_int.attr,
&dev_attr_usbhub_reset.attr,
+ &dev_attr_eth_reset.attr,
NULL,
};
diff --git a/io-module/mts_io.c b/io-module/mts_io.c
index f3b79d5..1122127 100644
--- a/io-module/mts_io.c
+++ b/io-module/mts_io.c
@@ -47,7 +47,7 @@
#include "mts_io.h"
-#define DRIVER_VERSION "v1.3.3"
+#define DRIVER_VERSION "v1.3.3.8"
#define DRIVER_AUTHOR "James Maki <jmaki@multitech.com>"
#define DRIVER_DESC "MTS-IO Controller"
#define DRIVER_NAME "mts-io"
@@ -503,7 +503,7 @@ static ssize_t mts_attr_show_radio_reset_backoff_seconds(struct device *dev,
if (strcmp(attr->attr.name, "radio-reset-backoff-seconds") == 0) {
if (radio_reset_timer_is_start == 1) {
- value = sprintf(buf, "%d", (timings_data_stop_seconds - time_now_secs()));
+ value = sprintf(buf, "%u", (timings_data_stop_seconds - time_now_secs()));
} else {
value = sprintf(buf, "%d", 0);
}
@@ -881,9 +881,11 @@ static int __init mts_io_init(void)
}
for (pin = gpio_pins; *pin->name; pin++) {
- ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label);
- if (ret) {
- log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret);
+ log_info("MTS: name %s: capability=%x, DEVICE_CAPA=%d",pin->name,pin->capability,id_eeprom.capa[DEVICE_CAPA_INDEX(pin->capability)]);
+ if (pin->capability == 0 || DEVICE_CAPA(id_eeprom.capa,pin->capability)) {
+ ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label);
+ if (ret)
+ log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret);
}
}
diff --git a/io-module/mts_io.h b/io-module/mts_io.h
index fefc35e..ee3a5a1 100644
--- a/io-module/mts_io.h
+++ b/io-module/mts_io.h
@@ -100,6 +100,7 @@ struct gpio_pin {
char name[32];
struct gpio pin;
int active_low;
+ uint8_t capability;
};
enum {
diff --git a/io-module/mts_io.mod.c b/io-module/mts_io.mod.c
new file mode 100644
index 0000000..3a3ab0a
--- /dev/null
+++ b/io-module/mts_io.mod.c
@@ -0,0 +1,23 @@
+#include <linux/module.h>
+#include <linux/vermagic.h>
+#include <linux/compiler.h>
+
+MODULE_INFO(vermagic, VERMAGIC_STRING);
+
+struct module __this_module
+__attribute__((section(".gnu.linkonce.this_module"))) = {
+ .name = KBUILD_MODNAME,
+ .init = init_module,
+#ifdef CONFIG_MODULE_UNLOAD
+ .exit = cleanup_module,
+#endif
+ .arch = MODULE_ARCH_INIT,
+};
+
+static const char __module_depends[]
+__used
+__attribute__((section(".modinfo"))) =
+"depends=";
+
+
+MODULE_INFO(srcversion, "D7BC1A1F207E0D4DA8EBD43");