From c3ae43430ccf0cf92a4fa2d4bcf0024b53dbac7a Mon Sep 17 00:00:00 2001 From: Mykyta Dorokhin Date: Wed, 2 Nov 2016 17:04:34 +0200 Subject: feat: expose on-board lora attributes oveer lora/ subdirectory --- io-module/mtcap.c | 163 +++++++++++++++------------------------------------ io-module/mts_io.c | 57 +++++++++++++----- io-module/mts_lora.c | 114 +++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+), 129 deletions(-) create mode 100644 io-module/mts_lora.c 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 " #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; +} -- cgit v1.2.3