summaryrefslogtreecommitdiff
path: root/io-module/mts_io.c
diff options
context:
space:
mode:
authorMike Fiore <mfiore@multitech.com>2014-09-23 10:35:11 -0500
committerMike Fiore <mfiore@multitech.com>2014-09-23 10:35:11 -0500
commita21c24fa2486e4d4a3b25d0dcbf873ae62fdbcec (patch)
tree6d78da220c6235cd33408acbd22adf9b4038bbc1 /io-module/mts_io.c
parent24c012065ca7a764e1e51a9cfc4422d649cd2851 (diff)
downloadmts-io-a21c24fa2486e4d4a3b25d0dcbf873ae62fdbcec.tar.gz
mts-io-a21c24fa2486e4d4a3b25d0dcbf873ae62fdbcec.tar.bz2
mts-io-a21c24fa2486e4d4a3b25d0dcbf873ae62fdbcec.zip
mts-io: clean up accessory card support
use custom kernel config option MTS_NUM_ACCESSORY_PORTS to find out how many slots exist (mostly) dynamically handle any number of accessory cards streamline code to make it easier to add accessory cards in the future
Diffstat (limited to 'io-module/mts_io.c')
-rw-r--r--io-module/mts_io.c376
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");
}