diff options
Diffstat (limited to 'io-module/mts_io.c')
-rw-r--r-- | io-module/mts_io.c | 274 |
1 files changed, 210 insertions, 64 deletions
diff --git a/io-module/mts_io.c b/io-module/mts_io.c index e26013d..b63a756 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -71,8 +71,8 @@ static struct mts_ap_eeprom_layout ap1_eeprom; static struct mts_ap_eeprom_layout ap2_eeprom; bool accessory_card_capable = false; -bool has_accessory_card_port_1 = false; -bool has_accessory_card_port_2 = false; +bool have_accessory_card_slot_1 = false; +bool have_accessory_card_slot_2 = false; static uint8_t mts_product_id; static uint8_t mts_ap1_product_id; @@ -405,7 +405,7 @@ static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth", mts_attr_show_product_info); /* include per-device pins and attributes */ -#include "mtr2.c" +//#include "mtr2.c" #include "mtr.c" #include "mtr2d2.c" @@ -414,10 +414,70 @@ static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth", #include "mt100eocg.c" */ -/* reorg this function to load and log both accessory card EEPROMs - * should be able to handle either or both slots being empty - */ -static int mts_ap_eeprom_load(void) +static bool add_accessory_card_attributes(int slot) +{ + size_t device_attrs_size; + size_t card_attrs_size; + size_t attrs_index; + size_t i; + + struct attribute **device_attrs; + struct attribute **card_attrs; + + switch (mts_product_id) { + case MTR2D2_0_0: + device_attrs_size = mtr2d2_platform_attributes_size; + device_attrs = mtr2d2_platform_attributes; + break; + default: + log_error("accessory cards aren't supported for platform %s", id_eeprom.hw_version); + return false; + } + + if (slot == 1) { + switch (mts_ap1_product_id) { + case MTDC_GPIOB_0_0: + card_attrs_size = ap1_gpio_attributes_size; + card_attrs = ap1_gpio_attributes; + break; + default: + log_error("accessory card %s isn't supported", ap1_eeprom.hw_version); + return false; + } + } else if (slot == 2) { + switch (mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + card_attrs_size = ap2_gpio_attributes_size; + card_attrs = ap2_gpio_attributes; + break; + default: + log_error("accessory card %s isn't supported", ap2_eeprom.hw_version); + return false; + } + } else { + log_error("%d is an invalid slot value", slot); + return false; + } + + for (attrs_index = 0; attrs_index < device_attrs_size; attrs_index++) { + if (! device_attrs[attrs_index]) { + break; + } + } + + if (device_attrs_size < attrs_index + card_attrs_size) { + log_error("not enough room for accessory card attributes!"); + return false; + } + + for (i = 0; i < card_attrs_size; i++) { + device_attrs[attrs_index + i] = card_attrs[i]; + } + + return true; +} + +static bool mts_ap_eeprom_load(void) { // Accessory Card Slot 1 memcpy(&ap1_eeprom, mts_ap1_eeprom, sizeof(mts_ap1_eeprom)); @@ -427,7 +487,7 @@ static int mts_ap_eeprom_load(void) } else if (mts_ap1_eeprom[0] == 0x00) { log_info("no accessory card inserted in slot 1"); } else { - has_accessory_card_port_1 = true; + have_accessory_card_slot_1 = true; log_info("accessory card 1 vendor-id: %.32s", ap1_eeprom.vendor_id); log_info("accessory card 1 product-id: %.32s", ap1_eeprom.product_id); @@ -452,7 +512,7 @@ static int mts_ap_eeprom_load(void) } else if (mts_ap2_eeprom[0] == 0x00) { log_info("no accessory card inserted in slot 2"); } else { - has_accessory_card_port_2 = true; + have_accessory_card_slot_2 = true; log_info("accessory card 2 vendor-id: %.32s", ap2_eeprom.vendor_id); log_info("accessory card 2 product-id: %.32s", ap2_eeprom.product_id); @@ -469,7 +529,8 @@ static int mts_ap_eeprom_load(void) } } - return 0; + // if either slot has a valid card, return true + return (have_accessory_card_slot_1 || have_accessory_card_slot_2); } static int mts_id_eeprom_load(void) @@ -507,7 +568,6 @@ static int mts_id_eeprom_load(void) has_spi_dout = 1; has_spi_temp = 1; log_info("detected board %s", HW_VERSION_MT100EOCG_0_0); - */ } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTR2_0_0, strlen(HW_VERSION_MTR2_0_0)) == 0) { attr_group = &mtr2_platform_attribute_group; gpio_pins = gpio_pins_mtr2_0_0; @@ -518,6 +578,7 @@ static int mts_id_eeprom_load(void) has_spi_dout = 0; has_spi_temp = 1; log_info("detected board %s", HW_VERSION_MTR2_0_0); + */ } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTR_0_0, strlen(HW_VERSION_MTR_0_0)) == 0) { attr_group = &mtr_platform_attribute_group; gpio_pins = gpio_pins_mtr_0_0; @@ -536,6 +597,7 @@ static int mts_id_eeprom_load(void) has_spi_dout = 0; has_spi_temp = 0; log_info("detected board %s", HW_VERSION_MTR_0_1); + /* } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTOCGD2_0_0, strlen(HW_VERSION_MTOCGD2_0_0)) == 0) { attr_group = &mtr2_platform_attribute_group; gpio_pins = gpio_pins_mtr2_0_0; @@ -546,6 +608,7 @@ static int mts_id_eeprom_load(void) has_spi_dout = 0; has_spi_temp = 1; log_info("detected board %s", HW_VERSION_MTOCGD2_0_0); + */ } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTOCGD_0_0, strlen(HW_VERSION_MTOCGD_0_0)) == 0) { attr_group = &mtr_platform_attribute_group; gpio_pins = gpio_pins_mtr_0_0; @@ -568,6 +631,7 @@ static int mts_id_eeprom_load(void) attr_group = &mtr2d2_platform_attribute_group; gpio_pins = gpio_pins_mtr2d2_0_0; mts_product_id = MTR2D2_0_0; + accessory_card_capable = true; has_spi_sout = 0; has_spi_din = 0; has_spi_dout = 0; @@ -631,6 +695,8 @@ static int __init mts_io_init(void) { struct gpio_pin *pin; int ret; + size_t device_attributes_size; + size_t card_attributes_size; log_info("init: " DRIVER_VERSION); @@ -641,54 +707,92 @@ static int __init mts_io_init(void) if (accessory_card_capable) { mts_ap1_product_id = MTDC_NONE; - ret = mts_ap_eeprom_load(); - if (ret) { - /* error reading the EEPROM from the daughter card */ - log_error("error reading daughter card eeprom: %d", ret); - log_error("unable to initialize daughter card"); - goto error1; - } else if (false) { - // this needs review, stay away for now - /* no error and we have a daughter card */ - if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) { - mts_ap1_product_id = MTDC_GPIOB_0_0; + mts_ap2_product_id = MTDC_NONE; + if (mts_ap_eeprom_load()) { + // handle both slots, but do slot 1 first + // probably need special handling if both cards are the same type + if (have_accessory_card_slot_1) { + // more elegant way to handle this? + if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) { + mts_ap1_product_id = MTDC_GPIOB_0_0; + } // else if (...) { } + + switch(mts_ap1_product_id) { + case MTDC_GPIOB_0_0: + log_info("loading GPIO accessory card in slot 1"); + if (! add_accessory_card_attributes(1)) { + log_error("failed to load GPIO accessory card in slot 1"); + } else { + log_info("successfully loaded GPIO accessory card in slot 1"); + } + log_debug("registering accessory card 1 dout driver"); + ret = spi_register_driver(&mts_spi_ap1_dout_driver); + if (ret) { + log_error("failed to register accessory card 1 dout driver"); + spi_unregister_driver(&mts_spi_ap1_dout_driver); + goto error1; + } + log_debug("registering accessory card 1 din driver"); + ret = spi_register_driver(&mts_spi_ap1_din_driver); + if (ret) { + log_error("failed to register accessory card 1 din driver"); + spi_unregister_driver(&mts_spi_ap1_din_driver); + goto error1; + } + log_debug("registering accessory card 1 adc driver"); + ret = spi_register_driver(&mts_spi_ap1_adc_driver); + if (ret) { + log_error("failed to register accessory card 1 adc driver"); + spi_unregister_driver(&mts_spi_ap1_adc_driver); + goto error1; + } + break; + + default: + log_error("accessory card %s unsupported", ap1_eeprom.product_id); + } } - switch(mts_ap1_product_id) { - case MTDC_GPIOB_0_0: - log_debug("adding GPIO daughter card attributes"); - if (! mtr2_add_daughter_card_attributes()) { - log_error("failed to add GPIO daughter card attributes"); - goto error1; - } else { - log_info("successfully added GPIO daughter card attributes"); - } - - log_debug("registering daughter card dout driver"); - ret = spi_register_driver(&mts_spi_dc_dout_driver); - if (ret) { - log_error("failed to register dc dout driver"); - spi_unregister_driver(&mts_spi_dc_dout_driver); - goto error1; - } - log_debug("registering daughter card din driver"); - ret = spi_register_driver(&mts_spi_dc_din_driver); - if (ret) { - log_error("failed to register dc din driver"); - spi_unregister_driver(&mts_spi_dc_din_driver); - goto error1; - } - log_debug("registering daughter card adc driver"); - ret = spi_register_driver(&mts_spi_dc_adc_driver); - if (ret) { - log_error("failed to register dc adc driver"); - spi_unregister_driver(&mts_spi_dc_adc_driver); - goto error1; - } - break; - - default: - log_info("daughter card '%s' currently unsupported", ap1_eeprom.product_id); + if (have_accessory_card_slot_2) { + // more elegant way to handle this? + if (strstr(ap2_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) { + mts_ap2_product_id = MTDC_GPIOB_0_0; + } // else if (...) { } + + switch(mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + log_info("loading GPIO accessory card in slot 2"); + if (! add_accessory_card_attributes(2)) { + log_error("failed to load GPIO accessory card in slot 2"); + } else { + log_info("successfully loaded GPIO accessory card in slot 2"); + } + log_debug("registering accessory card 2 dout driver"); + ret = spi_register_driver(&mts_spi_ap2_dout_driver); + if (ret) { + log_error("failed to register accessory card 2 dout driver"); + spi_unregister_driver(&mts_spi_ap2_dout_driver); + goto error1; + } + log_debug("registering accessory card 2 din driver"); + ret = spi_register_driver(&mts_spi_ap2_din_driver); + if (ret) { + log_error("failed to register accessory card 2 din driver"); + spi_unregister_driver(&mts_spi_ap2_din_driver); + goto error1; + } + log_debug("registering accessory card 2 adc driver"); + ret = spi_register_driver(&mts_spi_ap2_adc_driver); + if (ret) { + log_error("failed to register accessory card 2 adc driver"); + spi_unregister_driver(&mts_spi_ap2_adc_driver); + goto error1; + } + break; + + default: + log_error("accessory card %s unsupported", ap1_eeprom.product_id); + } } } } @@ -815,6 +919,32 @@ error3: platform_device_del(mts_io_platform_device); error2: platform_device_put(mts_io_platform_device); + + if (have_accessory_card_slot_1) { + switch (mts_ap1_product_id) { + case MTDC_GPIOB_0_0: + spi_unregister_driver(&mts_spi_ap1_dout_driver); + spi_unregister_driver(&mts_spi_ap1_din_driver); + spi_unregister_driver(&mts_spi_ap1_adc_driver); + break; + + default: + break; + } + } + + if (have_accessory_card_slot_2) { + switch (mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + spi_unregister_driver(&mts_spi_ap2_dout_driver); + spi_unregister_driver(&mts_spi_ap2_din_driver); + spi_unregister_driver(&mts_spi_ap2_adc_driver); + break; + + default: + break; + } + } error1: log_error("init failed: %d", ret); @@ -843,12 +973,25 @@ static void __exit mts_io_exit(void) if (has_spi_sout) spi_unregister_driver(&mts_spi_sout_driver); - if (has_accessory_card_port_1) { + if (have_accessory_card_slot_1) { switch (mts_ap1_product_id) { case MTDC_GPIOB_0_0: - spi_unregister_driver(&mts_spi_dc_dout_driver); - spi_unregister_driver(&mts_spi_dc_din_driver); - spi_unregister_driver(&mts_spi_dc_adc_driver); + spi_unregister_driver(&mts_spi_ap1_dout_driver); + spi_unregister_driver(&mts_spi_ap1_din_driver); + spi_unregister_driver(&mts_spi_ap1_adc_driver); + break; + + default: + break; + } + } + + if (have_accessory_card_slot_2) { + switch (mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + spi_unregister_driver(&mts_spi_ap2_dout_driver); + spi_unregister_driver(&mts_spi_ap2_din_driver); + spi_unregister_driver(&mts_spi_ap2_adc_driver); break; default: @@ -877,6 +1020,9 @@ MODULE_ALIAS("mts-io-sout"); MODULE_ALIAS("mts-io-board-temp"); MODULE_ALIAS("mts-io-dout"); MODULE_ALIAS("mts-io-din"); -MODULE_ALIAS("mts-io-dc-dout"); -MODULE_ALIAS("mts-io-dc-din"); -MODULE_ALIAS("mts-io-dc-adc"); +MODULE_ALIAS("mts-io-ap1-dout"); +MODULE_ALIAS("mts-io-ap1-din"); +MODULE_ALIAS("mts-io-ap1-adc"); +MODULE_ALIAS("mts-io-ap2-dout"); +MODULE_ALIAS("mts-io-ap2-din"); +MODULE_ALIAS("mts-io-ap2-adc"); |