diff options
-rw-r--r-- | io-module/mts_io.c | 565 | ||||
-rw-r--r-- | io-module/mts_io.h | 2 |
2 files changed, 527 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"); diff --git a/io-module/mts_io.h b/io-module/mts_io.h index e9282cc..2ae88bc 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -12,10 +12,12 @@ #define VENDOR_ID_MULTITECH "Multi-Tech Systems" #define PRODUCT_ID_MTCDP_E1_DK "MTCDP-E1-DK" +#define PRODUCT_ID_MT100ECDP "MT100ECDP" #define HW_VERSION_MTCBA2_2_0 "MTCBA2-2.0" #define HW_VERSION_MTCDP_0_0 "MTCDP-0.0" #define HW_VERSION_MTCDP_1_0 "MTCDP-1.0" +#define HW_VERSION_MT100ECDP_0_0 "MT100ECDP-0.0" #define DEVICE_CAPA_INDEX(c) (((c) & 0xFF) >> 3) #define DEVICE_CAPA_MASK(c) BIT((c) & 0x07) |