summaryrefslogtreecommitdiff
path: root/io-module/mts_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'io-module/mts_io.c')
-rw-r--r--io-module/mts_io.c565
1 files changed, 525 insertions, 40 deletions
diff --git a/io-module/mts_io.c b/io-module/mts_io.c
index a921fdd..4697209 100644
--- a/io-module/mts_io.c
+++ b/io-module/mts_io.c
@@ -41,7 +41,7 @@
#include "mts_io.h"
-#define DRIVER_VERSION "v0.4.1"
+#define DRIVER_VERSION "v0.4.2"
#define DRIVER_AUTHOR "James Maki <jmaki@multitech.com>"
#define DRIVER_DESC "MTCDP IO Controller"
#define DRIVER_NAME "mts-io"
@@ -260,6 +260,92 @@ static struct gpio_pin gpio_pins_mtcdp_1_0[] = {
{ },
};
+static struct gpio_pin gpio_pins_mt100ecdp_0_0[] = {
+ {
+ .name = "ENIO",
+ .pin = AT91_PIN_PC15,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "ETH0_ENABLED",
+ .pin = AT91_PIN_PB31,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "RADIO_RESET",
+ .pin = AT91_PIN_PB30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "DEVICE_RESET",
+ .pin = AT91_PIN_PA22,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .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,
+ },
+ {
+ .name = "LED2",
+ .pin = AT91_PIN_PA30,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "RSERSRC",
+ .pin = AT91_PIN_PC7,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "TXD1",
+ .pin = AT91_PIN_PB17,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "DTR1",
+ .pin = AT91_PIN_PB18,
+ .direction = GPIO_DIR_INPUT,
+ .output_value = 0,
+ .use_pullup = 0,
+ },
+ {
+ .name = "GPIO11",
+ .pin = AT91_PIN_PB19,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ {
+ .name = "GPIO12",
+ .pin = AT91_PIN_PB20,
+ .direction = GPIO_DIR_OUTPUT,
+ .output_value = 1,
+ .use_pullup = 0,
+ },
+ { },
+};
+
+
struct gpio_pin *gpio_pin_by_name(const char *name) {
struct gpio_pin *pin;
@@ -293,6 +379,8 @@ static int mts_id_eeprom_load(void)
DEVICE_CAPA_SET(id_eeprom.capa, CAPA_GPS);
gpio_pins = gpio_pins_mtcdp_0_0;
+ } else if (!strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ gpio_pins = gpio_pins_mt100ecdp_0_0;
} else {
gpio_pins = gpio_pins_mtcdp_1_0;
}
@@ -882,21 +970,21 @@ static ssize_t mts_attr_store_dout(struct device *dev,
return -ENODEV;
}
- if (!strcmp(attr->attr.name, "dout0")) {
+ if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) {
bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "dout1")) {
+ } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) {
bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "dout2")) {
+ } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) {
bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "dout3")) {
+ } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) {
bit = BIT(3);
- } else if (!strcmp(attr->attr.name, "dout4")) {
+ } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) {
bit = BIT(4);
- } else if (!strcmp(attr->attr.name, "dout5")) {
+ } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) {
bit = BIT(5);
- } else if (!strcmp(attr->attr.name, "dout6")) {
+ } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) {
bit = BIT(6);
- } else if (!strcmp(attr->attr.name, "dout7")) {
+ } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) {
bit = BIT(7);
} else {
log_notice("dout attr does not exist");
@@ -934,21 +1022,21 @@ static ssize_t mts_attr_show_dout(struct device *dev,
return -ENODEV;
}
- if (!strcmp(attr->attr.name, "dout0")) {
+ if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) {
bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "dout1")) {
+ } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) {
bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "dout2")) {
+ } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) {
bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "dout3")) {
+ } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) {
bit = BIT(3);
- } else if (!strcmp(attr->attr.name, "dout4")) {
+ } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) {
bit = BIT(4);
- } else if (!strcmp(attr->attr.name, "dout5")) {
+ } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) {
bit = BIT(5);
- } else if (!strcmp(attr->attr.name, "dout6")) {
+ } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) {
bit = BIT(6);
- } else if (!strcmp(attr->attr.name, "dout7")) {
+ } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) {
bit = BIT(7);
} else {
log_notice("dout attr does not exist");
@@ -1049,17 +1137,17 @@ static ssize_t mts_attr_show_din(struct device *dev,
return -ENODEV;
}
- if (!strcmp(attr->attr.name, "din0")) {
+ if ((!strcmp(attr->attr.name, "din0")) || (!strcmp(attr->attr.name, "gpi5"))) {
bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "din1")) {
+ } else if ((!strcmp(attr->attr.name, "din1")) || (!strcmp(attr->attr.name, "gpi6"))) {
bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "din2")) {
+ } else if ((!strcmp(attr->attr.name, "din2")) || (!strcmp(attr->attr.name, "gpi7"))) {
bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "din3")) {
+ } else if ((!strcmp(attr->attr.name, "din3")) || (!strcmp(attr->attr.name, "gpi8"))) {
bit = BIT(3);
- } else if (!strcmp(attr->attr.name, "din4")) {
+ } else if ((!strcmp(attr->attr.name, "din4")) || (!strcmp(attr->attr.name, "gpi9"))) {
bit = BIT(4);
- } else if (!strcmp(attr->attr.name, "din5")) {
+ } 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);
@@ -1255,7 +1343,14 @@ static ssize_t mts_attr_show_led_ls(struct device *dev,
char *buf)
{
int value;
- struct gpio_pin *pin = gpio_pin_by_name("LS_LED");
+ struct gpio_pin *pin;
+
+ if (!strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ pin = gpio_pin_by_name("LED3");
+ }
+ else {
+ pin = gpio_pin_by_name("LS_LED");
+ }
if (!pin) {
return -ENODEV;
@@ -1279,7 +1374,14 @@ static ssize_t mts_attr_store_led_ls(struct device *dev,
{
int value;
int err;
- struct gpio_pin *pin = gpio_pin_by_name("LS_LED");
+ struct gpio_pin *pin;
+
+ if (!strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ pin = gpio_pin_by_name("LED3");
+ }
+ else {
+ pin = gpio_pin_by_name("LS_LED");
+ }
if (!pin) {
return -ENODEV;
@@ -1587,6 +1689,357 @@ static struct device_attribute dev_attr_usbh2_ps_enabled = {
};
#endif
+
+static ssize_t mts_attr_show_led2(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int value;
+ struct gpio_pin *pin = gpio_pin_by_name("LED2");
+
+ 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_led2(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ int err;
+ struct gpio_pin *pin = gpio_pin_by_name("LED2");
+
+ if (!pin) {
+ return -ENODEV;
+ }
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ err = at91_set_gpio_value(pin->pin, !value);
+
+ mutex_unlock(&mts_io_mutex);
+
+ if (err) {
+ return err;
+ }
+
+ return count;
+}
+
+static ssize_t mts_attr_show_gpio11(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int value;
+ struct gpio_pin *pin = gpio_pin_by_name("GPIO11");
+
+ 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_gpio11(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ int err;
+ struct gpio_pin *pin = gpio_pin_by_name("GPIO11");
+
+ if (!pin) {
+ return -ENODEV;
+ }
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ err = at91_set_gpio_value(pin->pin, !value);
+
+ mutex_unlock(&mts_io_mutex);
+
+ return count;
+}
+
+static ssize_t mts_attr_show_gpio12(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int value;
+ struct gpio_pin *pin = gpio_pin_by_name("GPIO12");
+
+ 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_gpio12(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ int err;
+ struct gpio_pin *pin = gpio_pin_by_name("GPIO12");
+
+ if (!pin) {
+ return -ENODEV;
+ }
+
+ if (sscanf(buf, "%i", &value) != 1) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&mts_io_mutex);
+
+ err = at91_set_gpio_value(pin->pin, !value);
+
+ mutex_unlock(&mts_io_mutex);
+
+ if (err) {
+ return err;
+ }
+
+ return count;
+}
+
+static struct device_attribute dev_attr_gpo1 = {
+ .attr = {
+ .name = "gpo1",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_gpo2 = {
+ .attr = {
+ .name = "gpo2",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_gpo3 = {
+ .attr = {
+ .name = "gpo3",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_gpo4 = {
+ .attr = {
+ .name = "gpo4",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_gpi5 = {
+ .attr = {
+ .name = "gpi5",
+ .mode = MTS_ATTR_MODE_RO,
+ },
+ .show = mts_attr_show_din,
+};
+
+static struct device_attribute dev_attr_gpi6 = {
+ .attr = {
+ .name = "gpi6",
+ .mode = MTS_ATTR_MODE_RO,
+ },
+ .show = mts_attr_show_din,
+};
+
+static struct device_attribute dev_attr_gpi7 = {
+ .attr = {
+ .name = "gpi7",
+ .mode = MTS_ATTR_MODE_RO,
+ },
+ .show = mts_attr_show_din,
+};
+
+static struct device_attribute dev_attr_gpi8 = {
+ .attr = {
+ .name = "gpi8",
+ .mode = MTS_ATTR_MODE_RO,
+ },
+ .show = mts_attr_show_din,
+};
+
+static struct device_attribute dev_attr_gpi9 = {
+ .attr = {
+ .name = "gpi9",
+ .mode = MTS_ATTR_MODE_RO,
+ },
+ .show = mts_attr_show_din,
+};
+
+static struct device_attribute dev_attr_gpi10 = {
+ .attr = {
+ .name = "gpi10",
+ .mode = MTS_ATTR_MODE_RO,
+ },
+ .show = mts_attr_show_din,
+};
+
+static struct device_attribute dev_attr_led1 = {
+ .attr = {
+ .name = "led1",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_led2 = {
+ .attr = {
+ .name = "led2",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_led2,
+ .store = mts_attr_store_led2,
+};
+
+static struct device_attribute dev_attr_led3 = {
+ .attr = {
+ .name = "led3",
+#if LED_LS_CONTROLLABLE
+ .mode = MTS_ATTR_MODE_RW,
+#else
+ .mode = MTS_ATTR_MODE_RO,
+#endif
+ },
+ .show = mts_attr_show_led_ls,
+ .store = mts_attr_store_led_ls,
+};
+
+static struct device_attribute dev_attr_led4 = {
+ .attr = {
+ .name = "led4",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_led5 = {
+ .attr = {
+ .name = "led5",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_led6 = {
+ .attr = {
+ .name = "led6",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_dout,
+ .store = mts_attr_store_dout,
+};
+
+static struct device_attribute dev_attr_gpio11 = {
+ .attr = {
+ .name = "gpio11",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_gpio11,
+ .store = mts_attr_store_gpio11,
+};
+
+static struct device_attribute dev_attr_gpio12 = {
+ .attr = {
+ .name = "gpio12",
+ .mode = MTS_ATTR_MODE_RW,
+ },
+ .show = mts_attr_show_gpio12,
+ .store = mts_attr_store_gpio12,
+};
+
+
+static struct attribute *mt100ecdp_platform_attributes[] = {
+ &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 mt100ecdp_platform_attribute_group = {
+ .attrs = mt100ecdp_platform_attributes
+};
+
+
static struct attribute *platform_attributes[] = {
&dev_attr_reset.attr,
&dev_attr_reset_monitor.attr,
@@ -1842,15 +2295,27 @@ static int __init mts_io_init(void)
goto error2;
}
- ret = sysfs_create_group(&mts_io_platform_device->dev.kobj,
- &platform_attribute_group);
- if (ret) {
- goto error3;
+ if (!strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ ret = sysfs_create_group(&mts_io_platform_device->dev.kobj,
+ &mt100ecdp_platform_attribute_group);
+ if (ret) {
+ goto error3;
+ }
+ }
+ else {
+ ret = sysfs_create_group(&mts_io_platform_device->dev.kobj,
+ &platform_attribute_group);
+ if (ret) {
+ goto error3;
+ }
}
- ret = spi_register_driver(&mts_spi_sout_driver);
- if (ret) {
- goto error4;
+ // No sout driver for MT100ECDP
+ if (strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ ret = spi_register_driver(&mts_spi_sout_driver);
+ if (ret) {
+ goto error4;
+ }
}
ret = spi_register_driver(&mts_spi_board_temp_driver);
@@ -1903,7 +2368,10 @@ static int __init mts_io_init(void)
at91_set_gpio_value(pin->pin, 0);
}
- blink_callback(NULL);
+ // No blinking for MT100ECDP
+ if (strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ blink_callback(NULL);
+ }
return 0;
@@ -1916,10 +2384,18 @@ error7:
error6:
spi_unregister_driver(&mts_spi_dout_driver);
error5:
- spi_unregister_driver(&mts_spi_sout_driver);
+ if (strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ spi_unregister_driver(&mts_spi_sout_driver);
+ }
error4:
- sysfs_remove_group(&mts_io_platform_device->dev.kobj,
- &platform_attribute_group);
+ if (!strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ sysfs_remove_group(&mts_io_platform_device->dev.kobj,
+ &mt100ecdp_platform_attribute_group);
+ }
+ else {
+ sysfs_remove_group(&mts_io_platform_device->dev.kobj,
+ &platform_attribute_group);
+ }
error3:
platform_device_del(mts_io_platform_device);
error2:
@@ -1932,7 +2408,9 @@ error1:
static void __exit mts_io_exit(void)
{
- cancel_delayed_work_sync(&blink_work);
+ if (strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ cancel_delayed_work_sync(&blink_work);
+ }
iounmap(adc_base);
clk_disable(adc_clk);
@@ -1941,10 +2419,17 @@ static void __exit mts_io_exit(void)
spi_unregister_driver(&mts_spi_din_driver);
spi_unregister_driver(&mts_spi_dout_driver);
spi_unregister_driver(&mts_spi_board_temp_driver);
- spi_unregister_driver(&mts_spi_sout_driver);
- sysfs_remove_group(&mts_io_platform_device->dev.kobj,
- &platform_attribute_group);
+ if (!strcmp(id_eeprom.product_id, PRODUCT_ID_MT100ECDP)) {
+ sysfs_remove_group(&mts_io_platform_device->dev.kobj,
+ &mt100ecdp_platform_attribute_group);
+ }
+ else {
+ spi_unregister_driver(&mts_spi_sout_driver);
+
+ sysfs_remove_group(&mts_io_platform_device->dev.kobj,
+ &platform_attribute_group);
+ }
platform_device_unregister(mts_io_platform_device);
log_info("exiting");