summaryrefslogtreecommitdiff
path: root/io-module
diff options
context:
space:
mode:
authorJesse Gilles <jgilles@multitech.com>2014-09-04 13:38:01 -0500
committerJesse Gilles <jgilles@multitech.com>2014-09-04 13:38:01 -0500
commit5503d316c26d664117ff899c0dece6efc5ea7077 (patch)
treef37a8b7b4829162478cc3d05416baf6ae0786c3c /io-module
parentfc543eac11fbeb87fe226b8f7921725c4139bb33 (diff)
downloadmts-io-5503d316c26d664117ff899c0dece6efc5ea7077.tar.gz
mts-io-5503d316c26d664117ff899c0dece6efc5ea7077.tar.bz2
mts-io-5503d316c26d664117ff899c0dece6efc5ea7077.zip
add support for MTAC-MFSER
Diffstat (limited to 'io-module')
-rw-r--r--io-module/mtac_mfser.c215
-rw-r--r--io-module/mts_io.c35
-rw-r--r--io-module/mts_io.h2
3 files changed, 250 insertions, 2 deletions
diff --git a/io-module/mtac_mfser.c b/io-module/mtac_mfser.c
new file mode 100644
index 0000000..14eddd1
--- /dev/null
+++ b/io-module/mtac_mfser.c
@@ -0,0 +1,215 @@
+struct gpio_pin *ap_mfser_pin_by_attr_name(const char *name) {
+ struct gpio_pin *pin;
+ char *pin_attr_name;
+
+ if (!strcmp(name, "rs4xx-term-res:0")) {
+ pin_attr_name = "ap1-gpio3";
+ } else if (!strcmp(name, "rts-override:0")) {
+ pin_attr_name = "ap1-gpio4";
+ } else if (!strcmp(name, "rs4xx-term-res:1")) {
+ pin_attr_name = "ap2-gpio3";
+ } else if (!strcmp(name, "rts-override:1")) {
+ pin_attr_name = "ap2-gpio4";
+ } else {
+ log_error("accessory card attribute %s not available", name);
+ return NULL;
+ }
+
+ for (pin = gpio_pins; *pin->name; pin++) {
+ if (!strcmp(pin->pin.label, pin_attr_name)) {
+ return pin;
+ }
+ }
+
+ log_error("pin with attr name %s not found", name);
+
+ return NULL;
+}
+
+
+static ssize_t mts_attr_show_ap_mfser_pin(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int value;
+ struct gpio_pin *pin = ap_mfser_pin_by_attr_name(attr->attr.name);
+
+ 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_ap_mfser_pin(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ struct gpio_pin *pin = ap_mfser_pin_by_attr_name(attr->attr.name);
+
+ 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;
+}
+
+static ssize_t mts_attr_show_mfser_mode(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int ret;
+ int modesel0;
+ int modesel1;
+
+ struct gpio_pin *pin_modesel0;
+ struct gpio_pin *pin_modesel1;
+
+ if (strstr(attr->attr.name, ":0")) {
+ pin_modesel0 = gpio_pin_by_name("AP1_GPIO1");
+ pin_modesel1 = gpio_pin_by_name("AP1_GPIO2");
+ }
+ else if (strstr(attr->attr.name, ":1")) {
+ pin_modesel0 = gpio_pin_by_name("AP2_GPIO1");
+ pin_modesel1 = gpio_pin_by_name("AP2_GPIO2");
+ }
+ else {
+ log_error("unknown serial-mode attr %s", attr->attr.name);
+ return -ENODEV;
+ }
+
+ if (!pin_modesel0 || !pin_modesel1)
+ return -ENODEV;
+
+ mutex_lock(&mts_io_mutex);
+
+ modesel0 = gpio_get_value(pin_modesel0->pin.gpio);
+ modesel1 = gpio_get_value(pin_modesel1->pin.gpio);
+
+ if (modesel1 == 0 && modesel0 == 0)
+ ret = sprintf(buf, "loopback\n");
+ else if (modesel1 == 0 && modesel0 == 1)
+ ret = sprintf(buf, "rs232\n");
+ else if (modesel1 == 1 && modesel0 == 0)
+ ret = sprintf(buf, "rs485-half\n");
+ else if (modesel1 == 1 && modesel0 == 1)
+ ret = sprintf(buf, "rs422-485-full\n");
+ else
+ ret = sprintf(buf, "error\n");
+
+ mutex_unlock(&mts_io_mutex);
+
+ return ret;
+}
+
+static ssize_t mts_attr_store_mfser_mode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int modesel0;
+ int modesel1;
+ struct gpio_pin *pin_modesel0;
+ struct gpio_pin *pin_modesel1;
+
+ if (strstr(attr->attr.name, ":0")) {
+ pin_modesel0 = gpio_pin_by_name("AP1_GPIO1");
+ pin_modesel1 = gpio_pin_by_name("AP1_GPIO2");
+ }
+ else if (strstr(attr->attr.name, ":1")) {
+ pin_modesel0 = gpio_pin_by_name("AP2_GPIO1");
+ pin_modesel1 = gpio_pin_by_name("AP2_GPIO2");
+ }
+ else {
+ log_error("unknown serial-mode attr %s", attr->attr.name);
+ return -ENODEV;
+ }
+
+ if (!pin_modesel0 || !pin_modesel1)
+ return -ENODEV;
+
+ if (!strcasecmp(buf, "loopback")) {
+ modesel1 = 0;
+ modesel0 = 0;
+ }
+ else if (!strcasecmp(buf, "rs232")) {
+ modesel1 = 0;
+ modesel0 = 1;
+ }
+ else if (!strcasecmp(buf, "rs485-half")) {
+ modesel1 = 1;
+ modesel0 = 0;
+ }
+ else if (!strcasecmp(buf, "rs422-485-full")) {
+ modesel1 = 1;
+ modesel0 = 1;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ gpio_set_value(pin_modesel0->pin.gpio, modesel0);
+ gpio_set_value(pin_modesel1->pin.gpio, modesel1);
+
+ mutex_unlock(&mts_io_mutex);
+
+ return count;
+}
+
+/* accessory port 1 serial attributes */
+static DEVICE_ATTR_MTS(dev_attr_ap1_serial_mode, "serial-mode:0", mts_attr_show_mfser_mode, mts_attr_store_mfser_mode);
+static DEVICE_ATTR_MTS(dev_attr_ap1_rs4xx_term_res, "rs4xx-term-res:0", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin);
+static DEVICE_ATTR_MTS(dev_attr_ap1_rts_override, "rts-override:0", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin);
+
+static int ap1_mfser_attributes_size = 3; // not including NULL at end
+
+static struct attribute *ap1_mfser_attributes[] = {
+ &dev_attr_ap1_serial_mode.attr,
+ &dev_attr_ap1_rs4xx_term_res.attr, // gpio3
+ &dev_attr_ap1_rts_override.attr, // gpio4
+ NULL,
+};
+
+/* accessory port 2 serial attributes */
+static DEVICE_ATTR_MTS(dev_attr_ap2_serial_mode, "serial-mode:1", mts_attr_show_mfser_mode, mts_attr_store_mfser_mode);
+static DEVICE_ATTR_MTS(dev_attr_ap2_rs4xx_term_res, "rs4xx-term-res:1", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin);
+static DEVICE_ATTR_MTS(dev_attr_ap2_rts_override, "rts-override:1", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin);
+
+static int ap2_mfser_attributes_size = 3; // not including NULL at end
+
+static struct attribute *ap2_mfser_attributes[] = {
+ &dev_attr_ap2_serial_mode.attr,
+ &dev_attr_ap2_rs4xx_term_res.attr, // gpio3
+ &dev_attr_ap2_rts_override.attr, // gpio4
+ NULL,
+};
+
+
diff --git a/io-module/mts_io.c b/io-module/mts_io.c
index b63a756..2ecc636 100644
--- a/io-module/mts_io.c
+++ b/io-module/mts_io.c
@@ -99,6 +99,7 @@ static DEFINE_MUTEX(mts_io_mutex);
/* accessory card support */
#include "mtdc_gpiob.c"
+#include "mtac_mfser.c"
/* telit radio reset handling */
#include "telit_radio.c"
@@ -440,6 +441,10 @@ static bool add_accessory_card_attributes(int slot)
card_attrs_size = ap1_gpio_attributes_size;
card_attrs = ap1_gpio_attributes;
break;
+ case MTAC_MFSER_0_0:
+ card_attrs_size = ap1_mfser_attributes_size;
+ card_attrs = ap1_mfser_attributes;
+ break;
default:
log_error("accessory card %s isn't supported", ap1_eeprom.hw_version);
return false;
@@ -450,6 +455,10 @@ static bool add_accessory_card_attributes(int slot)
card_attrs_size = ap2_gpio_attributes_size;
card_attrs = ap2_gpio_attributes;
break;
+ case MTAC_MFSER_0_0:
+ card_attrs_size = ap2_mfser_attributes_size;
+ card_attrs = ap2_mfser_attributes;
+ break;
default:
log_error("accessory card %s isn't supported", ap2_eeprom.hw_version);
return false;
@@ -715,7 +724,10 @@ static int __init mts_io_init(void)
// more elegant way to handle this?
if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) {
mts_ap1_product_id = MTDC_GPIOB_0_0;
- } // else if (...) { }
+ }
+ else if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTAC_MFSER)) {
+ mts_ap1_product_id = MTAC_MFSER_0_0;
+ }
switch(mts_ap1_product_id) {
case MTDC_GPIOB_0_0:
@@ -747,6 +759,14 @@ static int __init mts_io_init(void)
goto error1;
}
break;
+ case MTAC_MFSER_0_0:
+ log_info("loading MFSER accessory card in slot 1");
+ if (! add_accessory_card_attributes(1)) {
+ log_error("failed to load MFSER accessory card in slot 1");
+ } else {
+ log_info("successfully loaded MFSER accessory card in slot 1");
+ }
+ break;
default:
log_error("accessory card %s unsupported", ap1_eeprom.product_id);
@@ -757,7 +777,10 @@ static int __init mts_io_init(void)
// more elegant way to handle this?
if (strstr(ap2_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) {
mts_ap2_product_id = MTDC_GPIOB_0_0;
- } // else if (...) { }
+ }
+ else if (strstr(ap2_eeprom.product_id, PRODUCT_ID_MTAC_MFSER)) {
+ mts_ap2_product_id = MTAC_MFSER_0_0;
+ }
switch(mts_ap2_product_id) {
case MTDC_GPIOB_0_0:
@@ -789,6 +812,14 @@ static int __init mts_io_init(void)
goto error1;
}
break;
+ case MTAC_MFSER_0_0:
+ log_info("loading MFSER accessory card in slot 2");
+ if (! add_accessory_card_attributes(2)) {
+ log_error("failed to load MFSER accessory card in slot 2");
+ } else {
+ log_info("successfully loaded MFSER accessory card in slot 2");
+ }
+ break;
default:
log_error("accessory card %s unsupported", ap1_eeprom.product_id);
diff --git a/io-module/mts_io.h b/io-module/mts_io.h
index cff0b2a..c76471c 100644
--- a/io-module/mts_io.h
+++ b/io-module/mts_io.h
@@ -49,6 +49,7 @@ struct device_attribute _dev_name = { \
#define PRODUCT_ID_MTR2D2 "MTR2D2"
#define PRODUCT_ID_MTDC_GPIOB "MTDC-GPIOB"
+#define PRODUCT_ID_MTAC_MFSER "MTAC-MFSER"
#define PRODUCT_ID_MTDC_ETH "MTDC-ETH"
#define HW_VERSION_MTCBA2_2_0 "MTCBA2-2.0"
@@ -79,6 +80,7 @@ enum {
enum {
MTDC_NONE,
MTDC_GPIOB_0_0,
+ MTAC_MFSER_0_0,
};
// GPIO pin types:input, output, open drain (1 = high Z, 0 = output low)