From 5503d316c26d664117ff899c0dece6efc5ea7077 Mon Sep 17 00:00:00 2001 From: Jesse Gilles Date: Thu, 4 Sep 2014 13:38:01 -0500 Subject: add support for MTAC-MFSER --- io-module/mtac_mfser.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++ io-module/mts_io.c | 35 +++++++- io-module/mts_io.h | 2 + 3 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 io-module/mtac_mfser.c 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) -- cgit v1.2.3