summaryrefslogtreecommitdiff
path: root/io-module
diff options
context:
space:
mode:
Diffstat (limited to 'io-module')
-rw-r--r--io-module/mtcap.c163
-rw-r--r--io-module/mts_io.c57
-rw-r--r--io-module/mts_lora.c114
3 files changed, 205 insertions, 129 deletions
diff --git a/io-module/mtcap.c b/io-module/mtcap.c
index e651406..d86c5a6 100644
--- a/io-module/mtcap.c
+++ b/io-module/mtcap.c
@@ -45,24 +45,27 @@ static struct gpio_pin gpio_pins_mtcap_0_0[] = {
.pin = {
.gpio = AT91_PIN_PA8, // LORA_RST
.flags = GPIOF_OUT_INIT_LOW,
- .label = "lora-reset",
+ .label = "lora/reset",
},
+ .capability = CAPA_LORA,
},
{ // gpio 1 for LORA 1.5 ref design
.name = "LORA_CDONE",
.pin = {
.gpio = AT91_PIN_PA6,
.flags = GPIOF_IN,
- .label = "lora-cdone",
+ .label = "lora/cdone",
},
+ .capability = CAPA_LORA,
},
{ // gpio 2 for LORA 1.5 ref design
.name = "LORA_CRESET",
.pin = {
.gpio = AT91_PIN_PA29,
.flags = GPIOF_OUT_INIT_HIGH,
- .label = "lora-creset",
- }
+ .label = "lora/creset",
+ },
+ .capability = CAPA_LORA,
},
@@ -357,123 +360,20 @@ static ssize_t mts_attr_show_radio_power_mtcap(struct device *dev,
return sprintf(buf, "%d\n", value);
}
-static int lora_reset_mtcap(void)
-{
- struct gpio_pin *rst_pin = gpio_pin_by_attr_name("lora-reset");
-
- if (!rst_pin) {
- return -ENODEV;
- }
-
- /*
- * drive the reset pin low, set pin high for 100ns, drive pin low
- */
- gpio_set_value(rst_pin->pin.gpio, 0);
-
- gpio_set_value(rst_pin->pin.gpio, 1);
-
- msleep(1);
-
- gpio_set_value(rst_pin->pin.gpio, 0);
-
- msleep(100);
-
- return 0;
-}
-
-static ssize_t mts_attr_store_lora_reset_mtcap(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- int err;
-
- if (sscanf(buf, "%i", &value) != 1) {
- return -EINVAL;
- }
-
- log_info("performing lora reset");
-
- mutex_lock(&mts_io_mutex);
-
- err = lora_reset_mtcap();
-
- mutex_unlock(&mts_io_mutex);
-
- if (err) {
- return err;
- }
-
- return count;
-}
-
-static int eth_reset_mtcap(void)
-{
- struct gpio_pin *rst_pin = gpio_pin_by_attr_name("eth-reset");
-
- if (!rst_pin) {
- return -ENODEV;
- }
-
- /*
- * DS00002275A (09-15-16) KSZ8091MNX/RNB DATA SHEET:
- * For warm reset, the reset (RST#) pin should be asserted low for a minimum of 500 μs.
- */
- gpio_set_value(rst_pin->pin.gpio, 0);
-
- msleep(2);
-
- gpio_set_value(rst_pin->pin.gpio, 1);
-
- msleep(1);
-
- return 0;
-}
-
-static ssize_t mts_attr_store_eth_reset_mtcap(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- int err;
-
- if (sscanf(buf, "%i", &value) != 1) {
- return -EINVAL;
- }
-
- log_info("performing eth reset");
-
- mutex_lock(&mts_io_mutex);
-
- err = eth_reset_mtcap();
-
- mutex_unlock(&mts_io_mutex);
-
- if (err) {
- return err;
- }
-
- return count;
-}
-
static DEVICE_ATTR_MTS(dev_attr_radio_reset_mtcap, "radio-reset",
- mts_attr_show_gpio_pin, mts_attr_store_radio_reset_mtcap);
+ mts_attr_show_gpio_pin, mts_attr_store_radio_reset_mtcap);
static DEVICE_ATTR_MTS(dev_attr_radio_power_mtcap, "radio-power",
mts_attr_show_radio_power_mtcap, mts_attr_store_radio_power_mtcap);
-static DEVICE_ATTR_MTS(dev_attr_lora_reset_mtcap, "lora-reset",
- mts_attr_show_gpio_pin, mts_attr_store_lora_reset_mtcap);
-
static DEVICE_ATTR_MTS(dev_attr_eth_reset_mtcap, "eth-reset",
- mts_attr_show_gpio_pin, mts_attr_store_eth_reset_mtcap);
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
static DEVICE_ATTR_MTS(dev_attr_led_lora_gpio_mtcap, "led-lora",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
static DEVICE_ATTR_MTS(dev_attr_led_wifi_gpio_mtcap, "led-wifi",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
-static DEVICE_ATTR_RO_MTS(dev_attr_lora_eui, "lora-eui",
- mts_attr_show_product_info);
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
static struct attribute *mtcap_0_0_platform_attributes[] = {
&dev_attr_vendor_id.attr,
@@ -489,8 +389,6 @@ static struct attribute *mtcap_0_0_platform_attributes[] = {
&dev_attr_eth_reset_mtcap.attr,
- &dev_attr_lora_reset_mtcap.attr,
-
&dev_attr_radio_power_mtcap.attr,
&dev_attr_radio_reset_mtcap.attr,
@@ -503,11 +401,46 @@ static struct attribute *mtcap_0_0_platform_attributes[] = {
&dev_attr_led_lora_gpio_mtcap.attr,
&dev_attr_led_wifi_gpio_mtcap.attr,
- &dev_attr_lora_eui.attr,
-
NULL,
};
static struct attribute_group mtcap_0_0_platform_attribute_group = {
.attrs = mtcap_0_0_platform_attributes
};
+
+
+//
+// on-board LORA attributes are to be stored in the lora/ sub-directory
+//
+//
+static DEVICE_ATTR_MTS(dev_attr_lora_reset_mtcap, "reset",
+ mts_attr_show_lora_gpio_pin, mts_attr_store_lora_gpio_pin);
+
+static DEVICE_ATTR_RO_MTS(dev_attr_lora_cdone_mtcap, "cdone",
+ mts_attr_show_lora_gpio_pin);
+
+static DEVICE_ATTR_MTS(dev_attr_lora_creset_mtcap, "creset",
+ mts_attr_show_lora_gpio_pin, mts_attr_store_lora_gpio_pin);
+
+static DEVICE_ATTR_RO_MTS(dev_attr_lora_eui_mtcap, "eui",
+ mts_attr_show_lora_product_info);
+
+static DEVICE_ATTR_RO_MTS(dev_attr_lora_product_id_mtcap, "product-id",
+ mts_attr_show_lora_product_info);
+
+static DEVICE_ATTR_RO_MTS(dev_attr_lora_hw_version_mtcap, "hw-version",
+ mts_attr_show_lora_product_info);
+
+static struct attribute *mtcap_0_0_lora_attributes[] = {
+ &dev_attr_lora_eui_mtcap.attr,
+ &dev_attr_lora_product_id_mtcap.attr,
+ &dev_attr_lora_hw_version_mtcap.attr,
+ &dev_attr_lora_reset_mtcap.attr,
+ &dev_attr_lora_cdone_mtcap.attr,
+ &dev_attr_lora_creset_mtcap.attr,
+ NULL,
+};
+
+static struct attribute_group mtcap_0_0_lora_attribute_group = {
+ .attrs = mtcap_0_0_lora_attributes
+};
diff --git a/io-module/mts_io.c b/io-module/mts_io.c
index 547f099..f1f8cb6 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.5.0"
+#define DRIVER_VERSION "v1.5.1"
#define DRIVER_AUTHOR "James Maki <jmaki@multitech.com>"
#define DRIVER_DESC "MTS-IO Controller"
#define DRIVER_NAME "mts-io"
@@ -77,6 +77,7 @@ static struct mts_id_eeprom_layout id_eeprom;
static uint8_t mts_hw_version;
static struct platform_device *mts_io_platform_device;
static struct attribute_group *attr_group;
+static struct attribute_group *attr_group_lora; // on-board lora peripheral to be stored in the lora/ sub-directory
static struct gpio_pin *gpio_pins;
static DEFINE_MUTEX(mts_io_mutex);
@@ -633,10 +634,14 @@ static DEVICE_ATTR_RO_MTS(dev_attr_imei, "imei",
static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth",
mts_attr_show_product_info);
+/* include on-board lora peripheral */
+#include "mts_lora.c"
+
/* include per-device pins and attributes */
#include "mtcdt.c"
#include "mtcap.c"
+
#if NUM_AP > 0
/* accessory card EEPROMs */
@@ -765,6 +770,25 @@ static void init_accessory_ports(void) {}
static void teardown_accessory_ports(void) {}
#endif
+static void init_ports(void)
+{
+ if (DEVICE_CAPA(id_eeprom.capa, CAPA_LORA) && attr_group_lora) {
+ mts_load_lora_port();
+ }
+
+ init_accessory_ports();
+}
+
+static void teardown_ports(void)
+{
+ if (DEVICE_CAPA(id_eeprom.capa, CAPA_LORA) && attr_group_lora) {
+ mts_teardown_lora_port();
+ }
+
+ teardown_accessory_ports();
+}
+
+
struct attribute *freelater = NULL; // Storage to free when driver is unloaded.
static int mts_id_eeprom_load()
@@ -789,6 +813,9 @@ static int mts_id_eeprom_load()
} else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTCAP_0_0, strlen(HW_VERSION_MTCAP_0_0)) == 0) {
attr_group = &mtcap_0_0_platform_attribute_group;
gpio_pins = gpio_pins_mtcap_0_0;
+ if (DEVICE_CAPA(id_eeprom.capa, CAPA_LORA)) {
+ attr_group_lora = &mtcap_0_0_lora_attribute_group;
+ }
mts_hw_version = MTCAP_0_0;
log_info("detected board %s", HW_VERSION_MTCAP_0_0);
}
@@ -851,6 +878,7 @@ static int mts_id_eeprom_load()
log_info("capa-bluetooth: %s", DEVICE_CAPA(id_eeprom.capa, CAPA_BLUETOOTH) ? "yes" : "no");
log_info("capa-wifi-bluetooth: %s", DEVICE_CAPA(id_eeprom.capa, CAPA_WIFI_BT) ? "yes" : "no");
log_info("capa-gnss: %s", DEVICE_CAPA(id_eeprom.capa, CAPA_GNSS) ? "yes" : "no");
+ log_info("capa-lora: %s", DEVICE_CAPA(id_eeprom.capa, CAPA_LORA) ? "yes" : "no");
if (DEVICE_CAPA(id_eeprom.capa, CAPA_BLUETOOTH)) {
log_info("mac-bluetooth: %02X:%02X:%02X:%02X:%02X:%02X",
@@ -877,17 +905,18 @@ static int mts_id_eeprom_load()
}
log_info("uuid: %s", (char*)buf);
- if (mts_hw_version == MTCAP_0_0) {
- log_info("lora-eui: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
- id_eeprom.lora_eui[0],
- id_eeprom.lora_eui[1],
- id_eeprom.lora_eui[2],
- id_eeprom.lora_eui[3],
- id_eeprom.lora_eui[4],
- id_eeprom.lora_eui[5],
- id_eeprom.lora_eui[6],
- id_eeprom.lora_eui[7]);
- }
+ log_info("lora-eui: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
+ id_eeprom.lora_eui[0],
+ id_eeprom.lora_eui[1],
+ id_eeprom.lora_eui[2],
+ id_eeprom.lora_eui[3],
+ id_eeprom.lora_eui[4],
+ id_eeprom.lora_eui[5],
+ id_eeprom.lora_eui[6],
+ id_eeprom.lora_eui[7]);
+
+ log_info("lora-product-id: %.32s", id_eeprom.lora_product_id);
+ log_info("lora-hw-version: %.32s", id_eeprom.lora_hw_version);
return 0;
}
@@ -899,7 +928,7 @@ static void cleanup(void)
platform_device_unregister(mts_io_platform_device);
}
- teardown_accessory_ports();
+ teardown_ports();
if(freelater) {
kfree(freelater);
freelater = NULL;
@@ -933,7 +962,7 @@ static int __init mts_io_init(void)
return ret;
}
- init_accessory_ports();
+ init_ports();
ret = sysfs_create_group(&mts_io_platform_device->dev.kobj, attr_group);
if (ret) {
diff --git a/io-module/mts_lora.c b/io-module/mts_lora.c
new file mode 100644
index 0000000..7b7e204
--- /dev/null
+++ b/io-module/mts_lora.c
@@ -0,0 +1,114 @@
+static struct kobject *mts_lora_kobject;
+
+static void mts_load_lora_port(void)
+{
+ // create lora/ subdir
+ mts_lora_kobject = kobject_create_and_add("lora", &mts_io_platform_device->dev.kobj);
+
+ if (sysfs_create_group(mts_lora_kobject, attr_group_lora)) {
+ log_error("failed to create lora attributes");
+ }
+}
+
+static void mts_teardown_lora_port(void)
+{
+ // clean up "lora/" kobject if it exists
+ if (mts_lora_kobject) {
+ kobject_put(mts_lora_kobject);
+ }
+}
+
+static ssize_t mts_attr_show_lora_product_info(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ ssize_t value;
+
+ char label[32];
+ snprintf(label, sizeof label, "%s/%s", kobj->name, attr->attr.name);
+
+ if (strcmp(label, "lora/eui") == 0) {
+ value = sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+ id_eeprom.lora_eui[0],
+ id_eeprom.lora_eui[1],
+ id_eeprom.lora_eui[2],
+ id_eeprom.lora_eui[3],
+ id_eeprom.lora_eui[4],
+ id_eeprom.lora_eui[5],
+ id_eeprom.lora_eui[6],
+ id_eeprom.lora_eui[7]);
+ }
+ else if (strcmp(label, "lora/product-id") == 0) {
+ value = sprintf(buf, "%.32s\n", id_eeprom.lora_product_id);
+ }
+ else if (strcmp(label, "lora/hw-version") == 0) {
+ value = sprintf(buf, "%.32s\n", id_eeprom.lora_hw_version);
+ }
+ else {
+ log_error("attribute '%s' not found", label);
+ value = -1;
+ }
+ return value;
+}
+
+static ssize_t mts_attr_show_lora_gpio_pin(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ int value;
+ struct gpio_pin *pin;
+
+ char pin_label[32];
+ snprintf(pin_label, sizeof pin_label, "%s/%s", kobj->name, attr->attr.name); // ex. lora/reset
+
+ pin = gpio_pin_by_attr_name(pin_label);
+ if (!pin) {
+ return -ENODEV;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ value = gpio_get_value(pin->pin.gpio);
+
+ mutex_unlock(&mts_io_mutex);
+
+ if (value < 0) {
+ return value;
+ }
+
+ if (pin->active_low) {
+ value = !value;
+ }
+
+ return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t mts_attr_store_lora_gpio_pin(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ struct gpio_pin *pin;
+ char pin_label[32];
+
+ snprintf(pin_label, sizeof pin_label, "%s/%s", kobj->name, attr->attr.name); // ex. lora/reset
+
+ pin = gpio_pin_by_attr_name(pin_label);
+ if (!pin) {
+ return -ENODEV;
+ }
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+
+ if (pin->active_low) {
+ value = !value;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ gpio_set_value(pin->pin.gpio, value);
+
+ mutex_unlock(&mts_io_mutex);
+
+ return count;
+}