diff options
author | Jesse Gilles <jgilles@multitech.com> | 2014-09-04 13:38:01 -0500 |
---|---|---|
committer | Jesse Gilles <jgilles@multitech.com> | 2014-09-04 13:38:01 -0500 |
commit | 5503d316c26d664117ff899c0dece6efc5ea7077 (patch) | |
tree | f37a8b7b4829162478cc3d05416baf6ae0786c3c /io-module/mtac_mfser.c | |
parent | fc543eac11fbeb87fe226b8f7921725c4139bb33 (diff) | |
download | mts-io-5503d316c26d664117ff899c0dece6efc5ea7077.tar.gz mts-io-5503d316c26d664117ff899c0dece6efc5ea7077.tar.bz2 mts-io-5503d316c26d664117ff899c0dece6efc5ea7077.zip |
add support for MTAC-MFSER
Diffstat (limited to 'io-module/mtac_mfser.c')
-rw-r--r-- | io-module/mtac_mfser.c | 215 |
1 files changed, 215 insertions, 0 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, +}; + + |