diff options
Diffstat (limited to 'io-module/mts_io.c')
-rw-r--r-- | io-module/mts_io.c | 376 |
1 files changed, 85 insertions, 291 deletions
diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 9adfd12..936d0d2 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -59,24 +59,33 @@ extern uint8_t mts_id_eeprom[512]; static struct mts_id_eeprom_layout id_eeprom; -/* accessory card EEPROMs */ -#ifdef MTOCGD2 -extern uint8_t mts_ap1_eeprom[512]; -extern uint8_t mts_ap2_eeprom[512]; +// NUM_AP should be defined from the board code +// it should be set to the value of CONFIG_MTS_NUM_ACCESSORY_PORTS +// arch/arm/mach-at91/board-dt-sam9.c +// if it is 0 or undefined, there is no accessory card support on this HW +#ifdef CONFIG_MTS_NUM_ACCESSORY_PORTS + +#ifndef NUM_AP +#define NUM_AP CONFIG_MTS_NUM_ACCESSORY_PORTS +#endif + #else -uint8_t mts_ap1_eeprom[512] = {}; -uint8_t mts_ap2_eeprom[512] = {}; +#define NUM_AP 0 #endif -static struct mts_ap_eeprom_layout ap1_eeprom; -static struct mts_ap_eeprom_layout ap2_eeprom; -bool accessory_card_capable = false; -bool have_accessory_card_slot_1 = false; -bool have_accessory_card_slot_2 = false; +#if NUM_AP > 0 +/* accessory card EEPROMs */ +extern uint8_t mts_ap_eeprom[NUM_AP][512]; +static struct mts_ap_eeprom_layout ap_eeprom[NUM_AP]; +#endif + +static struct ap_info* port_info[NUM_AP]; + +static struct attribute **device_attrs; +static size_t device_attrs_size; +static size_t device_attrs_max_size; static uint8_t mts_product_id; -static uint8_t mts_ap1_product_id; -static uint8_t mts_ap2_product_id; static uint8_t has_spi_sout; static uint8_t has_spi_din; static uint8_t has_spi_dout; @@ -98,6 +107,7 @@ static DEFINE_MUTEX(mts_io_mutex); #include "spi.c" /* accessory card support */ +#include "mtac.c" #include "mtac_gpiob.c" #include "mtac_mfser.c" @@ -415,131 +425,57 @@ static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth", #include "mt100eocg.c" */ -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; - } +static bool load_port(int port) { + int port_index = port - 1; + memcpy(&ap_eeprom[port_index], mts_ap_eeprom[port_index], sizeof(mts_ap_eeprom[port_index])); - if (slot == 1) { - switch (mts_ap1_product_id) { - case MTAC_GPIOB_0_0: - card_attrs_size = ap1_gpio_attributes_size; - card_attrs = ap1_gpio_attributes; - break; - case MTAC_MFSER_0_0: - card_attrs_size = ap1_mfser_attributes_size; - card_attrs = ap1_mfser_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 MTAC_GPIOB_0_0: - card_attrs_size = ap2_gpio_attributes_size; - card_attrs = ap2_gpio_attributes; - break; - case MTAC_MFSER_0_0: - card_attrs_size = ap2_mfser_attributes_size; - card_attrs = ap2_mfser_attributes; - break; - default: - log_error("accessory card %s isn't supported", ap2_eeprom.hw_version); - return false; - } + if (mts_ap_eeprom[port_index][0] == 0xFF) { + log_error("uninitialized eeprom on accessory card %d", port); + } else if (mts_ap_eeprom[port_index][0] == 0x00) { + log_info("no accessory card inserted in port %d", port); } 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 (strstr(ap_eeprom[port_index].product_id, PRODUCT_ID_MTAC_GPIOB)) { + port_info[port_index] = &gpiob_info; + } else if (strstr(ap_eeprom[port_index].product_id, PRODUCT_ID_MTAC_MFSER)) { + port_info[port_index] = &mfser_info; + } else { + log_error("unknown accessory card [%s] in port %d", ap_eeprom[port_index].product_id, port); + return false; } - } - if (device_attrs_size < attrs_index + card_attrs_size) { - log_error("not enough room for accessory card attributes!"); - return false; - } + log_info("accessory card %d vendor-id: %.32s", port, ap_eeprom[port_index].vendor_id); + log_info("accessory card %d product-id: %.32s", port, ap_eeprom[port_index].product_id); + log_info("accessory card %d device-id: %.32s", port, ap_eeprom[port_index].device_id); + log_info("accessory card %d hw-version: %.32s", port, ap_eeprom[port_index].hw_version); + if (strncmp(ap_eeprom[port_index].product_id, PRODUCT_ID_MTAC_ETH, strlen(PRODUCT_ID_MTAC_ETH)) == 0) { + log_info("accessory card %d mac-addr: %02X:%02X:%02X:%02X:%02X:%02X", + port, + ap_eeprom[port_index].mac_addr[0], + ap_eeprom[port_index].mac_addr[1], + ap_eeprom[port_index].mac_addr[2], + ap_eeprom[port_index].mac_addr[3], + ap_eeprom[port_index].mac_addr[4], + ap_eeprom[port_index].mac_addr[5]); + } - for (i = 0; i < card_attrs_size; i++) { - device_attrs[attrs_index + i] = card_attrs[i]; + if (! port_info[port_index]->setup(port)) { + log_error("accessory port %d setup failed", port); + port_info[port_index]->teardown(port); + return false; + } } return true; } -static bool mts_ap_eeprom_load(void) +static void init_accessory_ports(void) { - // Accessory Card Slot 1 - memcpy(&ap1_eeprom, mts_ap1_eeprom, sizeof(mts_ap1_eeprom)); - - if (mts_ap1_eeprom[0] == 0xFF) { - log_error("uninitialized eeprom on accessory card 1"); - } else if (mts_ap1_eeprom[0] == 0x00) { - log_info("no accessory card inserted in slot 1"); - } else { - 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); - log_info("accessory card 1 device-id: %.32s", ap1_eeprom.device_id); - log_info("accessory card 1 hw-version: %.32s", ap1_eeprom.hw_version); - if (strncmp(ap1_eeprom.product_id, PRODUCT_ID_MTAC_ETH, strlen(PRODUCT_ID_MTAC_ETH)) == 0) { - log_info("accessory card 1 mac-addr: %02X:%02X:%02X:%02X:%02X:%02X", - ap1_eeprom.mac_addr[0], - ap1_eeprom.mac_addr[1], - ap1_eeprom.mac_addr[2], - ap1_eeprom.mac_addr[3], - ap1_eeprom.mac_addr[4], - ap1_eeprom.mac_addr[5]); - } - } - - // Accessory Card Slot 2 - memcpy(&ap2_eeprom, mts_ap2_eeprom, sizeof(mts_ap2_eeprom)); - - if (mts_ap2_eeprom[0] == 0xFF) { - log_error("uninitialized eeprom on accessory card 2"); - } else if (mts_ap2_eeprom[0] == 0x00) { - log_info("no accessory card inserted in slot 2"); - } else { - 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); - log_info("accessory card 2 device-id: %.32s", ap2_eeprom.device_id); - log_info("accessory card 2 hw-version: %.32s", ap2_eeprom.hw_version); - if (strncmp(ap2_eeprom.product_id, PRODUCT_ID_MTAC_ETH, strlen(PRODUCT_ID_MTAC_ETH)) == 0) { - log_info("accessory card 2 mac-addr: %02X:%02X:%02X:%02X:%02X:%02X", - ap2_eeprom.mac_addr[0], - ap2_eeprom.mac_addr[1], - ap2_eeprom.mac_addr[2], - ap2_eeprom.mac_addr[3], - ap2_eeprom.mac_addr[4], - ap2_eeprom.mac_addr[5]); + int i; + for (i = 1; i <= NUM_AP; i++) { + if (! load_port(i)) { + log_error("failed to load accessory card in port %d", i); } } - - // 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) @@ -581,7 +517,6 @@ static int mts_id_eeprom_load(void) attr_group = &mtr2_platform_attribute_group; gpio_pins = gpio_pins_mtr2_0_0; mts_product_id = MTR2_0_0; - accessory_card_capable = true; has_spi_sout = 0; has_spi_din = 0; has_spi_dout = 0; @@ -611,7 +546,6 @@ static int mts_id_eeprom_load(void) attr_group = &mtr2_platform_attribute_group; gpio_pins = gpio_pins_mtr2_0_0; mts_product_id = MTOCGD2_0_0; - accessory_card_capable = true; has_spi_sout = 0; has_spi_din = 0; has_spi_dout = 0; @@ -637,10 +571,15 @@ static int mts_id_eeprom_load(void) has_spi_temp = 0; log_info("detected board %s", HW_VERSION_MTOCGD_0_1); } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTR2D2_0_0, strlen(HW_VERSION_MTR2D2_0_0)) == 0) { + // need to put any accessory card attributes into this list so they show up in sysfs + // the port_info->setup callback does this + device_attrs = mtr2d2_platform_attributes; + device_attrs_size = mtr2d2_platform_attributes_size; + device_attrs_max_size = mtr2d2_platform_attributes_max_size; + 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; @@ -706,6 +645,7 @@ static int __init mts_io_init(void) int ret; size_t device_attributes_size; size_t card_attributes_size; + int i; log_info("init: " DRIVER_VERSION); @@ -714,118 +654,11 @@ static int __init mts_io_init(void) goto error1; } - if (accessory_card_capable) { - mts_ap1_product_id = MTAC_NONE; - mts_ap2_product_id = MTAC_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_MTAC_GPIOB)) { - mts_ap1_product_id = MTAC_GPIOB_0_0; - } - else if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTAC_MFSER)) { - mts_ap1_product_id = MTAC_MFSER_0_0; - } - - switch(mts_ap1_product_id) { - case MTAC_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; - case MTAC_MFSER_0_0: - log_info("loading MFSER accessory card in slot 1"); - if (! add_accessory_card_attributes(1)) { - log_error("failed to load MFSER accessory card in slot 1"); - } else { - log_info("successfully loaded MFSER accessory card in slot 1"); - } - break; - - default: - log_error("accessory card %s 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_MTAC_GPIOB)) { - mts_ap2_product_id = MTAC_GPIOB_0_0; - } - else if (strstr(ap2_eeprom.product_id, PRODUCT_ID_MTAC_MFSER)) { - mts_ap2_product_id = MTAC_MFSER_0_0; - } - - switch(mts_ap2_product_id) { - case MTAC_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; - case MTAC_MFSER_0_0: - log_info("loading MFSER accessory card in slot 2"); - if (! add_accessory_card_attributes(2)) { - log_error("failed to load MFSER accessory card in slot 2"); - } else { - log_info("successfully loaded MFSER accessory card in slot 2"); - } - break; - - default: - log_error("accessory card %s unsupported", ap1_eeprom.product_id); - } - } + if (NUM_AP) { + for (i = 0; i < NUM_AP; i++) { + port_info[i] = NULL; } + init_accessory_ports(); } mts_io_platform_device = platform_device_alloc(PLATFORM_NAME, -1); @@ -950,40 +783,21 @@ 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 MTAC_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 MTAC_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); + for (i = 0; i < NUM_AP; i++) { + if (port_info[i]) { + port_info[i]->teardown(i); + } + } return ret; } static void __exit mts_io_exit(void) { + int i; + if ( mts_product_id != MT100EOCG_0_0 ) { cancel_delayed_work_sync(&reset_work); } @@ -1004,38 +818,18 @@ static void __exit mts_io_exit(void) if (has_spi_sout) spi_unregister_driver(&mts_spi_sout_driver); - if (have_accessory_card_slot_1) { - switch (mts_ap1_product_id) { - case MTAC_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 MTAC_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; - } - } - sysfs_remove_group(&mts_io_platform_device->dev.kobj, attr_group); sysfs_remove_link(&mts_io_platform_device->dev.parent->kobj, "mtcdp"); platform_device_unregister(mts_io_platform_device); + for (i = 0; i < NUM_AP; i++) { + if (port_info[i]) { + port_info[i]->teardown(i); + } + } + log_info("exiting"); } |