summaryrefslogtreecommitdiff
path: root/io-module/machine/mtre.c
diff options
context:
space:
mode:
Diffstat (limited to 'io-module/machine/mtre.c')
-rw-r--r--io-module/machine/mtre.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/io-module/machine/mtre.c b/io-module/machine/mtre.c
new file mode 100644
index 0000000..e3df31c
--- /dev/null
+++ b/io-module/machine/mtre.c
@@ -0,0 +1,282 @@
+static struct gpio_pin gpio_pins_mtre_0_0[] = {
+ {
+ .name = "ETH_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC6,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "eth-reset",
+ },
+ .active_low = 0,
+ },
+ {
+ .name = "RADIO_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC3,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "radio-reset",
+ },
+ .active_low = 0,
+ },
+ {
+ .name = "RADIO_POWER",
+ .pin = {
+ .gpio = AT91_PIN_PC3,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "radio-power",
+ },
+ .active_low = 0,
+ },
+ {
+ .name = "DEVICE_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC4,
+ .flags = GPIOF_IN,
+ .label = "reset",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "RI_B",
+ .pin = {
+ .gpio = AT91_PIN_PC25,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "extserial-ri",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "DTR_B",
+ .pin = {
+ .gpio = AT91_PIN_PC26,
+ .flags = GPIOF_IN,
+ .label = "extserial-dtr",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "DSR_B",
+ .pin = {
+ .gpio = AT91_PIN_PC27,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "extserial-dsr",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "DCD_B",
+ .pin = {
+ .gpio = AT91_PIN_PC28,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "extserial-dcd",
+ },
+ .active_low = 1,
+ },
+ { },
+};
+
+static
+struct mts_led mtre_0_0_leds[] = {
+ {.label = "led-cd",}, /* (cellular) Link Status */
+ {.label = "led-sig1",}, /* (cellular) Link Quality */
+ {.label = "led-sig2",}, /* (cellular) Link Quality */
+ {.label = "led-sig3",}, /* (cellular) Link Quality */
+ {.label = "led-sig4",}, /* (cellular) Link Quality */
+ {.label = "led-alarm",}, /* Alarm */
+ {.label = "led-no-alarm",}, /* Enabled (out-of-phase with Alarm) */
+ {}
+};
+
+/* Initial state of ALARM is "no alarm" = 0, "major alarm" state is 1 */
+/* alarm_mtre value represents alarm state and controls both ALARM and NO-ALARM LEDs */
+static int alarm_mtre = 0;
+
+/* Initial state of DEVICE_READY is "not ready", "ready" state is 1 */
+/* If device_ready_mtre is 0 than NO-ALARM (marked ENABLED on the front panel) LED should be turned off */
+static int device_ready_mtre = 0;
+
+static unsigned long delay_on_alarm_mtre = 1000;
+static unsigned long delay_off_alarm_mtre = 1;
+static unsigned long delay_on_no_alarm_mtre = 1000;
+static unsigned long delay_off_no_alarm_mtre = 1;
+
+static
+void mts_update_alarm_mtre(int value)
+{
+ const struct mts_led *led_alarm = mts_led_by_label("led-alarm");
+ const struct mts_led *led_no_alarm = mts_led_by_label("led-no-alarm");
+
+ if (!led_alarm || !led_no_alarm) {
+ return;
+ }
+
+ if (value > 2) {
+ /* just update the LEDs with current state */
+ value = alarm_mtre;
+ }
+
+ if (value == 0) {
+ /* NO ALARM */
+ alarm_mtre = 0;
+ mts_led_set(led_alarm, 1); /* turn ALARM LED off (note: inverted pin) */
+ mts_led_set(led_no_alarm, device_ready_mtre); /* turn on NO-ALARM only if "device ready" */
+ }
+ else if (value == 1) {
+ /* ALARM */
+ alarm_mtre = 1;
+ mts_led_set(led_alarm, 0); /* turn ALARM LED on (note: inverted pin) */
+ mts_led_set(led_no_alarm, 0); /* turn off NO-ALARM */
+ }
+ else if (value == 2 && alarm_mtre != 1) {
+ /* Minor ALARM: blink for 1 second if there is no "major alarm" */
+ delay_on_alarm_mtre = 1;
+ delay_off_alarm_mtre = 1000;
+ mts_led_blink(led_alarm, &delay_on_alarm_mtre, &delay_off_alarm_mtre, 1); /* blink ALARM LED (note: inverted) */
+
+ if (device_ready_mtre) {
+ /* blink NO-ALARM only if "device ready" */
+ delay_on_no_alarm_mtre = 1;
+ delay_off_no_alarm_mtre = 1000;
+ mts_led_blink(led_no_alarm, &delay_on_no_alarm_mtre, &delay_off_no_alarm_mtre, 1);
+ }
+ }
+}
+
+static
+ssize_t mts_attr_store_alarm_mtre(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+
+ mts_update_alarm_mtre(value);
+
+ return count;
+}
+
+static
+ssize_t mts_attr_show_alarm_mtre(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", alarm_mtre);
+}
+
+static
+ssize_t mts_attr_store_device_ready_mtre(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+
+ if (value == 0) {
+ device_ready_mtre = 0;
+ }
+ else if (value == 1) {
+ device_ready_mtre = 1;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ /* just update the LEDs with current state */
+ mts_update_alarm_mtre(100);
+
+ return count;
+}
+
+static
+ssize_t mts_attr_show_device_ready_mtre(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", device_ready_mtre);
+}
+
+static DEVICE_ATTR_MTS(dev_attr_eth_reset_mtre, "eth-reset",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+static DEVICE_ATTR_MTS(dev_attr_extserial_ri_gpio_mtre, "extserial-ri",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+static DEVICE_ATTR_RO_MTS(dev_attr_extserial_dtr_gpio_mtre, "extserial-dtr",
+ mts_attr_show_gpio_pin);
+
+static DEVICE_ATTR_MTS(dev_attr_extserial_dsr_gpio_mtre, "extserial-dsr",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+static DEVICE_ATTR_MTS(dev_attr_extserial_dcd_gpio_mtre, "extserial-dcd",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+static DEVICE_ATTR_MTS(dev_attr_alarm_mtre, "alarm",
+ mts_attr_show_alarm_mtre, mts_attr_store_alarm_mtre);
+
+static DEVICE_ATTR_MTS(dev_attr_device_ready_mtre, "device-ready",
+ mts_attr_show_device_ready_mtre, mts_attr_store_device_ready_mtre);
+
+static DEVICE_ATTR_MTS(dev_attr_led_cd_i2c_mtre, "led-cd",
+ mts_attr_show_led, mts_attr_store_led);
+
+static DEVICE_ATTR_MTS(dev_attr_led_sig1_i2c_mtre, "led-sig1",
+ mts_attr_show_led, mts_attr_store_led);
+
+static DEVICE_ATTR_MTS(dev_attr_led_sig2_i2c_mtre, "led-sig2",
+ mts_attr_show_led, mts_attr_store_led);
+
+static DEVICE_ATTR_MTS(dev_attr_led_sig3_i2c_mtre, "led-sig3",
+ mts_attr_show_led, mts_attr_store_led);
+
+static DEVICE_ATTR_MTS(dev_attr_led_sig4_i2c_mtre, "led-sig4",
+ mts_attr_show_led, mts_attr_store_led);
+
+static struct attribute *mtre_0_0_platform_attributes[] = {
+ /* Common entries */
+ &dev_attr_vendor_id.attr,
+ &dev_attr_product_id.attr,
+ &dev_attr_device_id.attr,
+ &dev_attr_uuid.attr,
+ &dev_attr_hw_version.attr,
+ &dev_attr_imei.attr,
+ &dev_attr_eth_mac.attr,
+ &dev_attr_has_radio.attr,
+
+ &dev_attr_reset.attr,
+ &dev_attr_reset_monitor.attr,
+ &dev_attr_reset_monitor_intervals.attr,
+ &dev_attr_radio_power.attr,
+ &dev_attr_radio_reset.attr,
+
+ &dev_attr_radio_reset_backoffs.attr,
+ &dev_attr_radio_reset_backoff_index.attr,
+ &dev_attr_radio_reset_backoff_seconds.attr,
+
+ &dev_attr_extserial_ri_gpio_mtre.attr,
+ &dev_attr_extserial_dtr_gpio_mtre.attr,
+ &dev_attr_extserial_dsr_gpio_mtre.attr,
+ &dev_attr_extserial_dcd_gpio_mtre.attr,
+
+ &dev_attr_eth_reset_mtre.attr,
+
+ &dev_attr_alarm_mtre.attr, /* Alarm attribute (driver for ENABLED/ALARM LEDs) */
+ &dev_attr_device_ready_mtre.attr, /* Set device readyness attribute (affects ENABLED/ALARM LEDs) */
+
+ &dev_attr_led_cd_i2c_mtre.attr, /* (cellular) Link Status */
+ &dev_attr_led_sig1_i2c_mtre.attr, /* (cellular) Link Quality */
+ &dev_attr_led_sig2_i2c_mtre.attr, /* (cellular) Link Quality */
+ &dev_attr_led_sig3_i2c_mtre.attr, /* (cellular) Link Quality */
+ &dev_attr_led_sig4_i2c_mtre.attr, /* (cellular) Link Quality */
+#ifdef MTRE
+ &dev_attr_oem_string1.attr,
+ &dev_attr_oem_string2.attr,
+#endif
+
+ NULL,
+};
+
+
+static struct attribute_group mtre_0_0_platform_attribute_group = {
+ .attrs = mtre_0_0_platform_attributes
+};