summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--io-module/adc.c87
-rw-r--r--io-module/gpio.c83
-rw-r--r--io-module/mt100eocg.c221
-rw-r--r--io-module/mtcdp.c310
-rw-r--r--io-module/mtr.c468
-rw-r--r--io-module/mtr2.c515
-rw-r--r--io-module/mts_io.c3140
-rw-r--r--io-module/mts_io.h19
-rw-r--r--io-module/spi.c767
-rw-r--r--io-module/telit_radio.c219
10 files changed, 2773 insertions, 3056 deletions
diff --git a/io-module/adc.c b/io-module/adc.c
new file mode 100644
index 0000000..bcb3598
--- /dev/null
+++ b/io-module/adc.c
@@ -0,0 +1,87 @@
+
+#define ADC_SHTIME_DEFAULT 0x05
+#define ADC_STARTUP_DEFAULT 0x04
+#define ADC_PRESCALE_DEFAULT 0x3F
+#define ADC_MODE_DEFAULT \
+ ((ADC_SHTIME_DEFAULT & 0x0F) << 24) | \
+ ((ADC_STARTUP_DEFAULT & 0x1F) << 16) | \
+ ((ADC_PRESCALE_DEFAULT & 0x3F) << 8)
+
+#define ADC_CR_OFFSET 0x00
+#define ADC_MR_OFFSET 0x04
+#define ADC_CHER_OFFSET 0x10
+#define ADC_CHDR_OFFSET 0x14
+#define ADC_CHSR_OFFSET 0x18
+#define ADC_SR_OFFSET 0x1C
+#define ADC_LDCR_OFFSET 0x20
+#define ADC_IER_OFFSET 0x14
+#define ADC_IDR_OFFSET 0x28
+#define ADC_IMR_OFFSET 0x2C
+#define ADC_CDR0_OFFSET 0x30
+#define ADC_CDR1_OFFSET 0x34
+#define ADC_CDR2_OFFSET 0x38
+#define ADC_CDR3_OFFSET 0x3C
+
+void __iomem *adc_base;
+struct clk *adc_clk;
+
+#define ADC_CONVERT_RESET(base) writel(0x01, (base) + ADC_CR_OFFSET)
+#define ADC_CONVERT_START(base) writel(0x02, (base) + ADC_CR_OFFSET)
+
+static ssize_t mts_attr_show_adc(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int offset;
+ u32 value;
+ u32 chan_mask;
+
+ if (!DEVICE_CAPA(id_eeprom.capa, CAPA_ADC)) {
+ log_debug("ADC not available");
+ return -ENODEV;
+ }
+
+ if (!strcmp(attr->attr.name, "adc0")) {
+ offset = ADC_CDR0_OFFSET;
+ chan_mask = 0x01;
+ } else if (!strcmp(attr->attr.name, "adc1")) {
+ offset = ADC_CDR1_OFFSET;
+ chan_mask = 0x02;
+ } else if (!strcmp(attr->attr.name, "adc2")) {
+ offset = ADC_CDR2_OFFSET;
+ chan_mask = 0x04;
+ } else if (!strcmp(attr->attr.name, "adc3")) {
+ offset = ADC_CDR3_OFFSET;
+ chan_mask = 0x08;
+ } else {
+ log_notice("adc attr does not exist");
+ return -ENOENT;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ // disable all channels and enable the one we want
+ writel(0x0F, adc_base + ADC_CHDR_OFFSET);
+ writel(chan_mask, adc_base + ADC_CHER_OFFSET);
+
+ ADC_CONVERT_START(adc_base);
+
+ // wait for conversion to complete (EOC bit set)
+ value = 0;
+ while (value != chan_mask) {
+ value = readl(adc_base + ADC_SR_OFFSET) & chan_mask;
+ log_debug("ADC_SR EOC [%X]", value);
+ }
+
+ // read result
+ value = readl(adc_base + offset);
+
+ mutex_unlock(&mts_io_mutex);
+
+ return sprintf(buf, "%lu\n", (unsigned long) value);
+}
+
+static DEVICE_ATTR_RO_MTS(dev_attr_adc0, "adc0", mts_attr_show_adc);
+static DEVICE_ATTR_RO_MTS(dev_attr_adc1, "adc1", mts_attr_show_adc);
+static DEVICE_ATTR_RO_MTS(dev_attr_adc2, "adc2", mts_attr_show_adc);
+static DEVICE_ATTR_RO_MTS(dev_attr_adc3, "adc3", mts_attr_show_adc);
diff --git a/io-module/gpio.c b/io-module/gpio.c
new file mode 100644
index 0000000..72c55f6
--- /dev/null
+++ b/io-module/gpio.c
@@ -0,0 +1,83 @@
+
+struct gpio_pin *gpio_pin_by_name(const char *name) {
+ struct gpio_pin *pin;
+
+ for (pin = gpio_pins; *pin->name; pin++) {
+ if (!strcmp(pin->name, name)) {
+ return pin;
+ }
+ }
+
+ log_error("pin named %s not found", name);
+
+ return NULL;
+}
+
+struct gpio_pin *gpio_pin_by_attr_name(const char *name) {
+ struct gpio_pin *pin;
+
+ for (pin = gpio_pins; *pin->name; pin++) {
+ if (!strcmp(pin->pin.label, name)) {
+ return pin;
+ }
+ }
+
+ log_error("pin with attr name %s not found", name);
+
+ return NULL;
+}
+
+static ssize_t mts_attr_show_gpio_pin(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int value;
+ struct gpio_pin *pin = gpio_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_gpio_pin(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ struct gpio_pin *pin = gpio_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;
+}
diff --git a/io-module/mt100eocg.c b/io-module/mt100eocg.c
new file mode 100644
index 0000000..8d2338d
--- /dev/null
+++ b/io-module/mt100eocg.c
@@ -0,0 +1,221 @@
+
+static struct gpio_pin gpio_pins_mt100eocg_0_0[] = {
+ {
+ .name = "ENIO",
+ .pin = AT91_PIN_PC15,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ETH0_ENABLED",
+ .attr_name = "eth0-enabled",
+ .pin = AT91_PIN_PB31,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "RADIO_RESET",
+ .attr_name = "radio-reset",
+ .pin = AT91_PIN_PB30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "DEVICE_RESET",
+ .attr_name = "reset",
+ .pin = AT91_PIN_PA22,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "LED3",
+ .attr_name = "led3",
+ .pin = AT91_PIN_PC9,
+#if LED_LS_CONTROLLABLE
+ .direction = GPIO_DIR_OUTPUT,
+#else
+ .direction = GPIO_DIR_INPUT,
+#endif
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "LED2",
+ .attr_name = "led2",
+ .pin = AT91_PIN_PA30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "RSERSRC",
+ .attr_name = "rsersrc",
+ .pin = AT91_PIN_PC7,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "TXD1",
+ .pin = AT91_PIN_PB17,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "DTR1",
+ .attr_name = "extserial-dtr",
+ .pin = AT91_PIN_PB18,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "DCD1",
+ .attr_name = "extserial-dcd",
+ .pin = AT91_PIN_PB3,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "GPIO11",
+ .attr_name = "gpio11",
+ .pin = AT91_PIN_PB19,
+ .direction = GPIO_DIR_OD,
+ .output_value = 1,
+ .use_pullup = 1,
+ },
+ {
+ .name = "GPIO12",
+ .attr_name = "gpio12",
+ .pin = AT91_PIN_PB20,
+ .direction = GPIO_DIR_OD,
+ .output_value = 1,
+ .use_pullup = 1,
+ },
+ {
+ .name = "ADC0",
+ .pin = AT91_PIN_PC0,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ADC1",
+ .pin = AT91_PIN_PC1,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ADC2",
+ .pin = AT91_PIN_PC2,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ADC3",
+ .pin = AT91_PIN_PC3,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ { },
+};
+
+/* mt100eocg specific attributes */
+static DEVICE_ATTR_MTS(dev_attr_gpo1, "gpo1",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_gpo2, "gpo2",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_gpo3, "gpo3",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_gpo4, "gpo4",
+ mts_attr_show_dout, mts_attr_store_dout);
+
+
+static DEVICE_ATTR_MTS(dev_attr_led1, "led1",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_led2, "led2",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+#if LED_LS_CONTROLLABLE
+static DEVICE_ATTR_MTS(dev_attr_led3, "led3",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+#else
+static DEVICE_ATTR_RO_MTS(dev_attr_led3, "led3", mts_attr_show_gpio_pin);
+#endif
+
+static DEVICE_ATTR_MTS(dev_attr_led4, "led4",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_led5, "led5",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_led6, "led6",
+ mts_attr_show_dout, mts_attr_store_dout);
+
+static DEVICE_ATTR_MTS(dev_attr_gpio11, "gpio11",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+static DEVICE_ATTR_MTS(dev_attr_gpio12, "gpio12",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+static DEVICE_ATTR_MTS(dev_attr_rsersrc, "rsersrc",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+
+static struct attribute *mt100eocg_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_extserial_dtr.attr,
+ &dev_attr_extserial_dcd_gpio.attr,
+ &dev_attr_rsersrc.attr,
+ &dev_attr_radio_reset.attr,
+ &dev_attr_eth0_enabled.attr,
+ &dev_attr_gpio11.attr,
+ &dev_attr_gpio12.attr,
+
+ &dev_attr_gpo1.attr,
+ &dev_attr_gpo2.attr,
+ &dev_attr_gpo3.attr,
+ &dev_attr_gpo4.attr,
+ &dev_attr_led1.attr,
+ &dev_attr_led2.attr,
+ &dev_attr_led3.attr,
+ &dev_attr_led4.attr,
+ &dev_attr_led5.attr,
+ &dev_attr_led6.attr,
+
+ &dev_attr_gpi5.attr,
+ &dev_attr_gpi6.attr,
+ &dev_attr_gpi7.attr,
+ &dev_attr_gpi8.attr,
+ &dev_attr_gpi9.attr,
+ &dev_attr_gpi10.attr,
+
+ &dev_attr_board_temperature.attr,
+
+ &dev_attr_adc0.attr,
+ &dev_attr_adc1.attr,
+ &dev_attr_adc2.attr,
+ &dev_attr_adc3.attr,
+
+ NULL,
+};
+
+static struct attribute_group mt100eocg_platform_attribute_group = {
+ .attrs = mt100eocg_platform_attributes
+};
diff --git a/io-module/mtcdp.c b/io-module/mtcdp.c
new file mode 100644
index 0000000..31551b0
--- /dev/null
+++ b/io-module/mtcdp.c
@@ -0,0 +1,310 @@
+
+#define USBH2_PS_CONTROLLABLE 0
+
+static struct gpio_pin gpio_pins_mtcdp_0_0[] = {
+ {
+ .name = "ENIO",
+ .pin = AT91_PIN_PC15,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ETH0_ENABLED",
+ .attr_name = "eth0-enabled",
+ .pin = AT91_PIN_PB31,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "RADIO_RESET",
+ .attr_name = "radio-reset",
+ .pin = AT91_PIN_PB30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "DEVICE_RESET",
+ .attr_name = "reset",
+ .pin = AT91_PIN_PA22,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "LS_LED",
+ .attr_name = "led-ls",
+ .pin = AT91_PIN_PC9,
+#if LED_LS_CONTROLLABLE
+ .direction = GPIO_DIR_OUTPUT,
+#else
+ .direction = GPIO_DIR_INPUT,
+#endif
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "STATUS_LED",
+ .attr_name = "led-status",
+ .pin = AT91_PIN_PA30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "STATUS_LED",
+ .attr_name = "led-sdk-a",
+ .pin = AT91_PIN_PA30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+#endif
+ {
+ .name = "RSERSRC",
+ .attr_name = "rsersrc",
+ .pin = AT91_PIN_PC7,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "DTR1",
+ .attr_name = "extserial-dtr",
+ .pin = AT91_PIN_PC10,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ { },
+};
+
+static struct gpio_pin gpio_pins_mtcdp_1_0[] = {
+ {
+ .name = "ENIO",
+ .pin = AT91_PIN_PC15,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ETH0_ENABLED",
+ .attr_name = "eth0-enabled",
+ .pin = AT91_PIN_PB31,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "RADIO_RESET",
+ .attr_name = "radio-reset",
+ .pin = AT91_PIN_PB30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "DEVICE_RESET",
+ .attr_name = "reset",
+ .pin = AT91_PIN_PA22,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "LS_LED",
+ .attr_name = "led-ls",
+ .pin = AT91_PIN_PC9,
+#if LED_LS_CONTROLLABLE
+ .direction = GPIO_DIR_OUTPUT,
+#else
+ .direction = GPIO_DIR_INPUT,
+#endif
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "STATUS_LED",
+ .attr_name = "led-status",
+ .pin = AT91_PIN_PA30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "STATUS_LED",
+ .attr_name = "led-sdk-a",
+ .pin = AT91_PIN_PA30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "RSERSRC",
+ .attr_name = "rsersrc",
+ .pin = AT91_PIN_PC7,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "TXD1",
+ .pin = AT91_PIN_PB17,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "DTR1",
+ .attr_name = "extserial-dtr",
+ .pin = AT91_PIN_PB18,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+ {
+ .name = "USBH2_PS_OC",
+ .attr_name = "usbh2-ps-oc",
+ .pin = AT91_PIN_PB19,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+#if USBH2_PS_CONTROLLABLE
+ {
+ .name = "USBH2_PS_ENABLED",
+ .attr_name = "usbh2-ps-enabled",
+ .pin = AT91_PIN_PB20,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ .active_low = 1,
+ },
+#endif
+ {
+ .name = "NDC_RESET",
+ .attr_name = "ndc-reset",
+ .pin = AT91_PIN_PB21,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ADC0",
+ .pin = AT91_PIN_PC0,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ADC1",
+ .pin = AT91_PIN_PC1,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ADC2",
+ .pin = AT91_PIN_PC2,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ADC3",
+ .pin = AT91_PIN_PC3,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ { },
+};
+
+/* mtcdp specific attributes */
+static DEVICE_ATTR_MTS(dev_attr_led_sdk_a, "led-sdk-a",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+static DEVICE_ATTR_RO_MTS(dev_attr_usbh2_ps_oc, "usbh2-ps-oc",
+ mts_attr_show_gpio_pin);
+
+#if USBH2_PS_CONTROLLABLE
+static DEVICE_ATTR_MTS(dev_attr_usbh2_ps_enabled, "usbh2-ps-enabled",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+#endif
+
+static struct attribute *mtcdp_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_reset.attr,
+ &dev_attr_reset_monitor.attr,
+ &dev_attr_radio_reset.attr,
+ &dev_attr_ndc_reset.attr,
+ &dev_attr_eth0_enabled.attr,
+ &dev_attr_extserial_dtr.attr,
+ &dev_attr_led_ls.attr,
+ &dev_attr_led_status.attr,
+ &dev_attr_led_sdk_a.attr,
+ &dev_attr_usbh2_ps_oc.attr,
+#if USBH2_PS_CONTROLLABLE
+ &dev_attr_usbh2_ps_enabled.attr,
+#endif
+
+ &dev_attr_extserial_dcd.attr,
+ &dev_attr_extserial_ri.attr,
+ &dev_attr_extserial_dsr.attr,
+ &dev_attr_led_cd.attr,
+ &dev_attr_led_sdk_b.attr,
+ &dev_attr_led_sig1.attr,
+ &dev_attr_led_sdk_c.attr,
+ &dev_attr_led_sig2.attr,
+ &dev_attr_led_sdk_d.attr,
+ &dev_attr_led_sig3.attr,
+ &dev_attr_led_sdk_e.attr,
+ &dev_attr_led_dtr.attr,
+ &dev_attr_led_sdk_f.attr,
+
+ &dev_attr_dout0.attr,
+ &dev_attr_dout1.attr,
+ &dev_attr_dout2.attr,
+ &dev_attr_dout3.attr,
+ &dev_attr_dout4.attr,
+ &dev_attr_dout5.attr,
+ &dev_attr_dout6.attr,
+ &dev_attr_dout7.attr,
+
+ &dev_attr_din0.attr,
+ &dev_attr_din1.attr,
+ &dev_attr_din2.attr,
+ &dev_attr_din3.attr,
+ &dev_attr_din4.attr,
+ &dev_attr_din5.attr,
+ &dev_attr_din6.attr,
+ &dev_attr_din7.attr,
+
+ &dev_attr_board_temperature.attr,
+
+ &dev_attr_adc0.attr,
+ &dev_attr_adc1.attr,
+ &dev_attr_adc2.attr,
+ &dev_attr_adc3.attr,
+
+ NULL,
+};
+
+static struct attribute_group mtcdp_platform_attribute_group = {
+ .attrs = mtcdp_platform_attributes
+};
diff --git a/io-module/mtr.c b/io-module/mtr.c
new file mode 100644
index 0000000..cef1560
--- /dev/null
+++ b/io-module/mtr.c
@@ -0,0 +1,468 @@
+
+static struct gpio_pin gpio_pins_mtr_0_0[] = {
+ {
+ .name = "NETH_RST",
+ .pin = {
+ .gpio = AT91_PIN_PC6,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "eth0-enabled",
+ },
+ },
+ {
+ .name = "PWRMON",
+ .pin = {
+ .gpio = AT91_PIN_PA23,
+ .flags = GPIOF_IN,
+ .label = "radio-power",
+ },
+ },
+ {
+ .name = "3G_RST",
+ .pin = {
+ .gpio = AT91_PIN_PA22,
+ .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH,
+ .label = "radio-reset",
+ },
+ },
+ {
+ .name = "3G_ONOFF",
+ .pin = {
+ .gpio = AT91_PIN_PA21,
+ .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH,
+ .label = "radio-enabled",
+ },
+ },
+ {
+ .name = "DEVICE_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC4,
+ .flags = GPIOF_IN,
+ .label = "reset",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LS_LED",
+ .pin = {
+ .gpio = AT91_PIN_PC16,
+#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_PC21,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "led-status",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "STATUS_LED",
+ .pin = {
+ .gpio = AT91_PIN_PC21,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "led-a",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED3",
+ .pin = {
+ .gpio = AT91_PIN_PC15,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-wifi",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED3",
+ .pin = {
+ .gpio = AT91_PIN_PC15,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-b",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED4",
+ .pin = {
+ .gpio = AT91_PIN_PC20,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-cd",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED4",
+ .pin = {
+ .gpio = AT91_PIN_PC20,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-c",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED6",
+ .pin = {
+ .gpio = AT91_PIN_PC19,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig1",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED6",
+ .pin = {
+ .gpio = AT91_PIN_PC19,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-d",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED7",
+ .pin = {
+ .gpio = AT91_PIN_PC18,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig2",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED7",
+ .pin = {
+ .gpio = AT91_PIN_PC18,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-e",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED8",
+ .pin = {
+ .gpio = AT91_PIN_PC17,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig3",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED8",
+ .pin = {
+ .gpio = AT91_PIN_PC17,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-f",
+ },
+ .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,
+ },
+ {
+ .name = "BT_EN",
+ .pin = {
+ .gpio = AT91_PIN_PA28,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "bt-enabled",
+ },
+ },
+ {
+ .name = "WLAN_EN",
+ .pin = {
+ .gpio = AT91_PIN_PA27,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "wlan-enabled",
+ },
+ },
+ { },
+};
+
+static struct gpio_pin gpio_pins_mtr_0_1[] = {
+ {
+ .name = "NETH_RST",
+ .pin = {
+ .gpio = AT91_PIN_PC6,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "eth0-enabled",
+ },
+ },
+ {
+ .name = "PWRMON",
+ .pin = {
+ .gpio = AT91_PIN_PA23,
+ .flags = GPIOF_IN,
+ .label = "radio-power",
+ },
+ },
+ {
+ .name = "3G_RST",
+ .pin = {
+ .gpio = AT91_PIN_PA22,
+ .flags = GPIOF_OUT_INIT_HIGH | GPIOF_PULLUP,
+ .label = "radio-reset",
+ },
+ },
+ {
+ .name = "3G_ONOFF",
+ .pin = {
+ .gpio = AT91_PIN_PA21,
+ .flags = GPIOF_OUT_INIT_HIGH | GPIOF_PULLUP,
+ .label = "radio-enabled",
+ },
+ },
+ {
+ .name = "DEVICE_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PC4,
+ .flags = GPIOF_IN,
+ .label = "reset",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LS_LED",
+ .pin = {
+ .gpio = AT91_PIN_PC16,
+#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_PC21,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "led-status",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED3",
+ .pin = {
+ .gpio = AT91_PIN_PC15,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-wifi",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED3",
+ .pin = {
+ .gpio = AT91_PIN_PC15,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-b",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED4",
+ .pin = {
+ .gpio = AT91_PIN_PC20,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-cd",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED4",
+ .pin = {
+ .gpio = AT91_PIN_PC20,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-c",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED6",
+ .pin = {
+ .gpio = AT91_PIN_PC19,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig1",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED6",
+ .pin = {
+ .gpio = AT91_PIN_PC19,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-d",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED7",
+ .pin = {
+ .gpio = AT91_PIN_PC18,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig2",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED7",
+ .pin = {
+ .gpio = AT91_PIN_PC18,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-e",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED8",
+ .pin = {
+ .gpio = AT91_PIN_PC17,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-sig3",
+ },
+ .active_low = 1,
+ },
+ {
+ .name = "LED8",
+ .pin = {
+ .gpio = AT91_PIN_PC17,
+ .flags = GPIOF_OUT_INIT_HIGH,
+ .label = "led-f",
+ },
+ .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,
+ },
+ {
+ .name = "BT_EN",
+ .pin = {
+ .gpio = AT91_PIN_PA28,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "bt-enabled",
+ },
+ },
+ {
+ .name = "WLAN_EN",
+ .pin = {
+ .gpio = AT91_PIN_PA27,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "wlan-enabled",
+ },
+ },
+ { },
+};
+
+static struct attribute *mtr_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_telit.attr,
+ &dev_attr_radio_reset_telit.attr,
+ &dev_attr_extserial_ri_gpio.attr,
+ &dev_attr_extserial_dtr.attr,
+ &dev_attr_extserial_dsr_gpio.attr,
+ &dev_attr_extserial_dcd_gpio.attr,
+ &dev_attr_eth0_enabled.attr,
+ &dev_attr_bt_enabled.attr,
+ &dev_attr_wlan_enabled.attr,
+
+ &dev_attr_led_status.attr,
+ &dev_attr_led_sig1_gpio.attr,
+ &dev_attr_led_sig2_gpio.attr,
+ &dev_attr_led_sig3_gpio.attr,
+ &dev_attr_led_cd_gpio.attr,
+ &dev_attr_led_wifi_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,
+
+ NULL,
+};
+
+static struct attribute_group mtr_platform_attribute_group = {
+ .attrs = mtr_platform_attributes
+};
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
+};
diff --git a/io-module/mts_io.c b/io-module/mts_io.c
index 79351fa..1f641d9 100644
--- a/io-module/mts_io.c
+++ b/io-module/mts_io.c
@@ -1,7 +1,7 @@
/*
* MTS-IO Controller
*
- * Copyright (C) 2013 by Multi-Tech Systems
+ * Copyright (C) 2014 by Multi-Tech Systems
*
* Authors: James Maki <jmaki@multitech.com>
* Jesse Gilles <jgilles@multitech.com>
@@ -44,46 +44,14 @@
#include "mts_io.h"
-#define DRIVER_VERSION "v0.8.2"
+#define DRIVER_VERSION "v0.9.1"
#define DRIVER_AUTHOR "James Maki <jmaki@multitech.com>"
#define DRIVER_DESC "MTS-IO Controller"
#define DRIVER_NAME "mts-io"
#define PLATFORM_NAME "mts-io"
-#define DEBUG 0
-
-#define __log(level, name, format, args...) \
- printk(level "[" name "] " DRIVER_NAME ":%s:%d: " format "\n" , \
- __func__ , __LINE__ , ## args)
-
-#define log_emerg(format, args...) __log(KERN_EMERG, "EMERG", format , ## args)
-#define log_alert(format, args...) __log(KERN_ALERT, "ALERT", format , ## args)
-#define log_crit(format, args...) __log(KERN_CRIT, "CRIT", format , ## args)
-#define log_error(format, args...) __log(KERN_ERR, "ERROR", format , ## args)
-#define log_warning(format, args...) __log(KERN_WARNING, "WARNING", format , ## args)
-#define log_notice(format, args...) __log(KERN_NOTICE, "NOTICE", format , ## args)
-#define log_info(format, args...) __log(KERN_INFO, "INFO", format , ## args)
-#if DEBUG
-# define log_debug(format, args...) __log(KERN_DEBUG, "DEBUG", format , ## args)
-#else
-# define log_debug(format, args...) do {} while (0)
-#endif
-
-#define LED_STATUS_CONTROLLABLE_MTCDP 0
#define LED_LS_CONTROLLABLE 0
-#define USBH2_PS_CONTROLLABLE 0
-
-static int led_mode_status = LED_OFF;
-
-#define SOUT_LED_CD_BIT BIT(0)
-#define SOUT_EXTSERIAL_RI_BIT BIT(1)
-#define SOUT_EXTSERIAL_DSR_BIT BIT(2)
-#define SOUT_LED_DTR BIT(3)
-#define SOUT_LED_SIG1_BIT BIT(4)
-#define SOUT_LED_SIG2_BIT BIT(5)
-#define SOUT_LED_SIG3_BIT BIT(6)
-#define SOUT_EXTSERIAL_DCD_BIT BIT(7)
#define AT91SAM9X5_BASE_ADC 0xf804c000
@@ -109,1253 +77,44 @@ static uint8_t has_spi_din;
static uint8_t has_spi_dout;
static uint8_t has_spi_temp;
+static struct platform_device *mts_io_platform_device;
static struct attribute_group *attr_group;
-
static struct gpio_pin *gpio_pins;
-/*
-static struct gpio_pin gpio_pins_mtcdp_0_0[] = {
- {
- .name = "ENIO",
- .pin = AT91_PIN_PC15,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "ETH0_ENABLED",
- .attr_name = "eth0-enabled",
- .pin = AT91_PIN_PB31,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "RADIO_RESET",
- .attr_name = "radio-reset",
- .pin = AT91_PIN_PB30,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "DEVICE_RESET",
- .attr_name = "reset",
- .pin = AT91_PIN_PA22,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "LS_LED",
- .attr_name = "led-ls",
- .pin = AT91_PIN_PC9,
-#if LED_LS_CONTROLLABLE
- .direction = GPIO_DIR_OUTPUT,
-#else
- .direction = GPIO_DIR_INPUT,
-#endif
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
-#if LED_STATUS_CONTROLLABLE_MTCDP
- {
- .name = "STATUS_LED",
- .attr_name = "led-status",
- .pin = AT91_PIN_PA30,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
-#endif
- {
- .name = "RSERSRC",
- .attr_name = "rsersrc",
- .pin = AT91_PIN_PC7,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "DTR1",
- .attr_name = "extserial-dtr",
- .pin = AT91_PIN_PC10,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
- { },
-};
-
-static struct gpio_pin gpio_pins_mtcdp_1_0[] = {
- {
- .name = "ENIO",
- .pin = AT91_PIN_PC15,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "ETH0_ENABLED",
- .attr_name = "eth0-enabled",
- .pin = AT91_PIN_PB31,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "RADIO_RESET",
- .attr_name = "radio-reset",
- .pin = AT91_PIN_PB30,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "DEVICE_RESET",
- .attr_name = "reset",
- .pin = AT91_PIN_PA22,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "LS_LED",
- .attr_name = "led-ls",
- .pin = AT91_PIN_PC9,
-#if LED_LS_CONTROLLABLE
- .direction = GPIO_DIR_OUTPUT,
-#else
- .direction = GPIO_DIR_INPUT,
-#endif
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
-#if LED_STATUS_CONTROLLABLE_MTCDP
- {
- .name = "STATUS_LED",
- .attr_name = "led-status",
- .pin = AT91_PIN_PA30,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
-#endif
- {
- .name = "RSERSRC",
- .attr_name = "rsersrc",
- .pin = AT91_PIN_PC7,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "TXD1",
- .pin = AT91_PIN_PB17,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "DTR1",
- .attr_name = "extserial-dtr",
- .pin = AT91_PIN_PB18,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "USBH2_PS_OC",
- .attr_name = "usbh2-ps-oc",
- .pin = AT91_PIN_PB19,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
-#if USBH2_PS_CONTROLLABLE
- {
- .name = "USBH2_PS_ENABLED",
- .attr_name = "usbh2-ps-enabled",
- .pin = AT91_PIN_PB20,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
-#endif
- {
- .name = "NDC_RESET",
- .attr_name = "ndc-reset",
- .pin = AT91_PIN_PB21,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "ADC0",
- .pin = AT91_PIN_PC0,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "ADC1",
- .pin = AT91_PIN_PC1,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "ADC2",
- .pin = AT91_PIN_PC2,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "ADC3",
- .pin = AT91_PIN_PC3,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- { },
-};
-
-static struct gpio_pin gpio_pins_mt100eocg_0_0[] = {
- {
- .name = "ENIO",
- .pin = AT91_PIN_PC15,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "ETH0_ENABLED",
- .attr_name = "eth0-enabled",
- .pin = AT91_PIN_PB31,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "RADIO_RESET",
- .attr_name = "radio-reset",
- .pin = AT91_PIN_PB30,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- },
- {
- .name = "DEVICE_RESET",
- .attr_name = "reset",
- .pin = AT91_PIN_PA22,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "LED3",
- .attr_name = "led3",
- .pin = AT91_PIN_PC9,
-#if LED_LS_CONTROLLABLE
- .direction = GPIO_DIR_OUTPUT,
-#else
- .direction = GPIO_DIR_INPUT,
-#endif
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "LED2",
- .attr_name = "led2",
- .pin = AT91_PIN_PA30,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "RSERSRC",
- .attr_name = "rsersrc",
- .pin = AT91_PIN_PC7,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "TXD1",
- .pin = AT91_PIN_PB17,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "DTR1",
- .attr_name = "extserial-dtr",
- .pin = AT91_PIN_PB18,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "DCD1",
- .attr_name = "extserial-dcd",
- .pin = AT91_PIN_PB3,
- .direction = GPIO_DIR_OUTPUT,
- .output_value = 1,
- .use_pullup = 0,
- .active_low = 1,
- },
- {
- .name = "GPIO11",
- .attr_name = "gpio11",
- .pin = AT91_PIN_PB19,
- .direction = GPIO_DIR_OD,
- .output_value = 1,
- .use_pullup = 1,
- },
- {
- .name = "GPIO12",
- .attr_name = "gpio12",
- .pin = AT91_PIN_PB20,
- .direction = GPIO_DIR_OD,
- .output_value = 1,
- .use_pullup = 1,
- },
- {
- .name = "ADC0",
- .pin = AT91_PIN_PC0,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "ADC1",
- .pin = AT91_PIN_PC1,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "ADC2",
- .pin = AT91_PIN_PC2,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- {
- .name = "ADC3",
- .pin = AT91_PIN_PC3,
- .direction = GPIO_DIR_INPUT,
- .output_value = 0,
- .use_pullup = 0,
- },
- { },
-};
-*/
-
-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 = "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",
- },
- },
- { },
-};
-
-static struct gpio_pin gpio_pins_mtr_0_0[] = {
- {
- .name = "NETH_RST",
- .pin = {
- .gpio = AT91_PIN_PC6,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "eth0-enabled",
- },
- },
- {
- .name = "PWRMON",
- .pin = {
- .gpio = AT91_PIN_PA23,
- .flags = GPIOF_IN,
- .label = "radio-power",
- },
- },
- {
- .name = "3G_RST",
- .pin = {
- .gpio = AT91_PIN_PA22,
- .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH,
- .label = "radio-reset",
- },
- },
- {
- .name = "3G_ONOFF",
- .pin = {
- .gpio = AT91_PIN_PA21,
- .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH,
- .label = "radio-enabled",
- },
- },
- {
- .name = "DEVICE_RESET",
- .pin = {
- .gpio = AT91_PIN_PC4,
- .flags = GPIOF_IN,
- .label = "reset",
- },
- .active_low = 1,
- },
- {
- .name = "LS_LED",
- .pin = {
- .gpio = AT91_PIN_PC16,
-#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_PC21,
- .flags = GPIOF_OUT_INIT_LOW,
- .label = "led-status",
- },
- .active_low = 1,
- },
- {
- .name = "LED3",
- .pin = {
- .gpio = AT91_PIN_PC15,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-wifi",
- },
- .active_low = 1,
- },
- {
- .name = "LED3",
- .pin = {
- .gpio = AT91_PIN_PC15,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-b",
- },
- .active_low = 1,
- },
- {
- .name = "LED4",
- .pin = {
- .gpio = AT91_PIN_PC20,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-cd",
- },
- .active_low = 1,
- },
- {
- .name = "LED4",
- .pin = {
- .gpio = AT91_PIN_PC20,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-c",
- },
- .active_low = 1,
- },
- {
- .name = "LED6",
- .pin = {
- .gpio = AT91_PIN_PC19,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-sig1",
- },
- .active_low = 1,
- },
- {
- .name = "LED6",
- .pin = {
- .gpio = AT91_PIN_PC19,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-d",
- },
- .active_low = 1,
- },
- {
- .name = "LED7",
- .pin = {
- .gpio = AT91_PIN_PC18,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-sig2",
- },
- .active_low = 1,
- },
- {
- .name = "LED7",
- .pin = {
- .gpio = AT91_PIN_PC18,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-e",
- },
- .active_low = 1,
- },
- {
- .name = "LED8",
- .pin = {
- .gpio = AT91_PIN_PC17,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-sig3",
- },
- .active_low = 1,
- },
- {
- .name = "LED8",
- .pin = {
- .gpio = AT91_PIN_PC17,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-f",
- },
- .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,
- },
- {
- .name = "BT_EN",
- .pin = {
- .gpio = AT91_PIN_PA28,
- .flags = GPIOF_OUT_INIT_LOW,
- .label = "bt-enabled",
- },
- },
- {
- .name = "WLAN_EN",
- .pin = {
- .gpio = AT91_PIN_PA27,
- .flags = GPIOF_OUT_INIT_LOW,
- .label = "wlan-enabled",
- },
- },
- { },
-};
-
-static struct gpio_pin gpio_pins_mtr_0_1[] = {
- {
- .name = "NETH_RST",
- .pin = {
- .gpio = AT91_PIN_PC6,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "eth0-enabled",
- },
- },
- {
- .name = "PWRMON",
- .pin = {
- .gpio = AT91_PIN_PA23,
- .flags = GPIOF_IN,
- .label = "radio-power",
- },
- },
- {
- .name = "3G_RST",
- .pin = {
- .gpio = AT91_PIN_PA22,
- .flags = GPIOF_OUT_INIT_HIGH | GPIOF_PULLUP,
- .label = "radio-reset",
- },
- },
- {
- .name = "3G_ONOFF",
- .pin = {
- .gpio = AT91_PIN_PA21,
- .flags = GPIOF_OUT_INIT_HIGH | GPIOF_PULLUP,
- .label = "radio-enabled",
- },
- },
- {
- .name = "DEVICE_RESET",
- .pin = {
- .gpio = AT91_PIN_PC4,
- .flags = GPIOF_IN,
- .label = "reset",
- },
- .active_low = 1,
- },
- {
- .name = "LS_LED",
- .pin = {
- .gpio = AT91_PIN_PC16,
-#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_PC21,
- .flags = GPIOF_OUT_INIT_LOW,
- .label = "led-status",
- },
- .active_low = 1,
- },
- {
- .name = "LED3",
- .pin = {
- .gpio = AT91_PIN_PC15,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-wifi",
- },
- .active_low = 1,
- },
- {
- .name = "LED3",
- .pin = {
- .gpio = AT91_PIN_PC15,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-b",
- },
- .active_low = 1,
- },
- {
- .name = "LED4",
- .pin = {
- .gpio = AT91_PIN_PC20,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-cd",
- },
- .active_low = 1,
- },
- {
- .name = "LED4",
- .pin = {
- .gpio = AT91_PIN_PC20,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-c",
- },
- .active_low = 1,
- },
- {
- .name = "LED6",
- .pin = {
- .gpio = AT91_PIN_PC19,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-sig1",
- },
- .active_low = 1,
- },
- {
- .name = "LED6",
- .pin = {
- .gpio = AT91_PIN_PC19,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-d",
- },
- .active_low = 1,
- },
- {
- .name = "LED7",
- .pin = {
- .gpio = AT91_PIN_PC18,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-sig2",
- },
- .active_low = 1,
- },
- {
- .name = "LED7",
- .pin = {
- .gpio = AT91_PIN_PC18,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-e",
- },
- .active_low = 1,
- },
- {
- .name = "LED8",
- .pin = {
- .gpio = AT91_PIN_PC17,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-sig3",
- },
- .active_low = 1,
- },
- {
- .name = "LED8",
- .pin = {
- .gpio = AT91_PIN_PC17,
- .flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-f",
- },
- .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,
- },
- {
- .name = "BT_EN",
- .pin = {
- .gpio = AT91_PIN_PA28,
- .flags = GPIOF_OUT_INIT_LOW,
- .label = "bt-enabled",
- },
- },
- {
- .name = "WLAN_EN",
- .pin = {
- .gpio = AT91_PIN_PA27,
- .flags = GPIOF_OUT_INIT_LOW,
- .label = "wlan-enabled",
- },
- },
- { },
-};
-
-struct gpio_pin *gpio_pin_by_name(const char *name) {
- struct gpio_pin *pin;
-
- for (pin = gpio_pins; *pin->name; pin++) {
- if (!strcmp(pin->name, name)) {
- return pin;
- }
- }
-
- log_error("pin named %s not found", name);
-
- return NULL;
-}
-
-struct gpio_pin *gpio_pin_by_attr_name(const char *name) {
- struct gpio_pin *pin;
-
- for (pin = gpio_pins; *pin->name; pin++) {
- if (!strcmp(pin->pin.label, name)) {
- return pin;
- }
- }
-
- log_error("pin with attr name %s not found", name);
-
- return NULL;
-}
-
-
-static struct spi_device *spi_sout_dev;
-static u8 spi_sout_value;
-static DEFINE_MUTEX(spi_sout_mutex);
-static unsigned int sout_max_speed_hz = 1 * 1000 * 1000;
-module_param(sout_max_speed_hz, uint, S_IRUGO);
-MODULE_PARM_DESC(
- sout_max_speed_hz,
- "Maximum clock rate to be used with this device (default: 1 MHz)"
-);
-
-static struct spi_device *spi_dout_dev;
-static u8 spi_dout_value;
-static DEFINE_MUTEX(spi_dout_mutex);
-static unsigned int dout_max_speed_hz = 1 * 1000 * 1000;
-module_param(dout_max_speed_hz, uint, S_IRUGO);
-MODULE_PARM_DESC(
- dout_max_speed_hz,
- "Maximum clock rate to be used with this device (default: 1 MHz)"
-);
-
-static struct spi_device *spi_din_dev;
-static unsigned int din_max_speed_hz = 1 * 1000 * 1000;
-module_param(din_max_speed_hz, uint, S_IRUGO);
-MODULE_PARM_DESC(
- din_max_speed_hz,
- "Maximum clock rate to be used with this device (default: 1 MHz)"
-);
-
-static struct spi_device *spi_dc_dout_dev;
-static u8 spi_dc_dout_value;
-static DEFINE_MUTEX(spi_dc_dout_mutex);
-static unsigned int dc_dout_max_speed_hz = 1 * 1000 * 1000;
-module_param(dc_dout_max_speed_hz, uint, S_IRUGO);
-MODULE_PARM_DESC(
- dc_dout_max_speed_hz,
- "Maximum clock rate to be used with this device (default: 1 MHz)"
-);
-
-static struct spi_device *spi_dc_din_dev;
-static unsigned int dc_din_max_speed_hz = 1 * 1000 * 1000;
-module_param(dc_din_max_speed_hz, uint, S_IRUGO);
-MODULE_PARM_DESC(
- dc_din_max_speed_hz,
- "Maximum clock rate to be used with this device (default: 1 MHz)"
-);
-
-static struct spi_device *spi_dc_adc_dev;
-static unsigned int dc_adc_max_speed_hz = 20 * 1000 * 1000;
-module_param(dc_adc_max_speed_hz, uint, S_IRUGO);
-MODULE_PARM_DESC(
- dc_adc_max_speed_hz,
- "Maximum clock rate to be used with this device (default: 20 MHz)"
-);
-
-static struct spi_device *spi_board_temp_dev;
-static unsigned int board_temp_max_speed_hz = 1 * 1000 * 1000;
-module_param(board_temp_max_speed_hz, uint, S_IRUGO);
-MODULE_PARM_DESC(
- board_temp_max_speed_hz,
- "Maximum clock rate to be used with this device (default: 1 MHz)"
-);
-
-static inline int spi_writen(struct spi_device *spi, const u8 *buf, size_t len)
-{
- int tmp;
- u8 *tx;
-
- tx = kmalloc(len, GFP_KERNEL);
- if (!tx) {
- return -ENOMEM;
- }
-
- memcpy(tx, buf, len);
- tmp = spi_write(spi, tx, len);
+static DEFINE_MUTEX(mts_io_mutex);
- kfree(tx);
+/* generic GPIO support */
+#include "gpio.c"
- return tmp;
-}
+/* AT91 built-in ADC */
+#include "adc.c"
-static inline int spi_readn(struct spi_device *spi, u8 *buf, size_t len)
-{
- int tmp;
- u8 *rx;
+/* SPI-based stuff */
+#include "spi.c"
- rx = kmalloc(len, GFP_KERNEL);
- if (!rx) {
- return -ENOMEM;
- }
+/* accessory card support */
+#include "mtdc_gpiob.c"
- tmp = spi_read(spi, rx, len);
- memcpy(buf, rx, len);
-
- kfree(rx);
-
- return tmp;
-}
+/* telit radio reset handling */
+#include "telit_radio.c"
-#define ADC_SHTIME_DEFAULT 0x05
-#define ADC_STARTUP_DEFAULT 0x04
-#define ADC_PRESCALE_DEFAULT 0x3F
-#define ADC_MODE_DEFAULT \
- ((ADC_SHTIME_DEFAULT & 0x0F) << 24) | \
- ((ADC_STARTUP_DEFAULT & 0x1F) << 16) | \
- ((ADC_PRESCALE_DEFAULT & 0x3F) << 8)
-
-#define ADC_CR_OFFSET 0x00
-#define ADC_MR_OFFSET 0x04
-#define ADC_CHER_OFFSET 0x10
-#define ADC_CHDR_OFFSET 0x14
-#define ADC_CHSR_OFFSET 0x18
-#define ADC_SR_OFFSET 0x1C
-#define ADC_LDCR_OFFSET 0x20
-#define ADC_IER_OFFSET 0x14
-#define ADC_IDR_OFFSET 0x28
-#define ADC_IMR_OFFSET 0x2C
-#define ADC_CDR0_OFFSET 0x30
-#define ADC_CDR1_OFFSET 0x34
-#define ADC_CDR2_OFFSET 0x38
-#define ADC_CDR3_OFFSET 0x3C
-
-void __iomem *adc_base;
-struct clk *adc_clk;
-
-#define ADC_CONVERT_RESET(base) writel(0x01, (base) + ADC_CR_OFFSET)
-#define ADC_CONVERT_START(base) writel(0x02, (base) + ADC_CR_OFFSET)
-
-#define BLINK_PER_SEC 8
-#define BLINK_INTERVAL (HZ / BLINK_PER_SEC)
-#define RESET_HOLD_COUNT (BLINK_PER_SEC * 3)
-#define RESET_LONG_HOLD_COUNT (BLINK_PER_SEC * 30)
+/* reset button handling */
+#define RESET_CHECK_PER_SEC 8
+#define RESET_INTERVAL (HZ / RESET_CHECK_PER_SEC)
+#define RESET_HOLD_COUNT (RESET_CHECK_PER_SEC * 3)
+#define RESET_LONG_HOLD_COUNT (RESET_CHECK_PER_SEC * 30)
static pid_t reset_pid = -1;
static pid_t reset_count = 0;
static int reset_short_signal = SIGUSR1;
static int reset_long_signal = SIGUSR2;
static int reset_extra_long_signal = SIGHUP;
-static DEFINE_MUTEX(mts_io_mutex);
-static void blink_callback(struct work_struct *ignored);
+static void reset_callback(struct work_struct *ignored);
-static DECLARE_DELAYED_WORK(blink_work, blink_callback);
+static DECLARE_DELAYED_WORK(reset_work, reset_callback);
-static void blink_callback(struct work_struct *ignored)
+static void reset_callback(struct work_struct *ignored)
{
struct gpio_pin *pin;
int reset_pressed = 0;
@@ -1394,205 +153,66 @@ static void blink_callback(struct work_struct *ignored)
reset_count = 0;
}
- if (led_mode_status == LED_FLASHING) {
- pin = gpio_pin_by_name("STATUS_LED");
- if (pin) {
- gpio_set_value(pin->pin.gpio, !gpio_get_value(pin->pin.gpio));
- }
- }
-
mutex_unlock(&mts_io_mutex);
- schedule_delayed_work(&blink_work, BLINK_INTERVAL);
+ schedule_delayed_work(&reset_work, RESET_INTERVAL);
}
-static int radio_off_telit(void)
+static ssize_t mts_attr_show_reset_monitor(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- int value, ret;
- struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON");
- struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF");
- struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST");
-
- if (!onoff_pin || !pwrmon_pin || !rst_pin) {
- return -ENODEV;
- }
-
- value = gpio_get_value(pwrmon_pin->pin.gpio);
- if(value == 0) {
- log_error("radio is already off");
- return -EINVAL;
- }
-
- // drive on/off pin low for at least 3 sec
- log_info("shutting down radio");
- ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- msleep(3500);
-
- // set on/off pin high
- ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- // wait for radio to power off
- msleep(5000);
+ int ret;
- // check that power is low
- value = gpio_get_value(pwrmon_pin->pin.gpio);
- if(value != 0) {
- log_warning("radio is still on. performing radio reset.");
- //Perform Hard Reset
- ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
+ mutex_lock(&mts_io_mutex);
- msleep(500);
+ ret = sprintf(buf, "%d %d %d %d\n", reset_pid, reset_short_signal, reset_long_signal, reset_extra_long_signal);
- // set pin high
- ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
- } else {
- log_info("radio has been shut down");
- }
+ mutex_unlock(&mts_io_mutex);
return ret;
}
-static int radio_on_telit(void)
+static ssize_t mts_attr_store_reset_monitor(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- int value, ret;
- struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON");
- struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF");
- struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST");
-
- if (!onoff_pin || !pwrmon_pin || !rst_pin) {
- return -ENODEV;
- }
+ pid_t pid;
+ int short_signal;
+ int long_signal;
+ int extra_long_signal;
+ int result = sscanf(buf, "%i %i %i %i", &pid, &short_signal, &long_signal, &extra_long_signal);
- value = gpio_get_value(pwrmon_pin->pin.gpio);
- if(value != 0) {
- log_error("radio is already on");
+ if (result < 3 || result > 4) {
return -EINVAL;
}
- // drive on/off pin low for at least 5 sec
- log_info("turning on radio");
- ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- msleep(5500);
-
- // set on/off pin high
- ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- msleep(200);
-
- // check that power is high
- value = gpio_get_value(pwrmon_pin->pin.gpio);
- if(value == 0) {
- log_warning("radio is still off. performing radio reset");
- //Perform Hard Reset
- ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- msleep(500);
-
- // set pin high
- ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
- } else {
- log_info("radio has been turned on");
- }
-
- return ret;
-}
+ if(result == 3) {
+ mutex_lock(&mts_io_mutex);
-static ssize_t mts_attr_store_radio_power_telit(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- int err;
+ reset_pid = pid;
+ reset_short_signal = short_signal;
+ reset_long_signal = long_signal;
- if (sscanf(buf, "%i", &value) != 1) {
- return -EINVAL;
- }
- if (value == 0) {
- mutex_lock(&mts_io_mutex);
- err = radio_off_telit();
mutex_unlock(&mts_io_mutex);
} else {
mutex_lock(&mts_io_mutex);
- err = radio_on_telit();
- mutex_unlock(&mts_io_mutex);
- }
- if (err) {
- return err;
+ reset_pid = pid;
+ reset_short_signal = short_signal;
+ reset_long_signal = long_signal;
+ reset_extra_long_signal = extra_long_signal;
+
+ mutex_unlock(&mts_io_mutex);
}
return count;
}
-static int radio_reset_telit(void)
-{
- int ret;
- struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST");
- struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF");
-
- if (!rst_pin || !onoff_pin) {
- return -ENODEV;
- }
-
- // drive reset pin low for 500ms
- ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- msleep(500);
-
- // set pin high
- ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- // wait for 2 sec before toggling on/off pin
- msleep(2000);
-
- // drive on/off pin low for 6 sec
- ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- msleep(6000);
-
- // set on/off pin high
- ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP);
- if (ret) {
- return ret;
- }
-
- return ret;
-}
+static DEVICE_ATTR_MTS(dev_attr_reset_monitor, "reset-monitor",
+ mts_attr_show_reset_monitor, mts_attr_store_reset_monitor);
+static DEVICE_ATTR_RO_MTS(dev_attr_reset, "reset", mts_attr_show_gpio_pin);
+/* generic peripheral reset functions */
static int radio_reset(void)
{
struct gpio_pin *pin = gpio_pin_by_name("RADIO_RESET");
@@ -1610,89 +230,6 @@ static int radio_reset(void)
return 0;
}
-static int ndc_reset(void)
-{
- struct gpio_pin *pin = gpio_pin_by_name("NDC_RESET");
-
- if (!pin) {
- return -ENODEV;
- }
-
- gpio_set_value(pin->pin.gpio, 0);
-
- mdelay(1);
-
- gpio_set_value(pin->pin.gpio, 1);
-
- return 0;
-}
-
-static int ADT7302_to_celsius(int value)
-{
- if (value & 0x2000) {
- value = value - 16384;
- }
-
- value = value / 32 + 1 * ((value % 32) >= 16);
-
- return value;
-}
-
-static ssize_t mts_attr_show_gpio_pin(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int value;
- struct gpio_pin *pin = gpio_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_gpio_pin(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- struct gpio_pin *pin = gpio_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_store_radio_reset(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1719,38 +256,23 @@ static ssize_t mts_attr_store_radio_reset(struct device *dev,
return count;
}
-static ssize_t mts_attr_store_radio_reset_telit(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+static int ndc_reset(void)
{
- int value;
- int err;
+ struct gpio_pin *pin = gpio_pin_by_name("NDC_RESET");
- if (sscanf(buf, "%i", &value) != 1) {
- return -EINVAL;
- }
- if (value != 0) {
- return -EINVAL;
+ if (!pin) {
+ return -ENODEV;
}
- mutex_lock(&mts_io_mutex);
-
- err = radio_reset_telit();
+ gpio_set_value(pin->pin.gpio, 0);
- mutex_unlock(&mts_io_mutex);
+ mdelay(1);
- if (err) {
- return err;
- }
+ gpio_set_value(pin->pin.gpio, 1);
- return count;
+ return 0;
}
-static DEVICE_ATTR_MTS(dev_attr_radio_power, "radio-power",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
-static DEVICE_ATTR_MTS(dev_attr_radio_reset, "radio-reset",
- mts_attr_show_gpio_pin, mts_attr_store_radio_reset);
-
static ssize_t mts_attr_store_ndc_reset(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1776,397 +298,35 @@ static ssize_t mts_attr_store_ndc_reset(struct device *dev,
return count;
}
+
+static DEVICE_ATTR_MTS(dev_attr_radio_reset, "radio-reset",
+ mts_attr_show_gpio_pin, mts_attr_store_radio_reset);
static DEVICE_ATTR_MTS(dev_attr_ndc_reset, "ndc-reset",
mts_attr_show_gpio_pin, mts_attr_store_ndc_reset);
+/* shared gpio attributes */
+static DEVICE_ATTR_MTS(dev_attr_radio_power, "radio-power",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
static DEVICE_ATTR_MTS(dev_attr_eth0_enabled, "eth0-enabled",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
static DEVICE_ATTR_MTS(dev_attr_bt_enabled, "bt-enabled",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
static DEVICE_ATTR_MTS(dev_attr_wlan_enabled, "wlan-enabled",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
-static ssize_t mts_attr_store_sout(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- u8 bit;
-
- if (!spi_sout_dev) {
- log_notice("sout device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "extserial-ri")) {
- bit = SOUT_EXTSERIAL_RI_BIT;
- } else if (!strcmp(attr->attr.name, "extserial-dsr")) {
- bit = SOUT_EXTSERIAL_DSR_BIT;
- } else if (!strcmp(attr->attr.name, "extserial-dcd")) {
- bit = SOUT_EXTSERIAL_DCD_BIT;
- } else if (!strcmp(attr->attr.name, "led-cd") ||
- !strcmp(attr->attr.name, "led-sdk-b")) {
- bit = SOUT_LED_CD_BIT;
- } else if (!strcmp(attr->attr.name, "led-dtr") ||
- !strcmp(attr->attr.name, "led-sdk-f")) {
- bit = SOUT_LED_DTR;
- } else if (!strcmp(attr->attr.name, "led-sig1") ||
- !strcmp(attr->attr.name, "led-sdk-c")) {
- bit = SOUT_LED_SIG1_BIT;
- } else if (!strcmp(attr->attr.name, "led-sig2") ||
- !strcmp(attr->attr.name, "led-sdk-d")) {
- bit = SOUT_LED_SIG2_BIT;
- } else if (!strcmp(attr->attr.name, "led-sig3") ||
- !strcmp(attr->attr.name, "led-sdk-e")) {
- bit = SOUT_LED_SIG3_BIT;
- } else {
- log_notice("sout attr does not exist");
- return -ENOENT;
- }
-
- if (sscanf(buf, "%i", &value) != 1) {
- log_notice("sout attr invalid argument");
- return -EINVAL;
- }
-
- mutex_lock(&spi_sout_mutex);
-
- if (value) {
- spi_sout_value &= ~bit;
- } else {
- spi_sout_value |= bit;
- }
- spi_writen(spi_sout_dev, &spi_sout_value, 1);
-
- mutex_unlock(&spi_sout_mutex);
-
- return count;
-}
-
-static ssize_t mts_attr_show_sout(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int value;
- u8 bit;
-
- if (!spi_sout_dev) {
- log_error("sout device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "extserial-ri")) {
- bit = SOUT_EXTSERIAL_RI_BIT;
- } else if (!strcmp(attr->attr.name, "extserial-dsr")) {
- bit = SOUT_EXTSERIAL_DSR_BIT;
- } else if (!strcmp(attr->attr.name, "extserial-dcd")) {
- bit = SOUT_EXTSERIAL_DCD_BIT;
- } else if (!strcmp(attr->attr.name, "led-cd") ||
- !strcmp(attr->attr.name, "led-sdk-b")) {
- bit = SOUT_LED_CD_BIT;
- } else if (!strcmp(attr->attr.name, "led-dtr") ||
- !strcmp(attr->attr.name, "led-sdk-f")) {
- bit = SOUT_LED_DTR;
- } else if (!strcmp(attr->attr.name, "led-sig1") ||
- !strcmp(attr->attr.name, "led-sdk-c")) {
- bit = SOUT_LED_SIG1_BIT;
- } else if (!strcmp(attr->attr.name, "led-sig2") ||
- !strcmp(attr->attr.name, "led-sdk-d")) {
- bit = SOUT_LED_SIG2_BIT;
- } else if (!strcmp(attr->attr.name, "led-sig3") ||
- !strcmp(attr->attr.name, "led-sdk-e")) {
- bit = SOUT_LED_SIG3_BIT;
- } else {
- log_notice("sout attr does not exist");
- return -ENOENT;
- }
-
- mutex_lock(&spi_sout_mutex);
-
- value = spi_sout_value & bit ? 0 : 1;
-
- mutex_unlock(&spi_sout_mutex);
-
- return sprintf(buf, "%d\n", value);
-}
-
-static DEVICE_ATTR_MTS(dev_attr_extserial_dcd, "extserial-dcd",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_extserial_ri, "extserial-ri",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_extserial_dsr, "extserial-dsr",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_cd, "led-cd",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sdk_b, "led-sdk-b",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sig1, "led-sig1",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sdk_c, "led-sdk-c",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sig2, "led-sig2",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sdk_d, "led-sdk-d",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sig3, "led-sig3",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sdk_e, "led-sdk-e",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_dtr, "led-dtr",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static DEVICE_ATTR_MTS(dev_attr_led_sdk_f, "led-sdk-f",
- mts_attr_show_sout, mts_attr_store_sout);
-
-static ssize_t mts_attr_store_dout(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- u8 bit;
-
- if (!spi_dout_dev) {
- log_notice("dout device not present");
- return -ENODEV;
- }
-
- if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) {
- bit = BIT(0);
- } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) {
- bit = BIT(1);
- } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) {
- bit = BIT(2);
- } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) {
- bit = BIT(3);
- } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) {
- bit = BIT(4);
- } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) {
- bit = BIT(5);
- } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) {
- bit = BIT(6);
- } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) {
- bit = BIT(7);
- } else {
- log_notice("dout attr does not exist");
- return -ENOENT;
- }
-
- if (sscanf(buf, "%i", &value) != 1) {
- log_notice("dout attr invalid argument");
- return -EINVAL;
- }
-
- mutex_lock(&spi_dout_mutex);
-
- if (value) {
- spi_dout_value &= ~bit;
- } else {
- spi_dout_value |= bit;
- }
-
- spi_writen(spi_dout_dev, &spi_dout_value, 1);
-
- mutex_unlock(&spi_dout_mutex);
-
- return count;
-}
-
-static ssize_t mts_attr_show_dout(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int value;
- u8 bit;
-
- if (!spi_dout_dev) {
- log_error("dout device not present");
- return -ENODEV;
- }
-
- if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) {
- bit = BIT(0);
- } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) {
- bit = BIT(1);
- } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) {
- bit = BIT(2);
- } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) {
- bit = BIT(3);
- } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) {
- bit = BIT(4);
- } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) {
- bit = BIT(5);
- } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) {
- bit = BIT(6);
- } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) {
- bit = BIT(7);
- } else {
- log_notice("dout attr does not exist");
- return -ENOENT;
- }
-
- mutex_lock(&spi_dout_mutex);
-
- value = spi_dout_value & bit ? 0 : 1;
-
- mutex_unlock(&spi_dout_mutex);
-
- return sprintf(buf, "%d\n", value);
-}
-
-
-static DEVICE_ATTR_MTS(dev_attr_dout0, "dout0",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_dout1, "dout1",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_dout2, "dout2",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_dout3, "dout3",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_dout4, "dout4",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_dout5, "dout5",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_dout6, "dout6",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_dout7, "dout7",
- mts_attr_show_dout, mts_attr_store_dout);
-
-
-static ssize_t mts_attr_show_din(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int tmp;
- u8 bit;
- u8 byte;
-
- if (!spi_din_dev) {
- log_error("din device not present");
- return -ENODEV;
- }
-
- if ((!strcmp(attr->attr.name, "din0")) || (!strcmp(attr->attr.name, "gpi5"))) {
- bit = BIT(0);
- } else if ((!strcmp(attr->attr.name, "din1")) || (!strcmp(attr->attr.name, "gpi6"))) {
- bit = BIT(1);
- } else if ((!strcmp(attr->attr.name, "din2")) || (!strcmp(attr->attr.name, "gpi7"))) {
- bit = BIT(2);
- } else if ((!strcmp(attr->attr.name, "din3")) || (!strcmp(attr->attr.name, "gpi8"))) {
- bit = BIT(3);
- } else if ((!strcmp(attr->attr.name, "din4")) || (!strcmp(attr->attr.name, "gpi9"))) {
- bit = BIT(4);
- } else if ((!strcmp(attr->attr.name, "din5")) || (!strcmp(attr->attr.name, "gpi10"))) {
- bit = BIT(5);
- } else if (!strcmp(attr->attr.name, "din6")) {
- bit = BIT(6);
- } else if (!strcmp(attr->attr.name, "din7")) {
- bit = BIT(7);
- } else {
- log_notice("din attr does not exist");
- return -ENOENT;
- }
-
- tmp = spi_readn(spi_din_dev, &byte, 1);
- if (tmp) {
- log_error("spi_read failed %d", tmp);
- return tmp;
- }
-
- tmp = byte & bit ? 1 : 0;
-
- return sprintf(buf, "%d\n", tmp);
-}
-
-static DEVICE_ATTR_RO_MTS(dev_attr_din0, "din0", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_din1, "din1", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_din2, "din2", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_din3, "din3", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_din4, "din4", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_din5, "din5", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_din6, "din6", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_din7, "din7", mts_attr_show_din);
-
static DEVICE_ATTR_RO_MTS(dev_attr_extserial_dtr, "extserial-dtr",
mts_attr_show_gpio_pin);
-
static DEVICE_ATTR_MTS(dev_attr_extserial_dsr_gpio, "extserial-dsr",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
static DEVICE_ATTR_MTS(dev_attr_extserial_ri_gpio, "extserial-ri",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
+static DEVICE_ATTR_MTS(dev_attr_extserial_dcd_gpio, "extserial-dcd",
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-static ssize_t mts_attr_show_led_status(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- return sprintf(buf, "%d\n", led_mode_status);
-}
-
-static ssize_t mts_attr_store_led_status(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- int ret;
- struct gpio_pin *pin = gpio_pin_by_name("STATUS_LED");
-
- if (!pin) {
- return -ENODEV;
- }
-
- if (sscanf(buf, "%i", &value) != 1) {
- return -EINVAL;
- }
-
- mutex_lock(&mts_io_mutex);
-
- switch (value) {
- case LED_OFF:
- led_mode_status = LED_OFF;
- gpio_set_value(pin->pin.gpio, 1);
-
- break;
-
- case LED_ON:
- led_mode_status = LED_ON;
- gpio_set_value(pin->pin.gpio, 0);
-
- break;
-
- case LED_FLASHING:
- led_mode_status = LED_FLASHING;
- gpio_set_value(pin->pin.gpio, 0);
-
- break;
-
- default:
- ret = -EINVAL;
- }
-
- mutex_unlock(&mts_io_mutex);
-
- return count;
-}
-
+/* shared gpio-based LEDs */
static DEVICE_ATTR_MTS(dev_attr_led_status, "led-status",
- mts_attr_show_led_status, mts_attr_store_led_status);
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
static DEVICE_ATTR_MTS(dev_attr_led_a_gpio, "led-a",
- mts_attr_show_led_status, mts_attr_store_led_status);
-
-#if LED_STATUS_CONTROLLABLE_MTCDP
-static DEVICE_ATTR_MTS(dev_attr_led_sdk_a, "led-sdk-a",
- mts_attr_show_led_status, mts_attr_store_led_status);
-#endif
+ mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
#if LED_LS_CONTROLLABLE
static DEVICE_ATTR_MTS(dev_attr_led_ls, "led-ls",
@@ -2200,288 +360,8 @@ static DEVICE_ATTR_MTS(dev_attr_led_e_gpio, "led-e",
static DEVICE_ATTR_MTS(dev_attr_led_f_gpio, "led-f",
mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-static DEVICE_ATTR_RO_MTS(dev_attr_reset, "reset", mts_attr_show_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 ssize_t mts_attr_show_reset_monitor(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int ret;
-
- mutex_lock(&mts_io_mutex);
-
- ret = sprintf(buf, "%d %d %d %d\n", reset_pid, reset_short_signal, reset_long_signal, reset_extra_long_signal);
-
- mutex_unlock(&mts_io_mutex);
-
- return ret;
-}
-
-static ssize_t mts_attr_store_reset_monitor(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- pid_t pid;
- int short_signal;
- int long_signal;
- int extra_long_signal;
- int result = sscanf(buf, "%i %i %i %i", &pid, &short_signal, &long_signal, &extra_long_signal);
-
- if (result < 3 || result > 4) {
- return -EINVAL;
- }
-
- if(result == 3) {
- mutex_lock(&mts_io_mutex);
-
- reset_pid = pid;
- reset_short_signal = short_signal;
- reset_long_signal = long_signal;
-
- mutex_unlock(&mts_io_mutex);
- } else {
- mutex_lock(&mts_io_mutex);
-
- reset_pid = pid;
- reset_short_signal = short_signal;
- reset_long_signal = long_signal;
- reset_extra_long_signal = extra_long_signal;
-
- mutex_unlock(&mts_io_mutex);
- }
-
- return count;
-}
-
-static DEVICE_ATTR_MTS(dev_attr_reset_monitor, "reset-monitor",
- mts_attr_show_reset_monitor, mts_attr_store_reset_monitor);
-
-static ssize_t mts_attr_show_board_temperature(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int tmp;
- u16 temp_raw;
-
- if (!spi_board_temp_dev) {
- log_notice("spi_board_temp device not present");
- return -ENODEV;
- }
-
- tmp = spi_readn(spi_board_temp_dev, (u8 *) buf, 2);
- if (tmp) {
- log_error("spi_readn failed %d", tmp);
- return tmp;
- }
- temp_raw = ((u8 *) buf)[0] << 8 | ((u8 *) buf)[1];
-
- log_debug("temp: 0x%04X", temp_raw);
-
- return sprintf(buf, "%d\n", ADT7302_to_celsius(temp_raw));
-}
-
-static DEVICE_ATTR_RO_MTS(dev_attr_board_temperature, "board-temperature",
- mts_attr_show_board_temperature);
-
-static ssize_t mts_attr_show_adc(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int offset;
- u32 value;
- u32 chan_mask;
-
- if (!DEVICE_CAPA(id_eeprom.capa, CAPA_ADC)) {
- log_debug("ADC not available");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "adc0")) {
- offset = ADC_CDR0_OFFSET;
- chan_mask = 0x01;
- } else if (!strcmp(attr->attr.name, "adc1")) {
- offset = ADC_CDR1_OFFSET;
- chan_mask = 0x02;
- } else if (!strcmp(attr->attr.name, "adc2")) {
- offset = ADC_CDR2_OFFSET;
- chan_mask = 0x04;
- } else if (!strcmp(attr->attr.name, "adc3")) {
- offset = ADC_CDR3_OFFSET;
- chan_mask = 0x08;
- } else {
- log_notice("adc attr does not exist");
- return -ENOENT;
- }
-
- mutex_lock(&mts_io_mutex);
-
- // disable all channels and enable the one we want
- writel(0x0F, adc_base + ADC_CHDR_OFFSET);
- writel(chan_mask, adc_base + ADC_CHER_OFFSET);
-
- ADC_CONVERT_START(adc_base);
-
- // wait for conversion to complete (EOC bit set)
- value = 0;
- while (value != chan_mask) {
- value = readl(adc_base + ADC_SR_OFFSET) & chan_mask;
- log_debug("ADC_SR EOC [%X]", value);
- }
-
- // read result
- value = readl(adc_base + offset);
-
- mutex_unlock(&mts_io_mutex);
-
- return sprintf(buf, "%lu\n", (unsigned long) value);
-}
-
-static DEVICE_ATTR_RO_MTS(dev_attr_adc0, "adc0", mts_attr_show_adc);
-static DEVICE_ATTR_RO_MTS(dev_attr_adc1, "adc1", mts_attr_show_adc);
-static DEVICE_ATTR_RO_MTS(dev_attr_adc2, "adc2", mts_attr_show_adc);
-static DEVICE_ATTR_RO_MTS(dev_attr_adc3, "adc3", mts_attr_show_adc);
-
-static DEVICE_ATTR_RO_MTS(dev_attr_usbh2_ps_oc, "usbh2-ps-oc",
- mts_attr_show_gpio_pin);
-
-#if USBH2_PS_CONTROLLABLE
-static DEVICE_ATTR_MTS(dev_attr_usbh2_ps_enabled, "usbh2-ps-enabled",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-#endif
-
-static DEVICE_ATTR_MTS(dev_attr_gpo1, "gpo1",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_gpo2, "gpo2",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_gpo3, "gpo3",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_gpo4, "gpo4",
- mts_attr_show_dout, mts_attr_store_dout);
-
-static DEVICE_ATTR_RO_MTS(dev_attr_gpi5, "gpi5", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_gpi6, "gpi6", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_gpi7, "gpi7", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_gpi8, "gpi8", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_gpi9, "gpi9", mts_attr_show_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_gpi10, "gpi10", mts_attr_show_din);
-
-static DEVICE_ATTR_MTS(dev_attr_led1, "led1",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_led2, "led2",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
-#if LED_LS_CONTROLLABLE
-static DEVICE_ATTR_MTS(dev_attr_led3, "led3",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-#else
-static DEVICE_ATTR_RO_MTS(dev_attr_led3, "led3", mts_attr_show_gpio_pin);
-#endif
-
-static DEVICE_ATTR_MTS(dev_attr_led4, "led4",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_led5, "led5",
- mts_attr_show_dout, mts_attr_store_dout);
-static DEVICE_ATTR_MTS(dev_attr_led6, "led6",
- mts_attr_show_dout, mts_attr_store_dout);
-
-static DEVICE_ATTR_MTS(dev_attr_gpio11, "gpio11",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-static DEVICE_ATTR_MTS(dev_attr_gpio12, "gpio12",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
-static DEVICE_ATTR_MTS(dev_attr_rsersrc, "rsersrc",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-static DEVICE_ATTR_MTS(dev_attr_extserial_dcd_gpio, "extserial-dcd",
- mts_attr_show_gpio_pin, mts_attr_store_gpio_pin);
-
-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;
-}
+/* eeprom info */
static ssize_t mts_attr_show_product_info(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -2522,882 +402,29 @@ static ssize_t mts_attr_show_product_info(struct device *dev,
return value;
}
-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_radio_power_telit, "radio-power",
- mts_attr_show_gpio_pin, mts_attr_store_radio_power_telit);
-
-static DEVICE_ATTR_MTS(dev_attr_radio_reset_telit, "radio-reset",
- mts_attr_show_gpio_pin, mts_attr_store_radio_reset_telit);
-
static DEVICE_ATTR_RO_MTS(dev_attr_vendor_id, "vendor-id",
mts_attr_show_product_info);
-
static DEVICE_ATTR_RO_MTS(dev_attr_product_id, "product-id",
mts_attr_show_product_info);
-
static DEVICE_ATTR_RO_MTS(dev_attr_device_id, "device-id",
mts_attr_show_product_info);
-
static DEVICE_ATTR_RO_MTS(dev_attr_hw_version, "hw-version",
mts_attr_show_product_info);
-
static DEVICE_ATTR_RO_MTS(dev_attr_imei, "imei",
mts_attr_show_product_info);
-
static DEVICE_ATTR_RO_MTS(dev_attr_wifi_mac, "mac-wifi",
mts_attr_show_product_info);
-
static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth",
mts_attr_show_product_info);
-struct gpio_pin *dc_gpio_pin_by_attr_name(const char *name) {
- struct gpio_pin *pin;
- char *pin_attr_name;
-
- if (!strcmp(name, "led1")) {
- pin_attr_name = "dc-gpio1";
- } else if (!strcmp(name, "led2")) {
- pin_attr_name = "dc-gpio2";
- } else if (!strcmp(name, "dout-enable")) {
- pin_attr_name = "dc-gpio3";
- } else {
- log_error("daughter 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_dc_gpio_pin(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- int value;
- struct gpio_pin *pin = dc_gpio_pin_by_attr_name(attr->attr.name);
-
- if (!pin) {
- return -ENODEV;
- }
+/* include per-device pins and attributes */
+#include "mtr2.c"
+#include "mtr.c"
- 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_dc_gpio_pin(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- struct gpio_pin *pin = dc_gpio_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_dc_din(struct device *dev, struct device_attribute *attr, char *buf)
-{
- int tmp;
- u8 bit;
- u8 byte;
-
- if (!spi_dc_din_dev) {
- log_error("dc din device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "din0")) {
- bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "din1")) {
- bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "din2")) {
- bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "din3")) {
- bit = BIT(3);
- } else {
- log_error("dc din attr does not exist");
- return -ENOENT;
- }
-
- tmp = spi_readn(spi_dc_din_dev, &byte, 1);
- if (tmp) {
- log_error("spi_read failed %d", tmp);
- return tmp;
- }
-
- tmp = byte & bit ? 1 : 0;
-
- return sprintf(buf, "%d\n", tmp);
-}
-
-static ssize_t mts_attr_store_dc_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- u8 bit;
-
- if (!spi_dc_dout_dev) {
- log_error("dc dout device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "dout0")) {
- bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "dout1")) {
- bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "dout2")) {
- bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "dout3")) {
- bit = BIT(3);
- } else {
- log_error("dc dout attr does not exist");
- return -ENOENT;
- }
-
- if (sscanf(buf, "%i", &value) != 1) {
- log_error("dc dout attr invalid argument");
- return -EINVAL;
- }
-
- mutex_lock(&spi_dc_dout_mutex);
-
- if (value) {
- spi_dc_dout_value &= ~bit;
- } else {
- spi_dc_dout_value |= bit;
- }
-
- spi_writen(spi_dc_dout_dev, &spi_dc_dout_value, 1);
-
- mutex_unlock(&spi_dc_dout_mutex);
-
- return count;
-}
-
-static ssize_t mts_attr_show_dc_dout(struct device *dev, struct device_attribute *attr, char *buf)
-{
- int value;
- u8 bit;
-
- if (!spi_dc_dout_dev) {
- log_error("dc dout device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "dout0")) {
- bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "dout1")) {
- bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "dout2")) {
- bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "dout3")) {
- bit = BIT(3);
- } else {
- log_error("dc dout attr does not exist");
- return -ENOENT;
- }
-
- mutex_lock(&spi_dc_dout_mutex);
-
- value = spi_dc_dout_value & bit ? 0 : 1;
-
- mutex_unlock(&spi_dc_dout_mutex);
-
- return sprintf(buf, "%d\n", value);
-}
-
-static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute *attr, char *buf)
-{
- int tmp;
- int tx_data;
- int rx_data;
- int channel;
- int channel_mask = 0x0180; /* 0b 0000 0001 1000 0000 */
- int manual_mode = 0x1840; /* 0b 0001 1000 0100 0000 */
- uint8_t tx[2];
- uint8_t rx[2];
-
- if (!spi_dc_adc_dev) {
- log_error("dc adc device not present");
- return -ENODEV;
- }
-
- memset(tx, 0, sizeof(tx));
- memset(rx, 0, sizeof(rx));
-
- if (!strcmp(attr->attr.name, "adc0")) {
- channel = 0;
- } else if (!strcmp(attr->attr.name, "adc1")) {
- channel = 1;
- } else if (! strcmp(attr->attr.name, "adc2")) {
- channel = 2;
- } else {
- log_error("dc adc attr does not exist");
- return -ENOENT;
- }
-
- /* 1st transfer to set up (5V reference, channel to read from) */
- tx_data = manual_mode | ((channel << 7) & channel_mask);
- tx[0] = tx_data >> 8;
- tx[1] = tx_data & 0xFF;
- tmp = spi_writen(spi_dc_adc_dev, tx, 2);
- if (tmp) {
- log_error("spi_write failed %d", tmp);
- return tmp;
- }
-
- /* 2nd transfer to clock chip for ADC conversion
- * this can be a throw-away read or an empty write,
- * the ADC just needs the clock running so it can convert */
- tx[0] = 0;
- tx[1] = 0;
- tmp = spi_writen(spi_dc_adc_dev, tx, 2);
- if (tmp) {
- log_error("2nd spi_write failed %d", tmp);
- return tmp;
- }
-
- /* 3rd transfer to read data */
- tmp = spi_readn(spi_dc_adc_dev, rx, 2);
- if (tmp) {
- log_error("spi_read failed %d", tmp);
- return tmp;
- }
- rx_data = ((rx[0] & 0x0F) << 8) | (rx[1] & 0xFF);
-
- return sprintf(buf, "%lu\n", (unsigned long) rx_data);
-}
-
-/* MTDC-GPIOB */
-static DEVICE_ATTR_RO_MTS(dev_attr_dc_din0, "din0", mts_attr_show_dc_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_dc_din1, "din1", mts_attr_show_dc_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_dc_din2, "din2", mts_attr_show_dc_din);
-static DEVICE_ATTR_RO_MTS(dev_attr_dc_din3, "din3", mts_attr_show_dc_din);
-static DEVICE_ATTR_MTS(dev_attr_dc_dout0, "dout0", mts_attr_show_dc_dout, mts_attr_store_dc_dout);
-static DEVICE_ATTR_MTS(dev_attr_dc_dout1, "dout1", mts_attr_show_dc_dout, mts_attr_store_dc_dout);
-static DEVICE_ATTR_MTS(dev_attr_dc_dout2, "dout2", mts_attr_show_dc_dout, mts_attr_store_dc_dout);
-static DEVICE_ATTR_MTS(dev_attr_dc_dout3, "dout3", mts_attr_show_dc_dout, mts_attr_store_dc_dout);
-static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc0, "adc0", mts_attr_show_dc_adc);
-static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc1, "adc1", mts_attr_show_dc_adc);
-static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc2, "adc2", mts_attr_show_dc_adc);
-static DEVICE_ATTR_MTS(dev_attr_dc_led1, "led1", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin);
-static DEVICE_ATTR_MTS(dev_attr_dc_led2, "led2", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin);
-static DEVICE_ATTR_MTS(dev_attr_dc_oe, "dout-enable", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin);
-
-static struct attribute *mt100eocg_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_extserial_dtr.attr,
- &dev_attr_extserial_dcd_gpio.attr,
- &dev_attr_rsersrc.attr,
- &dev_attr_radio_reset.attr,
- &dev_attr_eth0_enabled.attr,
- &dev_attr_gpio11.attr,
- &dev_attr_gpio12.attr,
-
- &dev_attr_gpo1.attr,
- &dev_attr_gpo2.attr,
- &dev_attr_gpo3.attr,
- &dev_attr_gpo4.attr,
- &dev_attr_led1.attr,
- &dev_attr_led2.attr,
- &dev_attr_led3.attr,
- &dev_attr_led4.attr,
- &dev_attr_led5.attr,
- &dev_attr_led6.attr,
-
- &dev_attr_gpi5.attr,
- &dev_attr_gpi6.attr,
- &dev_attr_gpi7.attr,
- &dev_attr_gpi8.attr,
- &dev_attr_gpi9.attr,
- &dev_attr_gpi10.attr,
-
- &dev_attr_board_temperature.attr,
-
- &dev_attr_adc0.attr,
- &dev_attr_adc1.attr,
- &dev_attr_adc2.attr,
- &dev_attr_adc3.attr,
-
- NULL,
-};
-
-static struct attribute_group mt100eocg_platform_attribute_group = {
- .attrs = mt100eocg_platform_attributes
-};
-
-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 struct attribute_group mtr2_platform_attribute_group = {
- .attrs = mtr2_platform_attributes
-};
-
-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 *mtcdp_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_reset.attr,
- &dev_attr_reset_monitor.attr,
- &dev_attr_radio_reset.attr,
- &dev_attr_ndc_reset.attr,
- &dev_attr_eth0_enabled.attr,
- &dev_attr_extserial_dtr.attr,
- &dev_attr_led_ls.attr,
-#if LED_STATUS_CONTROLLABLE_MTCDP
- &dev_attr_led_status.attr,
- &dev_attr_led_sdk_a.attr,
-#endif
- &dev_attr_usbh2_ps_oc.attr,
-#if USBH2_PS_CONTROLLABLE
- &dev_attr_usbh2_ps_enabled.attr,
-#endif
-
- &dev_attr_extserial_dcd.attr,
- &dev_attr_extserial_ri.attr,
- &dev_attr_extserial_dsr.attr,
- &dev_attr_led_cd.attr,
- &dev_attr_led_sdk_b.attr,
- &dev_attr_led_sig1.attr,
- &dev_attr_led_sdk_c.attr,
- &dev_attr_led_sig2.attr,
- &dev_attr_led_sdk_d.attr,
- &dev_attr_led_sig3.attr,
- &dev_attr_led_sdk_e.attr,
- &dev_attr_led_dtr.attr,
- &dev_attr_led_sdk_f.attr,
-
- &dev_attr_dout0.attr,
- &dev_attr_dout1.attr,
- &dev_attr_dout2.attr,
- &dev_attr_dout3.attr,
- &dev_attr_dout4.attr,
- &dev_attr_dout5.attr,
- &dev_attr_dout6.attr,
- &dev_attr_dout7.attr,
-
- &dev_attr_din0.attr,
- &dev_attr_din1.attr,
- &dev_attr_din2.attr,
- &dev_attr_din3.attr,
- &dev_attr_din4.attr,
- &dev_attr_din5.attr,
- &dev_attr_din6.attr,
- &dev_attr_din7.attr,
-
- &dev_attr_board_temperature.attr,
-
- &dev_attr_adc0.attr,
- &dev_attr_adc1.attr,
- &dev_attr_adc2.attr,
- &dev_attr_adc3.attr,
-
- NULL,
-};
-
-static struct attribute_group mtcdp_platform_attribute_group = {
- .attrs = mtcdp_platform_attributes
-};
-
-static struct attribute *mtr_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_telit.attr,
- &dev_attr_radio_reset_telit.attr,
- &dev_attr_extserial_ri_gpio.attr,
- &dev_attr_extserial_dtr.attr,
- &dev_attr_extserial_dsr_gpio.attr,
- &dev_attr_extserial_dcd_gpio.attr,
- &dev_attr_eth0_enabled.attr,
- &dev_attr_bt_enabled.attr,
- &dev_attr_wlan_enabled.attr,
-
- &dev_attr_led_status.attr,
- &dev_attr_led_sig1_gpio.attr,
- &dev_attr_led_sig2_gpio.attr,
- &dev_attr_led_sig3_gpio.attr,
- &dev_attr_led_cd_gpio.attr,
- &dev_attr_led_wifi_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,
-
- NULL,
-};
-
-static struct attribute_group mtr_platform_attribute_group = {
- .attrs = mtr_platform_attributes
-};
-
-static struct platform_device *mts_io_platform_device;
-
-static int mts_spi_sout_probe(struct spi_device *spi)
-{
- int tmp;
-
- spi->max_speed_hz = sout_max_speed_hz;
- spi->mode = 0;
-
- log_debug("sout_max_speed_hz: %d", sout_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup sout failed");
- return tmp;
- }
-
- spi_sout_value = 0xFF;
- spi_writen(spi, &spi_sout_value, 1);
-
- spi_sout_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_sout_remove(struct spi_device *spi)
-{
- spi_sout_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_sout_driver = {
- .driver = {
- .name = "mts-io-sout",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_sout_probe,
- .remove = mts_spi_sout_remove,
-};
-
-static int mts_spi_dout_probe(struct spi_device *spi)
-{
- int tmp;
-
- if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DOUT)) {
- log_debug("digital outputs not available");
- return -ENODEV;
- }
-
- spi->max_speed_hz = dout_max_speed_hz;
- spi->mode = 0;
-
- log_debug("dout_max_speed_hz: %d", dout_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup dout failed");
- return tmp;
- }
-
- spi_dout_value = 0x00;
- spi_writen(spi, &spi_dout_value, 1);
-
- spi_dout_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_dout_remove(struct spi_device *spi)
-{
- spi_dout_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_dout_driver = {
- .driver = {
- .name = "mts-io-dout",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_dout_probe,
- .remove = mts_spi_dout_remove,
-};
-
-static int mts_spi_din_probe(struct spi_device *spi)
-{
- int tmp;
-
- if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DIN)) {
- log_debug("digital inputs not available");
- return -ENODEV;
- }
-
- spi->max_speed_hz = din_max_speed_hz;
- spi->mode = SPI_CPOL;
-
- log_debug("din_max_speed_hz: %d", din_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup din failed");
- return tmp;
- }
-
- spi_din_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_din_remove(struct spi_device *spi)
-{
- spi_din_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_din_driver = {
- .driver = {
- .name = "mts-io-din",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_din_probe,
- .remove = mts_spi_din_remove,
-};
-
-static int mts_spi_dc_dout_probe(struct spi_device *spi)
-{
- int tmp;
-
- if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) {
- log_error("daughter card digital outputs not available");
- return -ENODEV;
- }
-
- spi->max_speed_hz = dc_dout_max_speed_hz;
- spi->mode = 0;
-
- log_debug("dc_dout_max_speed_hz: %d", dc_dout_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup dc dout failed");
- return tmp;
- }
-
- spi_dc_dout_value = 0x00;
- spi_writen(spi, &spi_dc_dout_value, 1);
-
- spi_dc_dout_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_dc_dout_remove(struct spi_device *spi)
-{
- spi_dc_dout_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_dc_dout_driver = {
- .driver = {
- .name = "mts-io-dc-dout",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_dc_dout_probe,
- .remove = mts_spi_dc_dout_remove,
-};
-
-static int mts_spi_dc_din_probe(struct spi_device *spi)
-{
- int tmp;
-
- if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) {
- log_error("daughter card digital inputs not available");
- return -ENODEV;
- }
-
- spi->max_speed_hz = dc_din_max_speed_hz;
- spi->mode = SPI_CPOL;
-
- log_debug("dc_din_max_speed_hz: %d", dc_din_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup daughter card din failed");
- return tmp;
- }
-
- spi_dc_din_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_dc_din_remove(struct spi_device *spi)
-{
- spi_dc_din_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_dc_din_driver = {
- .driver = {
- .name = "mts-io-dc-din",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_dc_din_probe,
- .remove = mts_spi_dc_din_remove,
-};
-
-static int mts_spi_dc_adc_probe(struct spi_device *spi)
-{
- int tmp;
-
- if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) {
- log_error("daughter card analog to digital not available");
- return -ENODEV;
- }
-
- spi->max_speed_hz = dc_adc_max_speed_hz;
- spi->mode = 0;
-
- log_debug("dc_adc_max_speed_hz: %d", dc_adc_max_speed_hz);
- log_debug("dc_adc_mode: %d", spi->mode);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup daughter card adc failed");
- return tmp;
- }
-
- spi_dc_adc_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_dc_adc_remove(struct spi_device *spi)
-{
- spi_dc_adc_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_dc_adc_driver = {
- .driver = {
- .name = "mts-io-dc-adc",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_dc_adc_probe,
- .remove = mts_spi_dc_adc_remove,
-};
-
-static int mts_spi_board_temp_probe(struct spi_device *spi)
-{
- int tmp;
-
- spi->max_speed_hz = board_temp_max_speed_hz;
- spi->mode = SPI_CPOL | SPI_CPHA;
-
- log_debug("board_temp_max_speed_hz: %d", board_temp_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup board-temp failed");
- return tmp;
- }
-
- spi_board_temp_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_board_temp_remove(struct spi_device *spi)
-{
- spi_board_temp_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_board_temp_driver = {
- .driver = {
- .name = "mts-io-board-temp",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_board_temp_probe,
- .remove = mts_spi_board_temp_remove,
-};
+/* currently not supported
+#include "mtcdp.c"
+#include "mt100eocg.c"
+*/
static int mts_dc_eeprom_load(void)
{
@@ -3688,6 +715,7 @@ static int __init mts_io_init(void)
}
}
+ /* ADC Setup */
#ifdef CONFIG_SOC_AT91SAM9X5
adc_base = ioremap(AT91SAM9X5_BASE_ADC, SZ_16K);
#else
@@ -3724,9 +752,9 @@ static int __init mts_io_init(void)
}
}
- // No blink_callback for MT100EOCG
+ // No reset_callback for MT100EOCG
if ( mts_product_id != MT100EOCG_0_0 ) {
- blink_callback(NULL);
+ reset_callback(NULL);
}
return 0;
@@ -3766,7 +794,7 @@ error1:
static void __exit mts_io_exit(void)
{
if ( mts_product_id != MT100EOCG_0_0 ) {
- cancel_delayed_work_sync(&blink_work);
+ cancel_delayed_work_sync(&reset_work);
}
iounmap(adc_base);
diff --git a/io-module/mts_io.h b/io-module/mts_io.h
index ad82b2a..0842f25 100644
--- a/io-module/mts_io.h
+++ b/io-module/mts_io.h
@@ -4,6 +4,25 @@
#include "mts_eeprom.h"
#include <linux/gpio.h>
+#define DEBUG 0
+
+#define __log(level, name, format, args...) \
+ printk(level "[" name "] " DRIVER_NAME ":%s:%d: " format "\n" , \
+ __func__ , __LINE__ , ## args)
+
+#define log_emerg(format, args...) __log(KERN_EMERG, "EMERG", format , ## args)
+#define log_alert(format, args...) __log(KERN_ALERT, "ALERT", format , ## args)
+#define log_crit(format, args...) __log(KERN_CRIT, "CRIT", format , ## args)
+#define log_error(format, args...) __log(KERN_ERR, "ERROR", format , ## args)
+#define log_warning(format, args...) __log(KERN_WARNING, "WARNING", format , ## args)
+#define log_notice(format, args...) __log(KERN_NOTICE, "NOTICE", format , ## args)
+#define log_info(format, args...) __log(KERN_INFO, "INFO", format , ## args)
+#if DEBUG
+# define log_debug(format, args...) __log(KERN_DEBUG, "DEBUG", format , ## args)
+#else
+# define log_debug(format, args...) do {} while (0)
+#endif
+
#define MTS_ATTR_MODE_RW S_IWUSR | S_IRUGO
#define MTS_ATTR_MODE_RO S_IRUGO
diff --git a/io-module/spi.c b/io-module/spi.c
new file mode 100644
index 0000000..2da3f05
--- /dev/null
+++ b/io-module/spi.c
@@ -0,0 +1,767 @@
+/* SPI devices, functions, and attributes */
+
+static int ADT7302_to_celsius(int value)
+{
+ if (value & 0x2000) {
+ value = value - 16384;
+ }
+
+ value = value / 32 + 1 * ((value % 32) >= 16);
+
+ return value;
+}
+
+/* SPI Devices */
+static struct spi_device *spi_sout_dev;
+static u8 spi_sout_value;
+static DEFINE_MUTEX(spi_sout_mutex);
+static unsigned int sout_max_speed_hz = 1 * 1000 * 1000;
+module_param(sout_max_speed_hz, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ sout_max_speed_hz,
+ "Maximum clock rate to be used with this device (default: 1 MHz)"
+);
+
+static struct spi_device *spi_dout_dev;
+static u8 spi_dout_value;
+static DEFINE_MUTEX(spi_dout_mutex);
+static unsigned int dout_max_speed_hz = 1 * 1000 * 1000;
+module_param(dout_max_speed_hz, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ dout_max_speed_hz,
+ "Maximum clock rate to be used with this device (default: 1 MHz)"
+);
+
+static struct spi_device *spi_din_dev;
+static unsigned int din_max_speed_hz = 1 * 1000 * 1000;
+module_param(din_max_speed_hz, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ din_max_speed_hz,
+ "Maximum clock rate to be used with this device (default: 1 MHz)"
+);
+
+static struct spi_device *spi_dc_dout_dev;
+static u8 spi_dc_dout_value;
+static DEFINE_MUTEX(spi_dc_dout_mutex);
+static unsigned int dc_dout_max_speed_hz = 1 * 1000 * 1000;
+module_param(dc_dout_max_speed_hz, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ dc_dout_max_speed_hz,
+ "Maximum clock rate to be used with this device (default: 1 MHz)"
+);
+
+static struct spi_device *spi_dc_din_dev;
+static unsigned int dc_din_max_speed_hz = 1 * 1000 * 1000;
+module_param(dc_din_max_speed_hz, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ dc_din_max_speed_hz,
+ "Maximum clock rate to be used with this device (default: 1 MHz)"
+);
+
+static struct spi_device *spi_dc_adc_dev;
+static unsigned int dc_adc_max_speed_hz = 20 * 1000 * 1000;
+module_param(dc_adc_max_speed_hz, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ dc_adc_max_speed_hz,
+ "Maximum clock rate to be used with this device (default: 20 MHz)"
+);
+
+static struct spi_device *spi_board_temp_dev;
+static unsigned int board_temp_max_speed_hz = 1 * 1000 * 1000;
+module_param(board_temp_max_speed_hz, uint, S_IRUGO);
+MODULE_PARM_DESC(
+ board_temp_max_speed_hz,
+ "Maximum clock rate to be used with this device (default: 1 MHz)"
+);
+
+/* Generic SPI functions */
+static inline int spi_writen(struct spi_device *spi, const u8 *buf, size_t len)
+{
+ int tmp;
+ u8 *tx;
+
+ tx = kmalloc(len, GFP_KERNEL);
+ if (!tx) {
+ return -ENOMEM;
+ }
+
+ memcpy(tx, buf, len);
+ tmp = spi_write(spi, tx, len);
+
+ kfree(tx);
+
+ return tmp;
+}
+
+static inline int spi_readn(struct spi_device *spi, u8 *buf, size_t len)
+{
+ int tmp;
+ u8 *rx;
+
+ rx = kmalloc(len, GFP_KERNEL);
+ if (!rx) {
+ return -ENOMEM;
+ }
+
+ tmp = spi_read(spi, rx, len);
+ memcpy(buf, rx, len);
+
+ kfree(rx);
+
+ return tmp;
+}
+
+/* ----------------------------------------------------------------------------
+ *
+ * SPI-based attribute show/store functions
+ *
+ * ----------------------------------------------------------------------------
+*/
+
+#define SOUT_LED_CD_BIT BIT(0)
+#define SOUT_EXTSERIAL_RI_BIT BIT(1)
+#define SOUT_EXTSERIAL_DSR_BIT BIT(2)
+#define SOUT_LED_DTR BIT(3)
+#define SOUT_LED_SIG1_BIT BIT(4)
+#define SOUT_LED_SIG2_BIT BIT(5)
+#define SOUT_LED_SIG3_BIT BIT(6)
+#define SOUT_EXTSERIAL_DCD_BIT BIT(7)
+
+static ssize_t mts_attr_store_sout(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ u8 bit;
+
+ if (!spi_sout_dev) {
+ log_notice("sout device not present");
+ return -ENODEV;
+ }
+
+ if (!strcmp(attr->attr.name, "extserial-ri")) {
+ bit = SOUT_EXTSERIAL_RI_BIT;
+ } else if (!strcmp(attr->attr.name, "extserial-dsr")) {
+ bit = SOUT_EXTSERIAL_DSR_BIT;
+ } else if (!strcmp(attr->attr.name, "extserial-dcd")) {
+ bit = SOUT_EXTSERIAL_DCD_BIT;
+ } else if (!strcmp(attr->attr.name, "led-cd") ||
+ !strcmp(attr->attr.name, "led-sdk-b")) {
+ bit = SOUT_LED_CD_BIT;
+ } else if (!strcmp(attr->attr.name, "led-dtr") ||
+ !strcmp(attr->attr.name, "led-sdk-f")) {
+ bit = SOUT_LED_DTR;
+ } else if (!strcmp(attr->attr.name, "led-sig1") ||
+ !strcmp(attr->attr.name, "led-sdk-c")) {
+ bit = SOUT_LED_SIG1_BIT;
+ } else if (!strcmp(attr->attr.name, "led-sig2") ||
+ !strcmp(attr->attr.name, "led-sdk-d")) {
+ bit = SOUT_LED_SIG2_BIT;
+ } else if (!strcmp(attr->attr.name, "led-sig3") ||
+ !strcmp(attr->attr.name, "led-sdk-e")) {
+ bit = SOUT_LED_SIG3_BIT;
+ } else {
+ log_notice("sout attr does not exist");
+ return -ENOENT;
+ }
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ log_notice("sout attr invalid argument");
+ return -EINVAL;
+ }
+
+ mutex_lock(&spi_sout_mutex);
+
+ if (value) {
+ spi_sout_value &= ~bit;
+ } else {
+ spi_sout_value |= bit;
+ }
+ spi_writen(spi_sout_dev, &spi_sout_value, 1);
+
+ mutex_unlock(&spi_sout_mutex);
+
+ return count;
+}
+
+static ssize_t mts_attr_show_sout(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int value;
+ u8 bit;
+
+ if (!spi_sout_dev) {
+ log_error("sout device not present");
+ return -ENODEV;
+ }
+
+ if (!strcmp(attr->attr.name, "extserial-ri")) {
+ bit = SOUT_EXTSERIAL_RI_BIT;
+ } else if (!strcmp(attr->attr.name, "extserial-dsr")) {
+ bit = SOUT_EXTSERIAL_DSR_BIT;
+ } else if (!strcmp(attr->attr.name, "extserial-dcd")) {
+ bit = SOUT_EXTSERIAL_DCD_BIT;
+ } else if (!strcmp(attr->attr.name, "led-cd") ||
+ !strcmp(attr->attr.name, "led-sdk-b")) {
+ bit = SOUT_LED_CD_BIT;
+ } else if (!strcmp(attr->attr.name, "led-dtr") ||
+ !strcmp(attr->attr.name, "led-sdk-f")) {
+ bit = SOUT_LED_DTR;
+ } else if (!strcmp(attr->attr.name, "led-sig1") ||
+ !strcmp(attr->attr.name, "led-sdk-c")) {
+ bit = SOUT_LED_SIG1_BIT;
+ } else if (!strcmp(attr->attr.name, "led-sig2") ||
+ !strcmp(attr->attr.name, "led-sdk-d")) {
+ bit = SOUT_LED_SIG2_BIT;
+ } else if (!strcmp(attr->attr.name, "led-sig3") ||
+ !strcmp(attr->attr.name, "led-sdk-e")) {
+ bit = SOUT_LED_SIG3_BIT;
+ } else {
+ log_notice("sout attr does not exist");
+ return -ENOENT;
+ }
+
+ mutex_lock(&spi_sout_mutex);
+
+ value = spi_sout_value & bit ? 0 : 1;
+
+ mutex_unlock(&spi_sout_mutex);
+
+ return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t mts_attr_store_dout(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ u8 bit;
+
+ if (!spi_dout_dev) {
+ log_notice("dout device not present");
+ return -ENODEV;
+ }
+
+ if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) {
+ bit = BIT(0);
+ } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) {
+ bit = BIT(1);
+ } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) {
+ bit = BIT(2);
+ } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) {
+ bit = BIT(3);
+ } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) {
+ bit = BIT(4);
+ } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) {
+ bit = BIT(5);
+ } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) {
+ bit = BIT(6);
+ } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) {
+ bit = BIT(7);
+ } else {
+ log_notice("dout attr does not exist");
+ return -ENOENT;
+ }
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ log_notice("dout attr invalid argument");
+ return -EINVAL;
+ }
+
+ mutex_lock(&spi_dout_mutex);
+
+ if (value) {
+ spi_dout_value &= ~bit;
+ } else {
+ spi_dout_value |= bit;
+ }
+
+ spi_writen(spi_dout_dev, &spi_dout_value, 1);
+
+ mutex_unlock(&spi_dout_mutex);
+
+ return count;
+}
+
+static ssize_t mts_attr_show_dout(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int value;
+ u8 bit;
+
+ if (!spi_dout_dev) {
+ log_error("dout device not present");
+ return -ENODEV;
+ }
+
+ if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) {
+ bit = BIT(0);
+ } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) {
+ bit = BIT(1);
+ } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) {
+ bit = BIT(2);
+ } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) {
+ bit = BIT(3);
+ } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) {
+ bit = BIT(4);
+ } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) {
+ bit = BIT(5);
+ } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) {
+ bit = BIT(6);
+ } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) {
+ bit = BIT(7);
+ } else {
+ log_notice("dout attr does not exist");
+ return -ENOENT;
+ }
+
+ mutex_lock(&spi_dout_mutex);
+
+ value = spi_dout_value & bit ? 0 : 1;
+
+ mutex_unlock(&spi_dout_mutex);
+
+ return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t mts_attr_show_din(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int tmp;
+ u8 bit;
+ u8 byte;
+
+ if (!spi_din_dev) {
+ log_error("din device not present");
+ return -ENODEV;
+ }
+
+ if ((!strcmp(attr->attr.name, "din0")) || (!strcmp(attr->attr.name, "gpi5"))) {
+ bit = BIT(0);
+ } else if ((!strcmp(attr->attr.name, "din1")) || (!strcmp(attr->attr.name, "gpi6"))) {
+ bit = BIT(1);
+ } else if ((!strcmp(attr->attr.name, "din2")) || (!strcmp(attr->attr.name, "gpi7"))) {
+ bit = BIT(2);
+ } else if ((!strcmp(attr->attr.name, "din3")) || (!strcmp(attr->attr.name, "gpi8"))) {
+ bit = BIT(3);
+ } else if ((!strcmp(attr->attr.name, "din4")) || (!strcmp(attr->attr.name, "gpi9"))) {
+ bit = BIT(4);
+ } else if ((!strcmp(attr->attr.name, "din5")) || (!strcmp(attr->attr.name, "gpi10"))) {
+ bit = BIT(5);
+ } else if (!strcmp(attr->attr.name, "din6")) {
+ bit = BIT(6);
+ } else if (!strcmp(attr->attr.name, "din7")) {
+ bit = BIT(7);
+ } else {
+ log_notice("din attr does not exist");
+ return -ENOENT;
+ }
+
+ tmp = spi_readn(spi_din_dev, &byte, 1);
+ if (tmp) {
+ log_error("spi_read failed %d", tmp);
+ return tmp;
+ }
+
+ tmp = byte & bit ? 1 : 0;
+
+ return sprintf(buf, "%d\n", tmp);
+}
+
+static ssize_t mts_attr_show_board_temperature(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int tmp;
+ u16 temp_raw;
+
+ if (!spi_board_temp_dev) {
+ log_notice("spi_board_temp device not present");
+ return -ENODEV;
+ }
+
+ tmp = spi_readn(spi_board_temp_dev, (u8 *) buf, 2);
+ if (tmp) {
+ log_error("spi_readn failed %d", tmp);
+ return tmp;
+ }
+ temp_raw = ((u8 *) buf)[0] << 8 | ((u8 *) buf)[1];
+
+ log_debug("temp: 0x%04X", temp_raw);
+
+ return sprintf(buf, "%d\n", ADT7302_to_celsius(temp_raw));
+}
+
+/* ----------------------------------------------------------------------------
+ *
+ * SPI-based attributes
+ *
+ * ----------------------------------------------------------------------------
+*/
+
+static DEVICE_ATTR_RO_MTS(dev_attr_board_temperature, "board-temperature",
+ mts_attr_show_board_temperature);
+
+static DEVICE_ATTR_MTS(dev_attr_extserial_dcd, "extserial-dcd",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_extserial_ri, "extserial-ri",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_extserial_dsr, "extserial-dsr",
+ mts_attr_show_sout, mts_attr_store_sout);
+
+static DEVICE_ATTR_MTS(dev_attr_led_cd, "led-cd",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sdk_b, "led-sdk-b",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sig1, "led-sig1",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sdk_c, "led-sdk-c",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sig2, "led-sig2",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sdk_d, "led-sdk-d",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sig3, "led-sig3",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sdk_e, "led-sdk-e",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_dtr, "led-dtr",
+ mts_attr_show_sout, mts_attr_store_sout);
+static DEVICE_ATTR_MTS(dev_attr_led_sdk_f, "led-sdk-f",
+ mts_attr_show_sout, mts_attr_store_sout);
+
+static DEVICE_ATTR_MTS(dev_attr_dout0, "dout0",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_dout1, "dout1",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_dout2, "dout2",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_dout3, "dout3",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_dout4, "dout4",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_dout5, "dout5",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_dout6, "dout6",
+ mts_attr_show_dout, mts_attr_store_dout);
+static DEVICE_ATTR_MTS(dev_attr_dout7, "dout7",
+ mts_attr_show_dout, mts_attr_store_dout);
+
+static DEVICE_ATTR_RO_MTS(dev_attr_din0, "din0", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_din1, "din1", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_din2, "din2", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_din3, "din3", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_din4, "din4", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_din5, "din5", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_din6, "din6", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_din7, "din7", mts_attr_show_din);
+
+static DEVICE_ATTR_RO_MTS(dev_attr_gpi5, "gpi5", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_gpi6, "gpi6", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_gpi7, "gpi7", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_gpi8, "gpi8", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_gpi9, "gpi9", mts_attr_show_din);
+static DEVICE_ATTR_RO_MTS(dev_attr_gpi10, "gpi10", mts_attr_show_din);
+
+/* SPI driver setup */
+static int mts_spi_sout_probe(struct spi_device *spi)
+{
+ int tmp;
+
+ spi->max_speed_hz = sout_max_speed_hz;
+ spi->mode = 0;
+
+ log_debug("sout_max_speed_hz: %d", sout_max_speed_hz);
+
+ tmp = spi_setup(spi);
+ if (tmp < 0) {
+ log_error("spi_setup sout failed");
+ return tmp;
+ }
+
+ spi_sout_value = 0xFF;
+ spi_writen(spi, &spi_sout_value, 1);
+
+ spi_sout_dev = spi;
+
+ return 0;
+}
+
+static int mts_spi_sout_remove(struct spi_device *spi)
+{
+ spi_sout_dev = NULL;
+
+ return 0;
+}
+
+static struct spi_driver mts_spi_sout_driver = {
+ .driver = {
+ .name = "mts-io-sout",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = mts_spi_sout_probe,
+ .remove = mts_spi_sout_remove,
+};
+
+static int mts_spi_dout_probe(struct spi_device *spi)
+{
+ int tmp;
+
+ if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DOUT)) {
+ log_debug("digital outputs not available");
+ return -ENODEV;
+ }
+
+ spi->max_speed_hz = dout_max_speed_hz;
+ spi->mode = 0;
+
+ log_debug("dout_max_speed_hz: %d", dout_max_speed_hz);
+
+ tmp = spi_setup(spi);
+ if (tmp < 0) {
+ log_error("spi_setup dout failed");
+ return tmp;
+ }
+
+ spi_dout_value = 0x00;
+ spi_writen(spi, &spi_dout_value, 1);
+
+ spi_dout_dev = spi;
+
+ return 0;
+}
+
+static int mts_spi_dout_remove(struct spi_device *spi)
+{
+ spi_dout_dev = NULL;
+
+ return 0;
+}
+
+static struct spi_driver mts_spi_dout_driver = {
+ .driver = {
+ .name = "mts-io-dout",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = mts_spi_dout_probe,
+ .remove = mts_spi_dout_remove,
+};
+
+static int mts_spi_din_probe(struct spi_device *spi)
+{
+ int tmp;
+
+ if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DIN)) {
+ log_debug("digital inputs not available");
+ return -ENODEV;
+ }
+
+ spi->max_speed_hz = din_max_speed_hz;
+ spi->mode = SPI_CPOL;
+
+ log_debug("din_max_speed_hz: %d", din_max_speed_hz);
+
+ tmp = spi_setup(spi);
+ if (tmp < 0) {
+ log_error("spi_setup din failed");
+ return tmp;
+ }
+
+ spi_din_dev = spi;
+
+ return 0;
+}
+
+static int mts_spi_din_remove(struct spi_device *spi)
+{
+ spi_din_dev = NULL;
+
+ return 0;
+}
+
+static struct spi_driver mts_spi_din_driver = {
+ .driver = {
+ .name = "mts-io-din",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = mts_spi_din_probe,
+ .remove = mts_spi_din_remove,
+};
+
+static int mts_spi_dc_dout_probe(struct spi_device *spi)
+{
+ int tmp;
+
+ if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) {
+ log_error("daughter card digital outputs not available");
+ return -ENODEV;
+ }
+
+ spi->max_speed_hz = dc_dout_max_speed_hz;
+ spi->mode = 0;
+
+ log_debug("dc_dout_max_speed_hz: %d", dc_dout_max_speed_hz);
+
+ tmp = spi_setup(spi);
+ if (tmp < 0) {
+ log_error("spi_setup dc dout failed");
+ return tmp;
+ }
+
+ spi_dc_dout_value = 0x00;
+ spi_writen(spi, &spi_dc_dout_value, 1);
+
+ spi_dc_dout_dev = spi;
+
+ return 0;
+}
+
+static int mts_spi_dc_dout_remove(struct spi_device *spi)
+{
+ spi_dc_dout_dev = NULL;
+
+ return 0;
+}
+
+static struct spi_driver mts_spi_dc_dout_driver = {
+ .driver = {
+ .name = "mts-io-dc-dout",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = mts_spi_dc_dout_probe,
+ .remove = mts_spi_dc_dout_remove,
+};
+
+static int mts_spi_dc_din_probe(struct spi_device *spi)
+{
+ int tmp;
+
+ if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) {
+ log_error("daughter card digital inputs not available");
+ return -ENODEV;
+ }
+
+ spi->max_speed_hz = dc_din_max_speed_hz;
+ spi->mode = SPI_CPOL;
+
+ log_debug("dc_din_max_speed_hz: %d", dc_din_max_speed_hz);
+
+ tmp = spi_setup(spi);
+ if (tmp < 0) {
+ log_error("spi_setup daughter card din failed");
+ return tmp;
+ }
+
+ spi_dc_din_dev = spi;
+
+ return 0;
+}
+
+static int mts_spi_dc_din_remove(struct spi_device *spi)
+{
+ spi_dc_din_dev = NULL;
+
+ return 0;
+}
+
+static struct spi_driver mts_spi_dc_din_driver = {
+ .driver = {
+ .name = "mts-io-dc-din",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = mts_spi_dc_din_probe,
+ .remove = mts_spi_dc_din_remove,
+};
+
+static int mts_spi_dc_adc_probe(struct spi_device *spi)
+{
+ int tmp;
+
+ if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) {
+ log_error("daughter card analog to digital not available");
+ return -ENODEV;
+ }
+
+ spi->max_speed_hz = dc_adc_max_speed_hz;
+ spi->mode = 0;
+
+ log_debug("dc_adc_max_speed_hz: %d", dc_adc_max_speed_hz);
+ log_debug("dc_adc_mode: %d", spi->mode);
+
+ tmp = spi_setup(spi);
+ if (tmp < 0) {
+ log_error("spi_setup daughter card adc failed");
+ return tmp;
+ }
+
+ spi_dc_adc_dev = spi;
+
+ return 0;
+}
+
+static int mts_spi_dc_adc_remove(struct spi_device *spi)
+{
+ spi_dc_adc_dev = NULL;
+
+ return 0;
+}
+
+static struct spi_driver mts_spi_dc_adc_driver = {
+ .driver = {
+ .name = "mts-io-dc-adc",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = mts_spi_dc_adc_probe,
+ .remove = mts_spi_dc_adc_remove,
+};
+
+static int mts_spi_board_temp_probe(struct spi_device *spi)
+{
+ int tmp;
+
+ spi->max_speed_hz = board_temp_max_speed_hz;
+ spi->mode = SPI_CPOL | SPI_CPHA;
+
+ log_debug("board_temp_max_speed_hz: %d", board_temp_max_speed_hz);
+
+ tmp = spi_setup(spi);
+ if (tmp < 0) {
+ log_error("spi_setup board-temp failed");
+ return tmp;
+ }
+
+ spi_board_temp_dev = spi;
+
+ return 0;
+}
+
+static int mts_spi_board_temp_remove(struct spi_device *spi)
+{
+ spi_board_temp_dev = NULL;
+
+ return 0;
+}
+
+static struct spi_driver mts_spi_board_temp_driver = {
+ .driver = {
+ .name = "mts-io-board-temp",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = mts_spi_board_temp_probe,
+ .remove = mts_spi_board_temp_remove,
+};
diff --git a/io-module/telit_radio.c b/io-module/telit_radio.c
new file mode 100644
index 0000000..fbac4fa
--- /dev/null
+++ b/io-module/telit_radio.c
@@ -0,0 +1,219 @@
+
+static int radio_off_telit(void)
+{
+ int value, ret;
+ struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON");
+ struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF");
+ struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST");
+
+ if (!onoff_pin || !pwrmon_pin || !rst_pin) {
+ return -ENODEV;
+ }
+
+ value = gpio_get_value(pwrmon_pin->pin.gpio);
+ if(value == 0) {
+ log_error("radio is already off");
+ return -EINVAL;
+ }
+
+ // drive on/off pin low for at least 3 sec
+ log_info("shutting down radio");
+ ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ msleep(3500);
+
+ // set on/off pin high
+ ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ // wait for radio to power off
+ msleep(5000);
+
+ // check that power is low
+ value = gpio_get_value(pwrmon_pin->pin.gpio);
+ if(value != 0) {
+ log_warning("radio is still on. performing radio reset.");
+ //Perform Hard Reset
+ ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ msleep(500);
+
+ // set pin high
+ ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+ } else {
+ log_info("radio has been shut down");
+ }
+
+ return ret;
+}
+
+static int radio_on_telit(void)
+{
+ int value, ret;
+ struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON");
+ struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF");
+ struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST");
+
+ if (!onoff_pin || !pwrmon_pin || !rst_pin) {
+ return -ENODEV;
+ }
+
+ value = gpio_get_value(pwrmon_pin->pin.gpio);
+ if(value != 0) {
+ log_error("radio is already on");
+ return -EINVAL;
+ }
+
+ // drive on/off pin low for at least 5 sec
+ log_info("turning on radio");
+ ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ msleep(5500);
+
+ // set on/off pin high
+ ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ msleep(200);
+
+ // check that power is high
+ value = gpio_get_value(pwrmon_pin->pin.gpio);
+ if(value == 0) {
+ log_warning("radio is still off. performing radio reset");
+ //Perform Hard Reset
+ ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ msleep(500);
+
+ // set pin high
+ ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+ } else {
+ log_info("radio has been turned on");
+ }
+
+ return ret;
+}
+
+static ssize_t mts_attr_store_radio_power_telit(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ int err;
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+ if (value == 0) {
+ mutex_lock(&mts_io_mutex);
+ err = radio_off_telit();
+ mutex_unlock(&mts_io_mutex);
+ } else {
+ mutex_lock(&mts_io_mutex);
+ err = radio_on_telit();
+ mutex_unlock(&mts_io_mutex);
+ }
+
+ if (err) {
+ return err;
+ }
+
+ return count;
+}
+
+static int radio_reset_telit(void)
+{
+ int ret;
+ struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST");
+ struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF");
+
+ if (!rst_pin || !onoff_pin) {
+ return -ENODEV;
+ }
+
+ // drive reset pin low for 500ms
+ ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ msleep(500);
+
+ // set pin high
+ ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ // wait for 2 sec before toggling on/off pin
+ msleep(2000);
+
+ // drive on/off pin low for 6 sec
+ ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ msleep(6000);
+
+ // set on/off pin high
+ ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP);
+ if (ret) {
+ return ret;
+ }
+
+ return ret;
+}
+
+static ssize_t mts_attr_store_radio_reset_telit(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ int err;
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+ if (value != 0) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ err = radio_reset_telit();
+
+ mutex_unlock(&mts_io_mutex);
+
+ if (err) {
+ return err;
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR_MTS(dev_attr_radio_power_telit, "radio-power",
+ mts_attr_show_gpio_pin, mts_attr_store_radio_power_telit);
+
+static DEVICE_ATTR_MTS(dev_attr_radio_reset_telit, "radio-reset",
+ mts_attr_show_gpio_pin, mts_attr_store_radio_reset_telit);