From e56a17a78f778d92e7d60717893fe9e81b65869a Mon Sep 17 00:00:00 2001
From: Jesse Gilles <jgilles@multitech.com>
Date: Wed, 4 Jan 2012 16:51:48 -0600
Subject: add daughter card reset (ndc-reset)

---
 io-module/mts_io.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

(limited to 'io-module/mts_io.c')

diff --git a/io-module/mts_io.c b/io-module/mts_io.c
index fe7fcaf..c62b534 100644
--- a/io-module/mts_io.c
+++ b/io-module/mts_io.c
@@ -260,6 +260,13 @@ static struct gpio_pin gpio_pins_mtcdp_1_0[] = {
 		.use_pullup = 0,
 	},
 #endif
+	{
+		.name = "NDC_RESET",
+		.pin = AT91_PIN_PB21,
+		.direction = GPIO_DIR_OUTPUT,
+		.output_value = 1,
+		.use_pullup = 0,
+	},
 	{ },
 };
 
@@ -604,6 +611,27 @@ static int radio_reset(void)
 	return ret;
 }
 
+static int ndc_reset(void)
+{
+	int ret;
+	struct gpio_pin *pin = gpio_pin_by_name("NDC_RESET");
+
+	if (!pin) {
+		return -ENODEV;
+	}
+
+	ret = at91_set_gpio_value(pin->pin, 0);
+	if (ret) {
+		return ret;
+	}
+
+	mdelay(1);
+
+	ret = at91_set_gpio_value(pin->pin, 1);
+
+	return ret;
+}
+
 static int ADT7302_to_celsius(int value)
 {
 	if (value & 0x2000) {
@@ -692,6 +720,65 @@ static struct device_attribute dev_attr_radio_reset = {
 	.store = mts_attr_store_radio_reset,
 };
 
+static ssize_t mts_attr_show_ndc_reset(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	int value;
+	struct gpio_pin *pin = gpio_pin_by_name("NDC_RESET");
+
+	if (!pin) {
+		return -ENODEV;
+	}
+
+	mutex_lock(&mts_io_mutex);
+
+	value = at91_get_gpio_value(pin->pin);
+
+	mutex_unlock(&mts_io_mutex);
+
+	if (value < 0) {
+		return value;
+	}
+
+	return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t mts_attr_store_ndc_reset(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 = ndc_reset();
+
+	mutex_unlock(&mts_io_mutex);
+
+	if (err) {
+		return err;
+	}
+
+	return count;
+}
+
+static struct device_attribute dev_attr_ndc_reset = {
+	.attr = {
+		.name = "ndc-reset",
+		.mode = MTS_ATTR_MODE_RW,
+	},
+	.show = mts_attr_show_ndc_reset,
+	.store = mts_attr_store_ndc_reset,
+};
+
 static ssize_t mts_attr_show_eth0_enabled(struct device *dev,
 			struct device_attribute *attr,
 			char *buf)
@@ -2202,6 +2289,7 @@ static struct attribute *platform_attributes[] = {
 	&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,
-- 
cgit v1.2.3