summaryrefslogtreecommitdiff
path: root/io-module/mtr2.c
diff options
context:
space:
mode:
Diffstat (limited to 'io-module/mtr2.c')
-rw-r--r--io-module/mtr2.c515
1 files changed, 515 insertions, 0 deletions
diff --git a/io-module/mtr2.c b/io-module/mtr2.c
new file mode 100644
index 0000000..2efc85d
--- /dev/null
+++ b/io-module/mtr2.c
@@ -0,0 +1,515 @@
+
+static struct gpio_pin gpio_pins_mtr2_0_0[] = {
+ {
+ .name = "NETH_RST",
+ .pin = {
+ .gpio = AT91_PIN_PC6,
+ .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH,
+ .label = "eth-switch-enabled",
+ },
+ },
+ {
+ .name = "RADIO_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC5,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "radio-reset",
+ },
+ },
+ {
+ .name = "RADIO_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC5,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "radio-power",
+ },
+ },
+ {
+ .name = "DEVICE_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC4,
+ .flags = GPIOF_IN,
+ .label = "reset",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LS_LED",
+ .pin = {
+ .gpio = AT91_PIN_PA14,
+#if LED_LS_CONTROLLABLE
+ .flags = GPIOF_OUT_INIT_HIGH,
+#else
+ .flags = GPIOF_IN,
+#endif
+ .label = "led-ls",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "STATUS_LED",
+ .pin = {
+ .gpio = AT91_PIN_PA24,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "led-status",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "STATUS_LED",
+ .pin = {
+ .gpio = AT91_PIN_PA24,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "led-a",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED7",
+ .pin = {
+ .gpio = AT91_PIN_PA25,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-cd",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED7",
+ .pin = {
+ .gpio = AT91_PIN_PA25,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-c",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED10",
+ .pin = {
+ .gpio = AT91_PIN_PA26,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig1",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED10",
+ .pin = {
+ .gpio = AT91_PIN_PA26,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-d",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED11",
+ .pin = {
+ .gpio = AT91_PIN_PA27,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig2",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED11",
+ .pin = {
+ .gpio = AT91_PIN_PA27,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-e",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED12",
+ .pin = {
+ .gpio = AT91_PIN_PA28,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig3",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED12",
+ .pin = {
+ .gpio = AT91_PIN_PA28,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-f",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED13",
+ .pin = {
+ .gpio = AT91_PIN_PA29,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-wifi",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED13",
+ .pin = {
+ .gpio = AT91_PIN_PA29,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-b",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "UART3_DTR",
+ .pin = {
+ .gpio = AT91_PIN_PC12,
+ .flags = GPIOF_IN,
+ .label = "extserial-dtr",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "UART3_DSR",
+ .pin = {
+ .gpio = AT91_PIN_PC11,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "extserial-dsr",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "UART3_DCD",
+ .pin = {
+ .gpio = AT91_PIN_PC10,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "extserial-dcd",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "UART3_RI",
+ .pin = {
+ .gpio = AT91_PIN_PC13,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "extserial-ri",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "NDC_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC3,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "ndc-reset",
+ },
+ },
+ {
+ .name = "NDC_EEPROM_WRITE_PROTECT",
+ .pin = {
+ .gpio = AT91_PIN_PC26,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "ndc-eeprom-wp",
+ },
+ },
+ {
+ .name = "BT_EN",
+ .pin = {
+ .gpio = AT91_PIN_PD21,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "bt-enabled",
+ },
+ },
+ {
+ .name = "WLAN_EN",
+ .pin = {
+ .gpio = AT91_PIN_PC1,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "wlan-enabled",
+ },
+ },
+ {
+ .name = "SERIAL_MODE0",
+ .pin = {
+ .gpio = AT91_PIN_PC23,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "serial-mode",
+ },
+ },
+ {
+ .name = "SERIAL_MODE1",
+ .pin = {
+ .gpio = AT91_PIN_PC24,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "serial-mode",
+ },
+ },
+ {
+ .name = "SERIAL_MODE2",
+ .pin = {
+ .gpio = AT91_PIN_PC25,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "serial-mode",
+ },
+ },
+ {
+ .name = "RS4XX_TERM_RES",
+ .pin = {
+ .gpio = AT91_PIN_PC26,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "rs4xx-term-res",
+ },
+ },
+ {
+ .name = "NDC_GPIO1",
+ .pin = {
+ .gpio = AT91_PIN_PC0,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dc-gpio1",
+ },
+ },
+ {
+ .name = "NDC_GPIO2",
+ .pin = {
+ .gpio = AT91_PIN_PC14,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dc-gpio2",
+ },
+ },
+ {
+ .name = "NDC_GPIO3",
+ .pin = {
+ .gpio = AT91_PIN_PC29,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dc-gpio3",
+ },
+ },
+ {
+ .name = "NDC_GPIO4",
+ .pin = {
+ .gpio = AT91_PIN_PC30,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "dc-gpio4",
+ },
+ },
+ {
+ .name = "NDC_INTERRUPT1",
+ .pin = {
+ .gpio = AT91_PIN_PC20,
+ .flags = GPIOF_IN,
+ .label = "dc-int1",
+ },
+ },
+ {
+ .name = "NDC_INTERRUPT2",
+ .pin = {
+ .gpio = AT91_PIN_PC21,
+ .flags = GPIOF_IN,
+ .label = "dc-int2",
+ },
+ },
+ { },
+};
+
+/* MTOCGD2 specific functions */
+static ssize_t mts_attr_show_serial_mode(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int ret;
+ int smode0;
+ int smode1;
+ int smode2;
+
+ struct gpio_pin *pin_smode0 = gpio_pin_by_name("SERIAL_MODE0");
+ struct gpio_pin *pin_smode1 = gpio_pin_by_name("SERIAL_MODE1");
+ struct gpio_pin *pin_smode2 = gpio_pin_by_name("SERIAL_MODE2");
+
+ if (!pin_smode0 || !pin_smode1 || !pin_smode2)
+ return -ENODEV;
+
+ mutex_lock(&mts_io_mutex);
+
+ smode0 = gpio_get_value(pin_smode0->pin.gpio);
+ smode1 = gpio_get_value(pin_smode1->pin.gpio);
+ smode2 = gpio_get_value(pin_smode2->pin.gpio);
+
+ if (smode2 == 0 && smode1 == 0 && smode0 == 1)
+ ret = sprintf(buf, "rs232\n");
+ else if (smode2 == 0 && smode1 == 1 && smode0 == 0)
+ ret = sprintf(buf, "rs485\n");
+ else if (smode2 == 1 && smode1 == 0 && smode0 == 0)
+ ret = sprintf(buf, "rs422\n");
+ else if (smode2 == 0 && smode1 == 0 && smode0 == 0)
+ ret = sprintf(buf, "loopback\n");
+ else
+ ret = sprintf(buf, "error\n");
+
+ mutex_unlock(&mts_io_mutex);
+
+ return ret;
+}
+
+static ssize_t mts_attr_store_serial_mode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int smode0;
+ int smode1;
+ int smode2;
+ struct gpio_pin *pin_smode0 = gpio_pin_by_name("SERIAL_MODE0");
+ struct gpio_pin *pin_smode1 = gpio_pin_by_name("SERIAL_MODE1");
+ struct gpio_pin *pin_smode2 = gpio_pin_by_name("SERIAL_MODE2");
+
+ if (!pin_smode0 || !pin_smode1 || !pin_smode2)
+ return -ENODEV;
+
+ if (!strcasecmp(buf, "rs232")) {
+ smode2 = 0;
+ smode1 = 0;
+ smode0 = 1;
+ }
+ else if (!strcasecmp(buf, "rs485")) {
+ smode2 = 0;
+ smode1 = 1;
+ smode0 = 0;
+ }
+ else if (!strcasecmp(buf, "rs422")) {
+ smode2 = 1;
+ smode1 = 0;
+ smode0 = 0;
+ }
+ else if (!strcasecmp(buf, "loopback")) {
+ smode2 = 0;
+ smode1 = 0;
+ smode0 = 0;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ gpio_set_value(pin_smode2->pin.gpio, smode2);
+ gpio_set_value(pin_smode1->pin.gpio, smode1);
+ gpio_set_value(pin_smode0->pin.gpio, smode0);
+
+ mutex_unlock(&mts_io_mutex);
+
+ return count;
+}
+
+/* MTOCGD2 specific attributes */
+static DEVICE_ATTR_MTS(dev_attr_serial_mode, "serial-mode",
+ mts_attr_show_serial_mode, mts_attr_store_serial_mode);
+static DEVICE_ATTR_MTS(dev_attr_eth_switch_enabled, "eth-switch-enabled",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+static DEVICE_ATTR_MTS(dev_attr_rs4xx_term_res, "rs4xx-term-res",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+static struct attribute *mtr2_platform_attributes[] = {
+ &dev_attr_vendor_id.attr,
+ &dev_attr_product_id.attr,
+ &dev_attr_device_id.attr,
+ &dev_attr_hw_version.attr,
+ &dev_attr_imei.attr,
+ &dev_attr_eth_mac.attr,
+ &dev_attr_wifi_mac.attr,
+ &dev_attr_reset.attr,
+ &dev_attr_reset_monitor.attr,
+ &dev_attr_radio_power.attr,
+ &dev_attr_radio_reset.attr,
+ &dev_attr_ndc_reset.attr,
+ &dev_attr_extserial_dtr.attr,
+ &dev_attr_extserial_dsr_gpio.attr,
+ &dev_attr_extserial_ri_gpio.attr,
+ &dev_attr_extserial_dcd_gpio.attr,
+ &dev_attr_eth_switch_enabled.attr,
+ &dev_attr_bt_enabled.attr,
+ &dev_attr_wlan_enabled.attr,
+
+ &dev_attr_serial_mode.attr,
+ &dev_attr_rs4xx_term_res.attr,
+
+ &dev_attr_led_status.attr,
+ &dev_attr_led_wifi_gpio.attr,
+ &dev_attr_led_cd_gpio.attr,
+ &dev_attr_led_sig1_gpio.attr,
+ &dev_attr_led_sig2_gpio.attr,
+ &dev_attr_led_sig3_gpio.attr,
+
+ &dev_attr_led_a_gpio.attr,
+ &dev_attr_led_b_gpio.attr,
+ &dev_attr_led_c_gpio.attr,
+ &dev_attr_led_d_gpio.attr,
+ &dev_attr_led_e_gpio.attr,
+ &dev_attr_led_f_gpio.attr,
+
+ &dev_attr_board_temperature.attr,
+
+ /* extra space for the daughter card attributes */
+ NULL, // index 34
+ NULL, // index 35
+ NULL, // index 36
+ NULL, // index 37
+ NULL, // index 38
+ NULL, // index 39
+ NULL, // index 40
+ NULL, // index 41
+ NULL, // index 42
+ NULL, // index 43
+ NULL, // index 44
+ NULL, // index 45
+ NULL, // index 46
+ NULL, // index 47
+ NULL, // index 48
+ NULL, // index 49
+ NULL, // index 50
+ NULL, // index 51
+ NULL,
+};
+
+static struct attribute *mtr2_daughter_card_attributes[] = {
+ &dev_attr_dc_din0.attr,
+ &dev_attr_dc_din1.attr,
+ &dev_attr_dc_din2.attr,
+ &dev_attr_dc_din3.attr,
+
+ &dev_attr_dc_dout0.attr,
+ &dev_attr_dc_dout1.attr,
+ &dev_attr_dc_dout2.attr,
+ &dev_attr_dc_dout3.attr,
+
+ &dev_attr_dc_adc0.attr,
+ &dev_attr_dc_adc1.attr,
+ &dev_attr_dc_adc2.attr,
+
+ &dev_attr_dc_led1.attr,
+ &dev_attr_dc_led2.attr,
+ &dev_attr_dc_oe.attr,
+
+ NULL,
+};
+
+static bool mtr2_add_daughter_card_attributes(void)
+{
+ size_t platform_attrs_size = sizeof(mtr2_platform_attributes) / sizeof(struct attribute *);
+ size_t daughter_card_attrs_size = sizeof(mtr2_daughter_card_attributes) / sizeof(struct attribute *);
+ size_t platform_attrs_index;
+ size_t daughter_card_attrs_index;
+ size_t copy_length = daughter_card_attrs_size - 1; /* don't need to copy the NULL at the end */
+
+ for (platform_attrs_index = 0; platform_attrs_index < platform_attrs_size; platform_attrs_index++) {
+ if (! mtr2_platform_attributes[platform_attrs_index]) {
+ break;
+ }
+ }
+
+ if (platform_attrs_size < platform_attrs_index + daughter_card_attrs_size) {
+ log_error("not enough room for MTR2 daughter card attributes!");
+ return false;
+ }
+
+ for (daughter_card_attrs_index = 0; daughter_card_attrs_index < copy_length; daughter_card_attrs_index++, platform_attrs_index++) {
+ mtr2_platform_attributes[platform_attrs_index] = mtr2_daughter_card_attributes[daughter_card_attrs_index];
+ }
+
+ return true;
+}
+
+static struct attribute_group mtr2_platform_attribute_group = {
+ .attrs = mtr2_platform_attributes
+};