From 6709e0cb9fce54385937ccd4d42dece2159664a9 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Mon, 25 Aug 2014 14:43:59 -0500 Subject: mts-io: more changes for mtr2d2 HW only log MAC addresses for BT and WIFI if capable log contents of both accessory card EEPROMs skip loading accessory card attributes for now - needs rework w/new HW define MTAC-ETH in mts-io.h --- io-module/mts_io.c | 94 +++++++++++++++++++++++++++++++++++------------------- io-module/mts_io.h | 2 +- 2 files changed, 63 insertions(+), 33 deletions(-) diff --git a/io-module/mts_io.c b/io-module/mts_io.c index bf0332a..e26013d 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -419,30 +419,55 @@ static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth", */ static int mts_ap_eeprom_load(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 daughter card"); - return -EIO; + log_error("uninitialized eeprom on accessory card 1"); } else if (mts_ap1_eeprom[0] == 0x00) { - log_info("no daughter card inserted"); - return 0; + log_info("no accessory card inserted in slot 1"); + } else { + has_accessory_card_port_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_MTDC_ETH, strlen(PRODUCT_ID_MTDC_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]); + } } - has_accessory_card_port_1 = true; + // Accessory Card Slot 2 + memcpy(&ap2_eeprom, mts_ap2_eeprom, sizeof(mts_ap2_eeprom)); - log_info("daughter card vendor-id: %.32s", ap1_eeprom.vendor_id); - log_info("daughter card product-id: %.32s", ap1_eeprom.product_id); - log_info("daughter card device-id: %.32s", ap1_eeprom.device_id); - log_info("daughter card hw-version: %.32s", ap1_eeprom.hw_version); - /* TODO: only show the mac address if this is the ethernet card */ - log_info("daughter card 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]); + 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 { + has_accessory_card_port_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_MTDC_ETH, strlen(PRODUCT_ID_MTDC_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]); + } + } return 0; } @@ -580,20 +605,24 @@ static int mts_id_eeprom_load(void) log_info("capa-adc: %s", DEVICE_CAPA(id_eeprom.capa, CAPA_ADC) ? "yes" : "no"); log_info("capa-wifi: %s", DEVICE_CAPA(id_eeprom.capa, CAPA_WIFI) ? "yes" : "no"); log_info("capa-bluetooth: %s", DEVICE_CAPA(id_eeprom.capa, CAPA_BLUETOOTH) ? "yes" : "no"); - log_info("mac-bluetooth: %02X:%02X:%02X:%02X:%02X:%02X", - id_eeprom.mac_bluetooth[0], - id_eeprom.mac_bluetooth[1], - id_eeprom.mac_bluetooth[2], - id_eeprom.mac_bluetooth[3], - id_eeprom.mac_bluetooth[4], - id_eeprom.mac_bluetooth[5]); - log_info("mac-wifi: %02X:%02X:%02X:%02X:%02X:%02X", - id_eeprom.mac_wifi[0], - id_eeprom.mac_wifi[1], - id_eeprom.mac_wifi[2], - id_eeprom.mac_wifi[3], - id_eeprom.mac_wifi[4], - id_eeprom.mac_wifi[5]); + if (DEVICE_CAPA(id_eeprom.capa, CAPA_BLUETOOTH)) { + log_info("mac-bluetooth: %02X:%02X:%02X:%02X:%02X:%02X", + id_eeprom.mac_bluetooth[0], + id_eeprom.mac_bluetooth[1], + id_eeprom.mac_bluetooth[2], + id_eeprom.mac_bluetooth[3], + id_eeprom.mac_bluetooth[4], + id_eeprom.mac_bluetooth[5]); + } + if (DEVICE_CAPA(id_eeprom.capa, CAPA_WIFI)) { + log_info("mac-wifi: %02X:%02X:%02X:%02X:%02X:%02X", + id_eeprom.mac_wifi[0], + id_eeprom.mac_wifi[1], + id_eeprom.mac_wifi[2], + id_eeprom.mac_wifi[3], + id_eeprom.mac_wifi[4], + id_eeprom.mac_wifi[5]); + } return 0; } @@ -618,7 +647,8 @@ static int __init mts_io_init(void) log_error("error reading daughter card eeprom: %d", ret); log_error("unable to initialize daughter card"); goto error1; - } else if (has_accessory_card_port_1) { + } 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; diff --git a/io-module/mts_io.h b/io-module/mts_io.h index fc37ac5..cff0b2a 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -49,7 +49,7 @@ struct device_attribute _dev_name = { \ #define PRODUCT_ID_MTR2D2 "MTR2D2" #define PRODUCT_ID_MTDC_GPIOB "MTDC-GPIOB" - +#define PRODUCT_ID_MTDC_ETH "MTDC-ETH" #define HW_VERSION_MTCBA2_2_0 "MTCBA2-2.0" #define HW_VERSION_MTCDP_0_0 "MTCDP-0.0" -- cgit v1.2.3 From 1e563fc723ad8a44850b92f9c6e8c0bb41178215 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 27 Aug 2014 16:35:15 -0500 Subject: accessory cards: support both ports allow for 2 GPIOB accessory cards to be used at the same time some misc cleanup, more specific logging on init commented out mtr2 platform as it currently causes build issues with accessory card changes --- io-module/mtdc_gpiob.c | 289 ++++++++++++++++++++++++++++++++++++------------- io-module/mtr2d2.c | 134 +++++++++++++++++++++++ io-module/mts_io.c | 274 +++++++++++++++++++++++++++++++++++----------- io-module/spi.c | 248 ++++++++++++++++++++++++++++++++---------- 4 files changed, 750 insertions(+), 195 deletions(-) diff --git a/io-module/mtdc_gpiob.c b/io-module/mtdc_gpiob.c index c207483..5a592b7 100644 --- a/io-module/mtdc_gpiob.c +++ b/io-module/mtdc_gpiob.c @@ -1,16 +1,25 @@ - -struct gpio_pin *dc_gpio_pin_by_attr_name(const char *name) { +struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { struct gpio_pin *pin; char *pin_attr_name; - if (!strcmp(name, "led1")) { - pin_attr_name = "dc-gpio1"; - } else if (!strcmp(name, "led2")) { - pin_attr_name = "dc-gpio2"; - } else if (!strcmp(name, "dout-enable")) { - pin_attr_name = "dc-gpio3"; + if (!strcmp(name, "ap1-led1")) { + pin_attr_name = "ap1-gpio3"; + } else if (!strcmp(name, "ap1-led2")) { + pin_attr_name = "ap1-gpio4"; + } else if (!strcmp(name, "ap1-dout-enable")) { + pin_attr_name = "ap1-gpio1"; + } else if (!strcmp(name, "ap1-reset")) { + pin_attr_name = "ap1-reset"; + } else if (!strcmp(name, "ap2-led1")) { + pin_attr_name = "ap2-gpio3"; + } else if (!strcmp(name, "ap2-led2")) { + pin_attr_name = "ap2-gpio4"; + } else if (!strcmp(name, "ap2-dout-enable")) { + pin_attr_name = "ap2-gpio1"; + } else if (!strcmp(name, "ap2-reset")) { + pin_attr_name = "ap2-reset"; } else { - log_error("daughter card attribute %s not available", name); + log_error("accessory card attribute %s not available", name); return NULL; } @@ -26,12 +35,12 @@ struct gpio_pin *dc_gpio_pin_by_attr_name(const char *name) { } -static ssize_t mts_attr_show_dc_gpio_pin(struct device *dev, +static ssize_t mts_attr_show_ap_gpio_pin(struct device *dev, struct device_attribute *attr, char *buf) { int value; - struct gpio_pin *pin = dc_gpio_pin_by_attr_name(attr->attr.name); + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); if (!pin) { return -ENODEV; @@ -54,11 +63,11 @@ static ssize_t mts_attr_show_dc_gpio_pin(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t mts_attr_store_dc_gpio_pin(struct device *dev, +static ssize_t mts_attr_store_ap_gpio_pin(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; - struct gpio_pin *pin = dc_gpio_pin_by_attr_name(attr->attr.name); + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); if (!pin) { return -ENODEV; @@ -81,31 +90,46 @@ static ssize_t mts_attr_store_dc_gpio_pin(struct device *dev, return count; } -static ssize_t mts_attr_show_dc_din(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_din(struct device *dev, struct device_attribute *attr, char *buf) { int tmp; u8 bit; u8 byte; + struct spi_device* spi_dev; + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_din_dev) { + log_error("accessory card 1 din device not present"); + return -ENODEV; + } - if (!spi_dc_din_dev) { - log_error("dc din device not present"); + spi_dev = spi_ap1_din_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_din_dev) { + log_error("accessory card 2 din device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_din_dev; + } else { + log_error("unknown din device %s", attr->attr.name); return -ENODEV; } - if (!strcmp(attr->attr.name, "din0")) { + if (strstr(attr->attr.name, "din0")) { bit = BIT(0); - } else if (!strcmp(attr->attr.name, "din1")) { + } else if (strstr(attr->attr.name, "din1")) { bit = BIT(1); - } else if (!strcmp(attr->attr.name, "din2")) { + } else if (strstr(attr->attr.name, "din2")) { bit = BIT(2); - } else if (!strcmp(attr->attr.name, "din3")) { + } else if (strstr(attr->attr.name, "din3")) { bit = BIT(3); } else { - log_error("dc din attr does not exist"); + log_error("accessory card din attr does not exist"); return -ENOENT; } - tmp = spi_readn(spi_dc_din_dev, &byte, 1); + tmp = spi_readn(spi_dev, &byte, 1); if (tmp) { log_error("spi_read failed %d", tmp); return tmp; @@ -116,82 +140,112 @@ static ssize_t mts_attr_show_dc_din(struct device *dev, struct device_attribute return sprintf(buf, "%d\n", tmp); } -static ssize_t mts_attr_store_dc_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mts_attr_store_ap_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; u8 bit; + struct spi_device* spi_dev; + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_dout_dev) { + log_error("accessory card 1 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_dout_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_dout_dev) { + log_error("accessory card 2 dout device not present"); + return -ENODEV; + } - if (!spi_dc_dout_dev) { - log_error("dc dout device not present"); + spi_dev = spi_ap2_dout_dev; + } else { + log_error("unknown dout device %s", attr->attr.name); return -ENODEV; } - if (!strcmp(attr->attr.name, "dout0")) { + if (strstr(attr->attr.name, "dout0")) { bit = BIT(0); - } else if (!strcmp(attr->attr.name, "dout1")) { + } else if (strstr(attr->attr.name, "dout1")) { bit = BIT(1); - } else if (!strcmp(attr->attr.name, "dout2")) { + } else if (strstr(attr->attr.name, "dout2")) { bit = BIT(2); - } else if (!strcmp(attr->attr.name, "dout3")) { + } else if (strstr(attr->attr.name, "dout3")) { bit = BIT(3); } else { - log_error("dc dout attr does not exist"); + log_error("accessory card dout attr does not exist"); return -ENOENT; } if (sscanf(buf, "%i", &value) != 1) { - log_error("dc dout attr invalid argument"); + log_error("accessory card dout attr invalid argument"); return -EINVAL; } - mutex_lock(&spi_dc_dout_mutex); + mutex_lock(&spi_ap_dout_mutex); if (value) { - spi_dc_dout_value &= ~bit; + spi_ap_dout_value &= ~bit; } else { - spi_dc_dout_value |= bit; + spi_ap_dout_value |= bit; } - spi_writen(spi_dc_dout_dev, &spi_dc_dout_value, 1); + spi_writen(spi_dev, &spi_ap_dout_value, 1); - mutex_unlock(&spi_dc_dout_mutex); + mutex_unlock(&spi_ap_dout_mutex); return count; } -static ssize_t mts_attr_show_dc_dout(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_dout(struct device *dev, struct device_attribute *attr, char *buf) { int value; u8 bit; + struct spi_device* spi_dev; - if (!spi_dc_dout_dev) { - log_error("dc dout device not present"); + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_dout_dev) { + log_error("accessory card 1 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_dout_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_dout_dev) { + log_error("accessory card 2 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_dout_dev; + } else { + log_error("unknown dout device %s", attr->attr.name); return -ENODEV; } - if (!strcmp(attr->attr.name, "dout0")) { + if (strstr(attr->attr.name, "dout0")) { bit = BIT(0); - } else if (!strcmp(attr->attr.name, "dout1")) { + } else if (strstr(attr->attr.name, "dout1")) { bit = BIT(1); - } else if (!strcmp(attr->attr.name, "dout2")) { + } else if (strstr(attr->attr.name, "dout2")) { bit = BIT(2); - } else if (!strcmp(attr->attr.name, "dout3")) { + } else if (strstr(attr->attr.name, "dout3")) { bit = BIT(3); } else { - log_error("dc dout attr does not exist"); + log_error("accessory card dout attr does not exist"); return -ENOENT; } - mutex_lock(&spi_dc_dout_mutex); + mutex_lock(&spi_ap_dout_mutex); - value = spi_dc_dout_value & bit ? 0 : 1; + value = spi_ap_dout_value & bit ? 0 : 1; - mutex_unlock(&spi_dc_dout_mutex); + mutex_unlock(&spi_ap_dout_mutex); return sprintf(buf, "%d\n", value); } -static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute *attr, char *buf) { int tmp; int tx_data; @@ -201,23 +255,38 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute int manual_mode = 0x1840; /* 0b 0001 1000 0100 0000 */ uint8_t tx[2]; uint8_t rx[2]; - - if (!spi_dc_adc_dev) { - log_error("dc adc device not present"); - return -ENODEV; - } + struct spi_device* spi_dev; memset(tx, 0, sizeof(tx)); memset(rx, 0, sizeof(rx)); - if (!strcmp(attr->attr.name, "adc0")) { + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_adc_dev) { + log_error("accessory card 1 adc device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_adc_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_adc_dev) { + log_error("accessory card 2 adc device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_adc_dev; + } else { + log_error("unknown adc device %s", attr->attr.name); + return -ENODEV; + } + + if (strstr(attr->attr.name, "adc0")) { channel = 0; - } else if (!strcmp(attr->attr.name, "adc1")) { + } else if (strstr(attr->attr.name, "adc1")) { channel = 1; - } else if (! strcmp(attr->attr.name, "adc2")) { + } else if (strstr(attr->attr.name, "adc2")) { channel = 2; } else { - log_error("dc adc attr does not exist"); + log_error("accessory card adc attr does not exist"); return -ENOENT; } @@ -225,7 +294,7 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute tx_data = manual_mode | ((channel << 7) & channel_mask); tx[0] = tx_data >> 8; tx[1] = tx_data & 0xFF; - tmp = spi_writen(spi_dc_adc_dev, tx, 2); + tmp = spi_writen(spi_dev, tx, 2); if (tmp) { log_error("spi_write failed %d", tmp); return tmp; @@ -236,14 +305,14 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute * the ADC just needs the clock running so it can convert */ tx[0] = 0; tx[1] = 0; - tmp = spi_writen(spi_dc_adc_dev, tx, 2); + tmp = spi_writen(spi_dev, tx, 2); if (tmp) { log_error("2nd spi_write failed %d", tmp); return tmp; } /* 3rd transfer to read data */ - tmp = spi_readn(spi_dc_adc_dev, rx, 2); + tmp = spi_readn(spi_dev, rx, 2); if (tmp) { log_error("spi_read failed %d", tmp); return tmp; @@ -253,18 +322,88 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute return sprintf(buf, "%lu\n", (unsigned long) rx_data); } -/* MTDC-GPIOB */ -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din0, "din0", mts_attr_show_dc_din); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din1, "din1", mts_attr_show_dc_din); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din2, "din2", mts_attr_show_dc_din); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din3, "din3", mts_attr_show_dc_din); -static DEVICE_ATTR_MTS(dev_attr_dc_dout0, "dout0", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_MTS(dev_attr_dc_dout1, "dout1", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_MTS(dev_attr_dc_dout2, "dout2", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_MTS(dev_attr_dc_dout3, "dout3", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc0, "adc0", mts_attr_show_dc_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc1, "adc1", mts_attr_show_dc_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc2, "adc2", mts_attr_show_dc_adc); -static DEVICE_ATTR_MTS(dev_attr_dc_led1, "led1", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_dc_led2, "led2", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_dc_oe, "dout-enable", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin); +/* accessory port 1 gpiob attributes */ +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din0, "din0:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din1, "din1:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din2, "din2:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din3, "din3:0", mts_attr_show_ap_din); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout0, "dout0:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout1, "dout1:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout2, "dout2:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout3, "dout3:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc0, "adc0:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc1, "adc1:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc2, "adc2:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led1, "ap1-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led2, "ap1-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_oe, "ap1-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_reset, "ap1-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); + +static int ap1_gpio_attributes_size = 15; // not including NULL at end + +static struct attribute *ap1_gpio_attributes[] = { + &dev_attr_ap1_reset.attr, + + &dev_attr_ap1_gpio_oe.attr, // gpio1 + &dev_attr_ap1_gpio_led1.attr, // gpio3 + &dev_attr_ap1_gpio_led2.attr, // gpio4 + + &dev_attr_ap1_gpio_din0.attr, + &dev_attr_ap1_gpio_din1.attr, + &dev_attr_ap1_gpio_din2.attr, + &dev_attr_ap1_gpio_din3.attr, + + &dev_attr_ap1_gpio_dout0.attr, + &dev_attr_ap1_gpio_dout1.attr, + &dev_attr_ap1_gpio_dout2.attr, + &dev_attr_ap1_gpio_dout3.attr, + + &dev_attr_ap1_gpio_adc0.attr, + &dev_attr_ap1_gpio_adc1.attr, + &dev_attr_ap1_gpio_adc2.attr, + + NULL, +}; + +/* accessory port 2 gpiob attributes */ +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din0, "din0:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din1, "din1:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din2, "din2:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din3, "din3:1", mts_attr_show_ap_din); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout0, "dout0:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout1, "dout1:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout2, "dout2:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout3, "dout3:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc0, "adc0:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc1, "adc1:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc2, "adc2:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led1, "ap2-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led2, "ap2-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_oe, "ap2-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_reset, "ap2-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); + +static int ap2_gpio_attributes_size = 15; // not including NULL at end + +static struct attribute *ap2_gpio_attributes[] = { + &dev_attr_ap2_reset.attr, + + &dev_attr_ap2_gpio_oe.attr, // gpio1 + &dev_attr_ap2_gpio_led1.attr, // gpio3 + &dev_attr_ap2_gpio_led2.attr, // gpio4 + + &dev_attr_ap2_gpio_din0.attr, + &dev_attr_ap2_gpio_din1.attr, + &dev_attr_ap2_gpio_din2.attr, + &dev_attr_ap2_gpio_din3.attr, + + &dev_attr_ap2_gpio_dout0.attr, + &dev_attr_ap2_gpio_dout1.attr, + &dev_attr_ap2_gpio_dout2.attr, + &dev_attr_ap2_gpio_dout3.attr, + + &dev_attr_ap2_gpio_adc0.attr, + &dev_attr_ap2_gpio_adc1.attr, + &dev_attr_ap2_gpio_adc2.attr, + + NULL, +}; diff --git a/io-module/mtr2d2.c b/io-module/mtr2d2.c index 58aeb03..b2fc03f 100644 --- a/io-module/mtr2d2.c +++ b/io-module/mtr2d2.c @@ -146,9 +146,130 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { }, .active_low = 1, }, + + // gpio pins for Accessory Card 1 + { + .name = "AP1_RESET", + .pin = { + .gpio = AT91_PIN_PB12, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "ap1-reset", + } + }, + { + .name = "AP1_GPIO1", + .pin = { + .gpio = AT91_PIN_PC6, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio1", + }, + .active_low = 1, + }, + { + .name = "AP1_GPIO2", + .pin = { + .gpio = AT91_PIN_PC7, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio2", + } + }, + { + .name = "AP1_GPIO3", + .pin = { + .gpio = AT91_PIN_PC8, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio3", + } + }, + { + .name = "AP1_GPIO4", + .pin = { + .gpio = AT91_PIN_PC9, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio4", + } + }, + { + .name = "AP1_INTERRUPT1", + .pin = { + .gpio = AT91_PIN_PB14, + .flags = GPIOF_IN, + .label = "ap1-interrupt1", + } + }, + { + .name = "AP1_INTERRUPT2", + .pin = { + .gpio = AT91_PIN_PB15, + .flags = GPIOF_IN, + .label = "ap1-interrupt2", + } + }, + + // gpio pins for Accessory Card 2 + { + .name = "AP2_RESET", + .pin = { + .gpio = AT91_PIN_PB13, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "ap2-reset", + } + }, + { + .name = "AP2_GPIO1", + .pin = { + .gpio = AT91_PIN_PC20, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio1", + }, + .active_low = 1, + }, + { + .name = "AP2_GPIO2", + .pin = { + .gpio = AT91_PIN_PC21, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio2", + } + }, + { + .name = "AP2_GPIO3", + .pin = { + .gpio = AT91_PIN_PC22, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio3", + } + }, + { + .name = "AP2_GPIO4", + .pin = { + .gpio = AT91_PIN_PC23, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio4", + } + }, + { + .name = "AP2_INTERRUPT1", + .pin = { + .gpio = AT91_PIN_PB17, + .flags = GPIOF_IN, + .label = "ap2-interrupt1", + } + }, + { + .name = "AP2_INTERRUPT2", + .pin = { + .gpio = AT91_PIN_PB18, + .flags = GPIOF_IN, + .label = "ap2-interrupt2", + } + }, + { }, }; +static int mtr2d2_platform_attributes_size = 64; // not including NULL at end + static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_vendor_id.attr, &dev_attr_product_id.attr, @@ -207,6 +328,19 @@ static struct attribute *mtr2d2_platform_attributes[] = { NULL, // index 49 NULL, // index 50 NULL, // index 51 + NULL, // index 52 + NULL, // index 53 + NULL, // index 54 + NULL, // index 55 + NULL, // index 56 + NULL, // index 57 + NULL, // index 58 + NULL, // index 59 + NULL, // index 60 + NULL, // index 61 + NULL, // index 62 + NULL, // index 63 + NULL, // index 64 NULL, }; 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"); diff --git a/io-module/spi.c b/io-module/spi.c index dfbdfe2..df663ae 100644 --- a/io-module/spi.c +++ b/io-module/spi.c @@ -40,29 +40,32 @@ MODULE_PARM_DESC( "Maximum clock rate to be used with this device (default: 1 MHz)" ); -static struct spi_device *spi_dc_dout_dev; -static u8 spi_dc_dout_value; -static DEFINE_MUTEX(spi_dc_dout_mutex); -static unsigned int dc_dout_max_speed_hz = 1 * 1000 * 1000; -module_param(dc_dout_max_speed_hz, uint, S_IRUGO); +static struct spi_device *spi_ap1_dout_dev; +static struct spi_device *spi_ap2_dout_dev; +static u8 spi_ap_dout_value; +static DEFINE_MUTEX(spi_ap_dout_mutex); +static unsigned int ap_dout_max_speed_hz = 1 * 1000 * 1000; +module_param(ap_dout_max_speed_hz, uint, S_IRUGO); MODULE_PARM_DESC( - dc_dout_max_speed_hz, + ap_dout_max_speed_hz, "Maximum clock rate to be used with this device (default: 1 MHz)" ); -static struct spi_device *spi_dc_din_dev; -static unsigned int dc_din_max_speed_hz = 1 * 1000 * 1000; -module_param(dc_din_max_speed_hz, uint, S_IRUGO); +static struct spi_device *spi_ap1_din_dev; +static struct spi_device *spi_ap2_din_dev; +static unsigned int ap_din_max_speed_hz = 1 * 1000 * 1000; +module_param(ap_din_max_speed_hz, uint, S_IRUGO); MODULE_PARM_DESC( - dc_din_max_speed_hz, + ap_din_max_speed_hz, "Maximum clock rate to be used with this device (default: 1 MHz)" ); -static struct spi_device *spi_dc_adc_dev; -static unsigned int dc_adc_max_speed_hz = 20 * 1000 * 1000; -module_param(dc_adc_max_speed_hz, uint, S_IRUGO); +static struct spi_device *spi_ap1_adc_dev; +static struct spi_device *spi_ap2_adc_dev; +static unsigned int ap_adc_max_speed_hz = 20 * 1000 * 1000; +module_param(ap_adc_max_speed_hz, uint, S_IRUGO); MODULE_PARM_DESC( - dc_adc_max_speed_hz, + ap_adc_max_speed_hz, "Maximum clock rate to be used with this device (default: 20 MHz)" ); @@ -595,137 +598,270 @@ static struct spi_driver mts_spi_din_driver = { .remove = mts_spi_din_remove, }; -static int mts_spi_dc_dout_probe(struct spi_device *spi) +static int mts_spi_ap1_dout_probe(struct spi_device *spi) { int tmp; - if (! has_accessory_card_port_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { - log_error("accessory card digital outputs not available"); + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 1 digital outputs not available"); return -ENODEV; } - spi->max_speed_hz = dc_dout_max_speed_hz; + spi->max_speed_hz = ap_dout_max_speed_hz; spi->mode = 0; - log_debug("dc_dout_max_speed_hz: %d", dc_dout_max_speed_hz); + log_debug("ap1_dout_max_speed_hz: %d", ap_dout_max_speed_hz); tmp = spi_setup(spi); if (tmp < 0) { - log_error("spi_setup dc dout failed"); + log_error("spi_setup accessory card 1 dout failed"); return tmp; } - spi_dc_dout_value = 0x00; - spi_writen(spi, &spi_dc_dout_value, 1); + spi_ap_dout_value = 0x00; + spi_writen(spi, &spi_ap_dout_value, 1); - spi_dc_dout_dev = spi; + spi_ap1_dout_dev = spi; return 0; } -static int mts_spi_dc_dout_remove(struct spi_device *spi) +static int mts_spi_ap1_dout_remove(struct spi_device *spi) { - spi_dc_dout_dev = NULL; + spi_ap1_dout_dev = NULL; return 0; } -static struct spi_driver mts_spi_dc_dout_driver = { +static struct spi_driver mts_spi_ap1_dout_driver = { .driver = { - .name = "mts-io-dc-dout", + .name = "mts-io-ap1-dout", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = mts_spi_dc_dout_probe, - .remove = mts_spi_dc_dout_remove, + .probe = mts_spi_ap1_dout_probe, + .remove = mts_spi_ap1_dout_remove, }; -static int mts_spi_dc_din_probe(struct spi_device *spi) +static int mts_spi_ap1_din_probe(struct spi_device *spi) { int tmp; - if (! has_accessory_card_port_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { - log_error("accessory card digital inputs not available"); + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 1 digital inputs not available"); return -ENODEV; } - spi->max_speed_hz = dc_din_max_speed_hz; + spi->max_speed_hz = ap_din_max_speed_hz; spi->mode = SPI_CPOL; - log_debug("dc_din_max_speed_hz: %d", dc_din_max_speed_hz); + log_debug("ap1_din_max_speed_hz: %d", ap_din_max_speed_hz); tmp = spi_setup(spi); if (tmp < 0) { - log_error("spi_setup daughter card din failed"); + log_error("spi_setup accessory card 1 din failed"); return tmp; } - spi_dc_din_dev = spi; + spi_ap1_din_dev = spi; return 0; } -static int mts_spi_dc_din_remove(struct spi_device *spi) +static int mts_spi_ap1_din_remove(struct spi_device *spi) { - spi_dc_din_dev = NULL; + spi_ap1_din_dev = NULL; return 0; } -static struct spi_driver mts_spi_dc_din_driver = { +static struct spi_driver mts_spi_ap1_din_driver = { .driver = { - .name = "mts-io-dc-din", + .name = "mts-io-ap1-din", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = mts_spi_dc_din_probe, - .remove = mts_spi_dc_din_remove, + .probe = mts_spi_ap1_din_probe, + .remove = mts_spi_ap1_din_remove, }; -static int mts_spi_dc_adc_probe(struct spi_device *spi) +static int mts_spi_ap1_adc_probe(struct spi_device *spi) { int tmp; - if (! has_accessory_card_port_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { - log_error("accessory card analog to digital not available"); + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 1 analog to digital not available"); return -ENODEV; } - spi->max_speed_hz = dc_adc_max_speed_hz; + spi->max_speed_hz = ap_adc_max_speed_hz; spi->mode = 0; - log_debug("dc_adc_max_speed_hz: %d", dc_adc_max_speed_hz); - log_debug("dc_adc_mode: %d", spi->mode); + log_debug("ap1_adc_max_speed_hz: %d", ap_adc_max_speed_hz); + log_debug("ap1_adc_mode: %d", spi->mode); tmp = spi_setup(spi); if (tmp < 0) { - log_error("spi_setup daughter card adc failed"); + log_error("spi_setup accessory card 1 adc failed"); return tmp; } - spi_dc_adc_dev = spi; + spi_ap1_adc_dev = spi; return 0; } -static int mts_spi_dc_adc_remove(struct spi_device *spi) +static int mts_spi_ap1_adc_remove(struct spi_device *spi) { - spi_dc_adc_dev = NULL; + spi_ap1_adc_dev = NULL; return 0; } -static struct spi_driver mts_spi_dc_adc_driver = { +static struct spi_driver mts_spi_ap1_adc_driver = { .driver = { - .name = "mts-io-dc-adc", + .name = "mts-io-ap1-adc", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = mts_spi_dc_adc_probe, - .remove = mts_spi_dc_adc_remove, + .probe = mts_spi_ap1_adc_probe, + .remove = mts_spi_ap1_adc_remove, +}; + +static int mts_spi_ap2_dout_probe(struct spi_device *spi) +{ + int tmp; + + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 2 digital outputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = ap_dout_max_speed_hz; + spi->mode = 0; + + log_debug("ap2_dout_max_speed_hz: %d", ap_dout_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup accessory card 2 dout failed"); + return tmp; + } + + spi_ap_dout_value = 0x00; + spi_writen(spi, &spi_ap_dout_value, 2); + + spi_ap2_dout_dev = spi; + + return 0; +} + +static int mts_spi_ap2_dout_remove(struct spi_device *spi) +{ + spi_ap2_dout_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_ap2_dout_driver = { + .driver = { + .name = "mts-io-ap2-dout", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_ap2_dout_probe, + .remove = mts_spi_ap2_dout_remove, +}; + +static int mts_spi_ap2_din_probe(struct spi_device *spi) +{ + int tmp; + + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 2 digital inputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = ap_din_max_speed_hz; + spi->mode = SPI_CPOL; + + log_debug("ap2_din_max_speed_hz: %d", ap_din_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup accessory card 2 din failed"); + return tmp; + } + + spi_ap2_din_dev = spi; + + return 0; +} + +static int mts_spi_ap2_din_remove(struct spi_device *spi) +{ + spi_ap2_din_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_ap2_din_driver = { + .driver = { + .name = "mts-io-ap2-din", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_ap2_din_probe, + .remove = mts_spi_ap2_din_remove, +}; + +static int mts_spi_ap2_adc_probe(struct spi_device *spi) +{ + int tmp; + + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 2 analog to digital not available"); + return -ENODEV; + } + + spi->max_speed_hz = ap_adc_max_speed_hz; + spi->mode = 0; + + log_debug("ap2_adc_max_speed_hz: %d", ap_adc_max_speed_hz); + log_debug("ap2_adc_mode: %d", spi->mode); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup accessory card 2 adc failed"); + return tmp; + } + + spi_ap2_adc_dev = spi; + + return 0; +} + +static int mts_spi_ap2_adc_remove(struct spi_device *spi) +{ + spi_ap2_adc_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_ap2_adc_driver = { + .driver = { + .name = "mts-io-ap2-adc", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_ap2_adc_probe, + .remove = mts_spi_ap2_adc_remove, }; static int mts_spi_board_temp_probe(struct spi_device *spi) -- cgit v1.2.3 From fc543eac11fbeb87fe226b8f7921725c4139bb33 Mon Sep 17 00:00:00 2001 From: Jesse Gilles Date: Thu, 4 Sep 2014 13:35:32 -0500 Subject: mtr2d2: fix reset pins, update LEDs, add AP GPS_PPS pins --- io-module/mtr2d2.c | 70 +++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/io-module/mtr2d2.c b/io-module/mtr2d2.c index b2fc03f..0926952 100644 --- a/io-module/mtr2d2.c +++ b/io-module/mtr2d2.c @@ -3,7 +3,7 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { { .name = "RADIO_RESET", .pin = { - .gpio = AT91_PIN_PC5, + .gpio = AT91_PIN_PC3, .flags = GPIOF_OUT_INIT_HIGH, .label = "radio-reset", }, @@ -11,7 +11,7 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { { .name = "RADIO_RESET", .pin = { - .gpio = AT91_PIN_PC5, + .gpio = AT91_PIN_PC3, .flags = GPIOF_OUT_INIT_HIGH, .label = "radio-power", }, @@ -19,14 +19,14 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { { .name = "DEVICE_RESET", .pin = { - .gpio = AT91_PIN_PC4, + .gpio = AT91_PIN_PC2, .flags = GPIOF_IN, .label = "reset", }, .active_low = 1, }, { - .name = "LS_LED", + .name = "LS_LED", /* LED7 */ .pin = { .gpio = AT91_PIN_PA14, #if LED_LS_CONTROLLABLE @@ -39,7 +39,7 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .active_low = 1, }, { - .name = "STATUS_LED", + .name = "STATUS_LED", /* LED2 */ .pin = { .gpio = AT91_PIN_PA24, .flags = GPIOF_OUT_INIT_LOW, @@ -57,7 +57,7 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .active_low = 1, }, { - .name = "LED7", + .name = "LED5", .pin = { .gpio = AT91_PIN_PA25, .flags = GPIOF_OUT_INIT_HIGH, @@ -66,16 +66,16 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .active_low = 1, }, { - .name = "LED7", + .name = "LED5", .pin = { .gpio = AT91_PIN_PA25, .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-c", + .label = "led-b", }, .active_low = 1, }, { - .name = "LED10", + .name = "LED1", .pin = { .gpio = AT91_PIN_PA26, .flags = GPIOF_OUT_INIT_HIGH, @@ -84,16 +84,16 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .active_low = 1, }, { - .name = "LED10", + .name = "LED1", .pin = { .gpio = AT91_PIN_PA26, .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-d", + .label = "led-c", }, .active_low = 1, }, { - .name = "LED11", + .name = "LED4", .pin = { .gpio = AT91_PIN_PA27, .flags = GPIOF_OUT_INIT_HIGH, @@ -102,16 +102,16 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .active_low = 1, }, { - .name = "LED11", + .name = "LED4", .pin = { .gpio = AT91_PIN_PA27, .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-e", + .label = "led-d", }, .active_low = 1, }, { - .name = "LED12", + .name = "LED3", .pin = { .gpio = AT91_PIN_PA28, .flags = GPIOF_OUT_INIT_HIGH, @@ -120,29 +120,11 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .active_low = 1, }, { - .name = "LED12", + .name = "LED3", .pin = { .gpio = AT91_PIN_PA28, .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-f", - }, - .active_low = 1, - }, - { - .name = "LED13", - .pin = { - .gpio = AT91_PIN_PA29, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-wifi", - }, - .active_low = 1, - }, - { - .name = "LED13", - .pin = { - .gpio = AT91_PIN_PA29, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-b", + .label = "led-e", }, .active_low = 1, }, @@ -205,6 +187,14 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .label = "ap1-interrupt2", } }, + { + .name = "AP1_GPS_PPS", + .pin = { + .gpio = AT91_PIN_PA29, + .flags = GPIOF_IN, + .label = "ap1-gps-pps", + } + }, // gpio pins for Accessory Card 2 { @@ -264,6 +254,14 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { .label = "ap2-interrupt2", } }, + { + .name = "AP2_GPS_PPS", + .pin = { + .gpio = AT91_PIN_PA6, + .flags = GPIOF_IN, + .label = "ap2-gps-pps", + } + }, { }, }; @@ -283,7 +281,6 @@ static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_radio_reset.attr, &dev_attr_led_status.attr, - &dev_attr_led_wifi_gpio.attr, &dev_attr_led_cd_gpio.attr, &dev_attr_led_sig1_gpio.attr, &dev_attr_led_sig2_gpio.attr, @@ -294,7 +291,6 @@ static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_led_c_gpio.attr, &dev_attr_led_d_gpio.attr, &dev_attr_led_e_gpio.attr, - &dev_attr_led_f_gpio.attr, &dev_attr_board_temperature.attr, -- cgit v1.2.3 From 5503d316c26d664117ff899c0dece6efc5ea7077 Mon Sep 17 00:00:00 2001 From: Jesse Gilles Date: Thu, 4 Sep 2014 13:38:01 -0500 Subject: add support for MTAC-MFSER --- io-module/mtac_mfser.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++ io-module/mts_io.c | 35 +++++++- io-module/mts_io.h | 2 + 3 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 io-module/mtac_mfser.c diff --git a/io-module/mtac_mfser.c b/io-module/mtac_mfser.c new file mode 100644 index 0000000..14eddd1 --- /dev/null +++ b/io-module/mtac_mfser.c @@ -0,0 +1,215 @@ +struct gpio_pin *ap_mfser_pin_by_attr_name(const char *name) { + struct gpio_pin *pin; + char *pin_attr_name; + + if (!strcmp(name, "rs4xx-term-res:0")) { + pin_attr_name = "ap1-gpio3"; + } else if (!strcmp(name, "rts-override:0")) { + pin_attr_name = "ap1-gpio4"; + } else if (!strcmp(name, "rs4xx-term-res:1")) { + pin_attr_name = "ap2-gpio3"; + } else if (!strcmp(name, "rts-override:1")) { + pin_attr_name = "ap2-gpio4"; + } else { + log_error("accessory card attribute %s not available", name); + return NULL; + } + + for (pin = gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->pin.label, pin_attr_name)) { + return pin; + } + } + + log_error("pin with attr name %s not found", name); + + return NULL; +} + + +static ssize_t mts_attr_show_ap_mfser_pin(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int value; + struct gpio_pin *pin = ap_mfser_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + mutex_lock(&mts_io_mutex); + + value = gpio_get_value(pin->pin.gpio); + + mutex_unlock(&mts_io_mutex); + + if (value < 0) { + return value; + } + + if (pin->active_low) { + value = !value; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t mts_attr_store_ap_mfser_pin(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + struct gpio_pin *pin = ap_mfser_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + if (sscanf(buf, "%i", &value) != 1) { + return -EINVAL; + } + + if (pin->active_low) { + value = !value; + } + + mutex_lock(&mts_io_mutex); + + gpio_set_value(pin->pin.gpio, value); + + mutex_unlock(&mts_io_mutex); + + return count; +} + +static ssize_t mts_attr_show_mfser_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + int modesel0; + int modesel1; + + struct gpio_pin *pin_modesel0; + struct gpio_pin *pin_modesel1; + + if (strstr(attr->attr.name, ":0")) { + pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); + } + else if (strstr(attr->attr.name, ":1")) { + pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); + } + else { + log_error("unknown serial-mode attr %s", attr->attr.name); + return -ENODEV; + } + + if (!pin_modesel0 || !pin_modesel1) + return -ENODEV; + + mutex_lock(&mts_io_mutex); + + modesel0 = gpio_get_value(pin_modesel0->pin.gpio); + modesel1 = gpio_get_value(pin_modesel1->pin.gpio); + + if (modesel1 == 0 && modesel0 == 0) + ret = sprintf(buf, "loopback\n"); + else if (modesel1 == 0 && modesel0 == 1) + ret = sprintf(buf, "rs232\n"); + else if (modesel1 == 1 && modesel0 == 0) + ret = sprintf(buf, "rs485-half\n"); + else if (modesel1 == 1 && modesel0 == 1) + ret = sprintf(buf, "rs422-485-full\n"); + else + ret = sprintf(buf, "error\n"); + + mutex_unlock(&mts_io_mutex); + + return ret; +} + +static ssize_t mts_attr_store_mfser_mode(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int modesel0; + int modesel1; + struct gpio_pin *pin_modesel0; + struct gpio_pin *pin_modesel1; + + if (strstr(attr->attr.name, ":0")) { + pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); + } + else if (strstr(attr->attr.name, ":1")) { + pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); + } + else { + log_error("unknown serial-mode attr %s", attr->attr.name); + return -ENODEV; + } + + if (!pin_modesel0 || !pin_modesel1) + return -ENODEV; + + if (!strcasecmp(buf, "loopback")) { + modesel1 = 0; + modesel0 = 0; + } + else if (!strcasecmp(buf, "rs232")) { + modesel1 = 0; + modesel0 = 1; + } + else if (!strcasecmp(buf, "rs485-half")) { + modesel1 = 1; + modesel0 = 0; + } + else if (!strcasecmp(buf, "rs422-485-full")) { + modesel1 = 1; + modesel0 = 1; + } + else { + return -EINVAL; + } + + mutex_lock(&mts_io_mutex); + + gpio_set_value(pin_modesel0->pin.gpio, modesel0); + gpio_set_value(pin_modesel1->pin.gpio, modesel1); + + mutex_unlock(&mts_io_mutex); + + return count; +} + +/* accessory port 1 serial attributes */ +static DEVICE_ATTR_MTS(dev_attr_ap1_serial_mode, "serial-mode:0", mts_attr_show_mfser_mode, mts_attr_store_mfser_mode); +static DEVICE_ATTR_MTS(dev_attr_ap1_rs4xx_term_res, "rs4xx-term-res:0", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_rts_override, "rts-override:0", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); + +static int ap1_mfser_attributes_size = 3; // not including NULL at end + +static struct attribute *ap1_mfser_attributes[] = { + &dev_attr_ap1_serial_mode.attr, + &dev_attr_ap1_rs4xx_term_res.attr, // gpio3 + &dev_attr_ap1_rts_override.attr, // gpio4 + NULL, +}; + +/* accessory port 2 serial attributes */ +static DEVICE_ATTR_MTS(dev_attr_ap2_serial_mode, "serial-mode:1", mts_attr_show_mfser_mode, mts_attr_store_mfser_mode); +static DEVICE_ATTR_MTS(dev_attr_ap2_rs4xx_term_res, "rs4xx-term-res:1", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_rts_override, "rts-override:1", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); + +static int ap2_mfser_attributes_size = 3; // not including NULL at end + +static struct attribute *ap2_mfser_attributes[] = { + &dev_attr_ap2_serial_mode.attr, + &dev_attr_ap2_rs4xx_term_res.attr, // gpio3 + &dev_attr_ap2_rts_override.attr, // gpio4 + NULL, +}; + + diff --git a/io-module/mts_io.c b/io-module/mts_io.c index b63a756..2ecc636 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -99,6 +99,7 @@ static DEFINE_MUTEX(mts_io_mutex); /* accessory card support */ #include "mtdc_gpiob.c" +#include "mtac_mfser.c" /* telit radio reset handling */ #include "telit_radio.c" @@ -440,6 +441,10 @@ static bool add_accessory_card_attributes(int slot) 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; @@ -450,6 +455,10 @@ static bool add_accessory_card_attributes(int slot) 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; @@ -715,7 +724,10 @@ static int __init mts_io_init(void) // 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 (...) { } + } + 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 MTDC_GPIOB_0_0: @@ -747,6 +759,14 @@ static int __init mts_io_init(void) 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); @@ -757,7 +777,10 @@ static int __init mts_io_init(void) // 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 (...) { } + } + 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 MTDC_GPIOB_0_0: @@ -789,6 +812,14 @@ static int __init mts_io_init(void) 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); diff --git a/io-module/mts_io.h b/io-module/mts_io.h index cff0b2a..c76471c 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -49,6 +49,7 @@ struct device_attribute _dev_name = { \ #define PRODUCT_ID_MTR2D2 "MTR2D2" #define PRODUCT_ID_MTDC_GPIOB "MTDC-GPIOB" +#define PRODUCT_ID_MTAC_MFSER "MTAC-MFSER" #define PRODUCT_ID_MTDC_ETH "MTDC-ETH" #define HW_VERSION_MTCBA2_2_0 "MTCBA2-2.0" @@ -79,6 +80,7 @@ enum { enum { MTDC_NONE, MTDC_GPIOB_0_0, + MTAC_MFSER_0_0, }; // GPIO pin types:input, output, open drain (1 = high Z, 0 = output low) -- cgit v1.2.3 From 64d8ebafbf55fa4a4547184bfbdc73ad43eb6a4c Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 10 Sep 2014 11:26:03 -0500 Subject: rename mtdc_gpiob.c to mtac_gpiob.c --- io-module/mtac_gpiob.c | 409 +++++++++++++++++++++++++++++++++++++++++++++++++ io-module/mtdc_gpiob.c | 409 ------------------------------------------------- 2 files changed, 409 insertions(+), 409 deletions(-) create mode 100644 io-module/mtac_gpiob.c delete mode 100644 io-module/mtdc_gpiob.c diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c new file mode 100644 index 0000000..5a592b7 --- /dev/null +++ b/io-module/mtac_gpiob.c @@ -0,0 +1,409 @@ +struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { + struct gpio_pin *pin; + char *pin_attr_name; + + if (!strcmp(name, "ap1-led1")) { + pin_attr_name = "ap1-gpio3"; + } else if (!strcmp(name, "ap1-led2")) { + pin_attr_name = "ap1-gpio4"; + } else if (!strcmp(name, "ap1-dout-enable")) { + pin_attr_name = "ap1-gpio1"; + } else if (!strcmp(name, "ap1-reset")) { + pin_attr_name = "ap1-reset"; + } else if (!strcmp(name, "ap2-led1")) { + pin_attr_name = "ap2-gpio3"; + } else if (!strcmp(name, "ap2-led2")) { + pin_attr_name = "ap2-gpio4"; + } else if (!strcmp(name, "ap2-dout-enable")) { + pin_attr_name = "ap2-gpio1"; + } else if (!strcmp(name, "ap2-reset")) { + pin_attr_name = "ap2-reset"; + } else { + log_error("accessory card attribute %s not available", name); + return NULL; + } + + for (pin = gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->pin.label, pin_attr_name)) { + return pin; + } + } + + log_error("pin with attr name %s not found", name); + + return NULL; +} + + +static ssize_t mts_attr_show_ap_gpio_pin(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int value; + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + mutex_lock(&mts_io_mutex); + + value = gpio_get_value(pin->pin.gpio); + + mutex_unlock(&mts_io_mutex); + + if (value < 0) { + return value; + } + + if (pin->active_low) { + value = !value; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t mts_attr_store_ap_gpio_pin(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + if (sscanf(buf, "%i", &value) != 1) { + return -EINVAL; + } + + if (pin->active_low) { + value = !value; + } + + mutex_lock(&mts_io_mutex); + + gpio_set_value(pin->pin.gpio, value); + + mutex_unlock(&mts_io_mutex); + + return count; +} + +static ssize_t mts_attr_show_ap_din(struct device *dev, struct device_attribute *attr, char *buf) +{ + int tmp; + u8 bit; + u8 byte; + struct spi_device* spi_dev; + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_din_dev) { + log_error("accessory card 1 din device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_din_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_din_dev) { + log_error("accessory card 2 din device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_din_dev; + } else { + log_error("unknown din device %s", attr->attr.name); + return -ENODEV; + } + + if (strstr(attr->attr.name, "din0")) { + bit = BIT(0); + } else if (strstr(attr->attr.name, "din1")) { + bit = BIT(1); + } else if (strstr(attr->attr.name, "din2")) { + bit = BIT(2); + } else if (strstr(attr->attr.name, "din3")) { + bit = BIT(3); + } else { + log_error("accessory card din attr does not exist"); + return -ENOENT; + } + + tmp = spi_readn(spi_dev, &byte, 1); + if (tmp) { + log_error("spi_read failed %d", tmp); + return tmp; + } + + tmp = byte & bit ? 1 : 0; + + return sprintf(buf, "%d\n", tmp); +} + +static ssize_t mts_attr_store_ap_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + u8 bit; + struct spi_device* spi_dev; + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_dout_dev) { + log_error("accessory card 1 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_dout_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_dout_dev) { + log_error("accessory card 2 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_dout_dev; + } else { + log_error("unknown dout device %s", attr->attr.name); + return -ENODEV; + } + + if (strstr(attr->attr.name, "dout0")) { + bit = BIT(0); + } else if (strstr(attr->attr.name, "dout1")) { + bit = BIT(1); + } else if (strstr(attr->attr.name, "dout2")) { + bit = BIT(2); + } else if (strstr(attr->attr.name, "dout3")) { + bit = BIT(3); + } else { + log_error("accessory card dout attr does not exist"); + return -ENOENT; + } + + if (sscanf(buf, "%i", &value) != 1) { + log_error("accessory card dout attr invalid argument"); + return -EINVAL; + } + + mutex_lock(&spi_ap_dout_mutex); + + if (value) { + spi_ap_dout_value &= ~bit; + } else { + spi_ap_dout_value |= bit; + } + + spi_writen(spi_dev, &spi_ap_dout_value, 1); + + mutex_unlock(&spi_ap_dout_mutex); + + return count; +} + +static ssize_t mts_attr_show_ap_dout(struct device *dev, struct device_attribute *attr, char *buf) +{ + int value; + u8 bit; + struct spi_device* spi_dev; + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_dout_dev) { + log_error("accessory card 1 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_dout_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_dout_dev) { + log_error("accessory card 2 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_dout_dev; + } else { + log_error("unknown dout device %s", attr->attr.name); + return -ENODEV; + } + + if (strstr(attr->attr.name, "dout0")) { + bit = BIT(0); + } else if (strstr(attr->attr.name, "dout1")) { + bit = BIT(1); + } else if (strstr(attr->attr.name, "dout2")) { + bit = BIT(2); + } else if (strstr(attr->attr.name, "dout3")) { + bit = BIT(3); + } else { + log_error("accessory card dout attr does not exist"); + return -ENOENT; + } + + mutex_lock(&spi_ap_dout_mutex); + + value = spi_ap_dout_value & bit ? 0 : 1; + + mutex_unlock(&spi_ap_dout_mutex); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute *attr, char *buf) +{ + int tmp; + int tx_data; + int rx_data; + int channel; + int channel_mask = 0x0180; /* 0b 0000 0001 1000 0000 */ + int manual_mode = 0x1840; /* 0b 0001 1000 0100 0000 */ + uint8_t tx[2]; + uint8_t rx[2]; + struct spi_device* spi_dev; + + memset(tx, 0, sizeof(tx)); + memset(rx, 0, sizeof(rx)); + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_adc_dev) { + log_error("accessory card 1 adc device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_adc_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_adc_dev) { + log_error("accessory card 2 adc device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_adc_dev; + } else { + log_error("unknown adc device %s", attr->attr.name); + return -ENODEV; + } + + if (strstr(attr->attr.name, "adc0")) { + channel = 0; + } else if (strstr(attr->attr.name, "adc1")) { + channel = 1; + } else if (strstr(attr->attr.name, "adc2")) { + channel = 2; + } else { + log_error("accessory card adc attr does not exist"); + return -ENOENT; + } + + /* 1st transfer to set up (5V reference, channel to read from) */ + tx_data = manual_mode | ((channel << 7) & channel_mask); + tx[0] = tx_data >> 8; + tx[1] = tx_data & 0xFF; + tmp = spi_writen(spi_dev, tx, 2); + if (tmp) { + log_error("spi_write failed %d", tmp); + return tmp; + } + + /* 2nd transfer to clock chip for ADC conversion + * this can be a throw-away read or an empty write, + * the ADC just needs the clock running so it can convert */ + tx[0] = 0; + tx[1] = 0; + tmp = spi_writen(spi_dev, tx, 2); + if (tmp) { + log_error("2nd spi_write failed %d", tmp); + return tmp; + } + + /* 3rd transfer to read data */ + tmp = spi_readn(spi_dev, rx, 2); + if (tmp) { + log_error("spi_read failed %d", tmp); + return tmp; + } + rx_data = ((rx[0] & 0x0F) << 8) | (rx[1] & 0xFF); + + return sprintf(buf, "%lu\n", (unsigned long) rx_data); +} + +/* accessory port 1 gpiob attributes */ +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din0, "din0:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din1, "din1:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din2, "din2:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din3, "din3:0", mts_attr_show_ap_din); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout0, "dout0:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout1, "dout1:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout2, "dout2:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout3, "dout3:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc0, "adc0:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc1, "adc1:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc2, "adc2:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led1, "ap1-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led2, "ap1-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_oe, "ap1-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_reset, "ap1-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); + +static int ap1_gpio_attributes_size = 15; // not including NULL at end + +static struct attribute *ap1_gpio_attributes[] = { + &dev_attr_ap1_reset.attr, + + &dev_attr_ap1_gpio_oe.attr, // gpio1 + &dev_attr_ap1_gpio_led1.attr, // gpio3 + &dev_attr_ap1_gpio_led2.attr, // gpio4 + + &dev_attr_ap1_gpio_din0.attr, + &dev_attr_ap1_gpio_din1.attr, + &dev_attr_ap1_gpio_din2.attr, + &dev_attr_ap1_gpio_din3.attr, + + &dev_attr_ap1_gpio_dout0.attr, + &dev_attr_ap1_gpio_dout1.attr, + &dev_attr_ap1_gpio_dout2.attr, + &dev_attr_ap1_gpio_dout3.attr, + + &dev_attr_ap1_gpio_adc0.attr, + &dev_attr_ap1_gpio_adc1.attr, + &dev_attr_ap1_gpio_adc2.attr, + + NULL, +}; + +/* accessory port 2 gpiob attributes */ +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din0, "din0:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din1, "din1:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din2, "din2:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din3, "din3:1", mts_attr_show_ap_din); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout0, "dout0:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout1, "dout1:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout2, "dout2:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout3, "dout3:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc0, "adc0:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc1, "adc1:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc2, "adc2:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led1, "ap2-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led2, "ap2-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_oe, "ap2-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_reset, "ap2-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); + +static int ap2_gpio_attributes_size = 15; // not including NULL at end + +static struct attribute *ap2_gpio_attributes[] = { + &dev_attr_ap2_reset.attr, + + &dev_attr_ap2_gpio_oe.attr, // gpio1 + &dev_attr_ap2_gpio_led1.attr, // gpio3 + &dev_attr_ap2_gpio_led2.attr, // gpio4 + + &dev_attr_ap2_gpio_din0.attr, + &dev_attr_ap2_gpio_din1.attr, + &dev_attr_ap2_gpio_din2.attr, + &dev_attr_ap2_gpio_din3.attr, + + &dev_attr_ap2_gpio_dout0.attr, + &dev_attr_ap2_gpio_dout1.attr, + &dev_attr_ap2_gpio_dout2.attr, + &dev_attr_ap2_gpio_dout3.attr, + + &dev_attr_ap2_gpio_adc0.attr, + &dev_attr_ap2_gpio_adc1.attr, + &dev_attr_ap2_gpio_adc2.attr, + + NULL, +}; diff --git a/io-module/mtdc_gpiob.c b/io-module/mtdc_gpiob.c deleted file mode 100644 index 5a592b7..0000000 --- a/io-module/mtdc_gpiob.c +++ /dev/null @@ -1,409 +0,0 @@ -struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { - struct gpio_pin *pin; - char *pin_attr_name; - - if (!strcmp(name, "ap1-led1")) { - pin_attr_name = "ap1-gpio3"; - } else if (!strcmp(name, "ap1-led2")) { - pin_attr_name = "ap1-gpio4"; - } else if (!strcmp(name, "ap1-dout-enable")) { - pin_attr_name = "ap1-gpio1"; - } else if (!strcmp(name, "ap1-reset")) { - pin_attr_name = "ap1-reset"; - } else if (!strcmp(name, "ap2-led1")) { - pin_attr_name = "ap2-gpio3"; - } else if (!strcmp(name, "ap2-led2")) { - pin_attr_name = "ap2-gpio4"; - } else if (!strcmp(name, "ap2-dout-enable")) { - pin_attr_name = "ap2-gpio1"; - } else if (!strcmp(name, "ap2-reset")) { - pin_attr_name = "ap2-reset"; - } else { - log_error("accessory card attribute %s not available", name); - return NULL; - } - - for (pin = gpio_pins; *pin->name; pin++) { - if (!strcmp(pin->pin.label, pin_attr_name)) { - return pin; - } - } - - log_error("pin with attr name %s not found", name); - - return NULL; -} - - -static ssize_t mts_attr_show_ap_gpio_pin(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int value; - struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); - - if (!pin) { - return -ENODEV; - } - - mutex_lock(&mts_io_mutex); - - value = gpio_get_value(pin->pin.gpio); - - mutex_unlock(&mts_io_mutex); - - if (value < 0) { - return value; - } - - if (pin->active_low) { - value = !value; - } - - return sprintf(buf, "%d\n", value); -} - -static ssize_t mts_attr_store_ap_gpio_pin(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int value; - struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); - - if (!pin) { - return -ENODEV; - } - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - - if (pin->active_low) { - value = !value; - } - - mutex_lock(&mts_io_mutex); - - gpio_set_value(pin->pin.gpio, value); - - mutex_unlock(&mts_io_mutex); - - return count; -} - -static ssize_t mts_attr_show_ap_din(struct device *dev, struct device_attribute *attr, char *buf) -{ - int tmp; - u8 bit; - u8 byte; - struct spi_device* spi_dev; - - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_din_dev) { - log_error("accessory card 1 din device not present"); - return -ENODEV; - } - - spi_dev = spi_ap1_din_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_din_dev) { - log_error("accessory card 2 din device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_din_dev; - } else { - log_error("unknown din device %s", attr->attr.name); - return -ENODEV; - } - - if (strstr(attr->attr.name, "din0")) { - bit = BIT(0); - } else if (strstr(attr->attr.name, "din1")) { - bit = BIT(1); - } else if (strstr(attr->attr.name, "din2")) { - bit = BIT(2); - } else if (strstr(attr->attr.name, "din3")) { - bit = BIT(3); - } else { - log_error("accessory card din attr does not exist"); - return -ENOENT; - } - - tmp = spi_readn(spi_dev, &byte, 1); - if (tmp) { - log_error("spi_read failed %d", tmp); - return tmp; - } - - tmp = byte & bit ? 1 : 0; - - return sprintf(buf, "%d\n", tmp); -} - -static ssize_t mts_attr_store_ap_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int value; - u8 bit; - struct spi_device* spi_dev; - - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_dout_dev) { - log_error("accessory card 1 dout device not present"); - return -ENODEV; - } - - spi_dev = spi_ap1_dout_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_dout_dev) { - log_error("accessory card 2 dout device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_dout_dev; - } else { - log_error("unknown dout device %s", attr->attr.name); - return -ENODEV; - } - - if (strstr(attr->attr.name, "dout0")) { - bit = BIT(0); - } else if (strstr(attr->attr.name, "dout1")) { - bit = BIT(1); - } else if (strstr(attr->attr.name, "dout2")) { - bit = BIT(2); - } else if (strstr(attr->attr.name, "dout3")) { - bit = BIT(3); - } else { - log_error("accessory card dout attr does not exist"); - return -ENOENT; - } - - if (sscanf(buf, "%i", &value) != 1) { - log_error("accessory card dout attr invalid argument"); - return -EINVAL; - } - - mutex_lock(&spi_ap_dout_mutex); - - if (value) { - spi_ap_dout_value &= ~bit; - } else { - spi_ap_dout_value |= bit; - } - - spi_writen(spi_dev, &spi_ap_dout_value, 1); - - mutex_unlock(&spi_ap_dout_mutex); - - return count; -} - -static ssize_t mts_attr_show_ap_dout(struct device *dev, struct device_attribute *attr, char *buf) -{ - int value; - u8 bit; - struct spi_device* spi_dev; - - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_dout_dev) { - log_error("accessory card 1 dout device not present"); - return -ENODEV; - } - - spi_dev = spi_ap1_dout_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_dout_dev) { - log_error("accessory card 2 dout device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_dout_dev; - } else { - log_error("unknown dout device %s", attr->attr.name); - return -ENODEV; - } - - if (strstr(attr->attr.name, "dout0")) { - bit = BIT(0); - } else if (strstr(attr->attr.name, "dout1")) { - bit = BIT(1); - } else if (strstr(attr->attr.name, "dout2")) { - bit = BIT(2); - } else if (strstr(attr->attr.name, "dout3")) { - bit = BIT(3); - } else { - log_error("accessory card dout attr does not exist"); - return -ENOENT; - } - - mutex_lock(&spi_ap_dout_mutex); - - value = spi_ap_dout_value & bit ? 0 : 1; - - mutex_unlock(&spi_ap_dout_mutex); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute *attr, char *buf) -{ - int tmp; - int tx_data; - int rx_data; - int channel; - int channel_mask = 0x0180; /* 0b 0000 0001 1000 0000 */ - int manual_mode = 0x1840; /* 0b 0001 1000 0100 0000 */ - uint8_t tx[2]; - uint8_t rx[2]; - struct spi_device* spi_dev; - - memset(tx, 0, sizeof(tx)); - memset(rx, 0, sizeof(rx)); - - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_adc_dev) { - log_error("accessory card 1 adc device not present"); - return -ENODEV; - } - - spi_dev = spi_ap1_adc_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_adc_dev) { - log_error("accessory card 2 adc device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_adc_dev; - } else { - log_error("unknown adc device %s", attr->attr.name); - return -ENODEV; - } - - if (strstr(attr->attr.name, "adc0")) { - channel = 0; - } else if (strstr(attr->attr.name, "adc1")) { - channel = 1; - } else if (strstr(attr->attr.name, "adc2")) { - channel = 2; - } else { - log_error("accessory card adc attr does not exist"); - return -ENOENT; - } - - /* 1st transfer to set up (5V reference, channel to read from) */ - tx_data = manual_mode | ((channel << 7) & channel_mask); - tx[0] = tx_data >> 8; - tx[1] = tx_data & 0xFF; - tmp = spi_writen(spi_dev, tx, 2); - if (tmp) { - log_error("spi_write failed %d", tmp); - return tmp; - } - - /* 2nd transfer to clock chip for ADC conversion - * this can be a throw-away read or an empty write, - * the ADC just needs the clock running so it can convert */ - tx[0] = 0; - tx[1] = 0; - tmp = spi_writen(spi_dev, tx, 2); - if (tmp) { - log_error("2nd spi_write failed %d", tmp); - return tmp; - } - - /* 3rd transfer to read data */ - tmp = spi_readn(spi_dev, rx, 2); - if (tmp) { - log_error("spi_read failed %d", tmp); - return tmp; - } - rx_data = ((rx[0] & 0x0F) << 8) | (rx[1] & 0xFF); - - return sprintf(buf, "%lu\n", (unsigned long) rx_data); -} - -/* accessory port 1 gpiob attributes */ -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din0, "din0:0", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din1, "din1:0", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din2, "din2:0", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din3, "din3:0", mts_attr_show_ap_din); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout0, "dout0:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout1, "dout1:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout2, "dout2:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout3, "dout3:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc0, "adc0:0", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc1, "adc1:0", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc2, "adc2:0", mts_attr_show_ap_adc); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led1, "ap1-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led2, "ap1-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_oe, "ap1-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap1_reset, "ap1-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); - -static int ap1_gpio_attributes_size = 15; // not including NULL at end - -static struct attribute *ap1_gpio_attributes[] = { - &dev_attr_ap1_reset.attr, - - &dev_attr_ap1_gpio_oe.attr, // gpio1 - &dev_attr_ap1_gpio_led1.attr, // gpio3 - &dev_attr_ap1_gpio_led2.attr, // gpio4 - - &dev_attr_ap1_gpio_din0.attr, - &dev_attr_ap1_gpio_din1.attr, - &dev_attr_ap1_gpio_din2.attr, - &dev_attr_ap1_gpio_din3.attr, - - &dev_attr_ap1_gpio_dout0.attr, - &dev_attr_ap1_gpio_dout1.attr, - &dev_attr_ap1_gpio_dout2.attr, - &dev_attr_ap1_gpio_dout3.attr, - - &dev_attr_ap1_gpio_adc0.attr, - &dev_attr_ap1_gpio_adc1.attr, - &dev_attr_ap1_gpio_adc2.attr, - - NULL, -}; - -/* accessory port 2 gpiob attributes */ -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din0, "din0:1", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din1, "din1:1", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din2, "din2:1", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din3, "din3:1", mts_attr_show_ap_din); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout0, "dout0:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout1, "dout1:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout2, "dout2:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout3, "dout3:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc0, "adc0:1", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc1, "adc1:1", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc2, "adc2:1", mts_attr_show_ap_adc); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led1, "ap2-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led2, "ap2-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_oe, "ap2-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap2_reset, "ap2-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); - -static int ap2_gpio_attributes_size = 15; // not including NULL at end - -static struct attribute *ap2_gpio_attributes[] = { - &dev_attr_ap2_reset.attr, - - &dev_attr_ap2_gpio_oe.attr, // gpio1 - &dev_attr_ap2_gpio_led1.attr, // gpio3 - &dev_attr_ap2_gpio_led2.attr, // gpio4 - - &dev_attr_ap2_gpio_din0.attr, - &dev_attr_ap2_gpio_din1.attr, - &dev_attr_ap2_gpio_din2.attr, - &dev_attr_ap2_gpio_din3.attr, - - &dev_attr_ap2_gpio_dout0.attr, - &dev_attr_ap2_gpio_dout1.attr, - &dev_attr_ap2_gpio_dout2.attr, - &dev_attr_ap2_gpio_dout3.attr, - - &dev_attr_ap2_gpio_adc0.attr, - &dev_attr_ap2_gpio_adc1.attr, - &dev_attr_ap2_gpio_adc2.attr, - - NULL, -}; -- cgit v1.2.3 From 24c012065ca7a764e1e51a9cfc4422d649cd2851 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 10 Sep 2014 11:55:38 -0500 Subject: rename all "mtdc_*" variables to "mtac_*" --- io-module/mts_io.c | 34 +++++++++++++++++----------------- io-module/mts_io.h | 8 ++++---- io-module/spi.c | 12 ++++++------ 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 2ecc636..9adfd12 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -98,7 +98,7 @@ static DEFINE_MUTEX(mts_io_mutex); #include "spi.c" /* accessory card support */ -#include "mtdc_gpiob.c" +#include "mtac_gpiob.c" #include "mtac_mfser.c" /* telit radio reset handling */ @@ -437,7 +437,7 @@ static bool add_accessory_card_attributes(int slot) if (slot == 1) { switch (mts_ap1_product_id) { - case MTDC_GPIOB_0_0: + case MTAC_GPIOB_0_0: card_attrs_size = ap1_gpio_attributes_size; card_attrs = ap1_gpio_attributes; break; @@ -451,7 +451,7 @@ static bool add_accessory_card_attributes(int slot) } } else if (slot == 2) { switch (mts_ap2_product_id) { - case MTDC_GPIOB_0_0: + case MTAC_GPIOB_0_0: card_attrs_size = ap2_gpio_attributes_size; card_attrs = ap2_gpio_attributes; break; @@ -502,7 +502,7 @@ static bool mts_ap_eeprom_load(void) 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_MTDC_ETH, strlen(PRODUCT_ID_MTDC_ETH)) == 0) { + 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], @@ -527,7 +527,7 @@ static bool mts_ap_eeprom_load(void) 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_MTDC_ETH, strlen(PRODUCT_ID_MTDC_ETH)) == 0) { + 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], @@ -715,22 +715,22 @@ static int __init mts_io_init(void) } if (accessory_card_capable) { - mts_ap1_product_id = MTDC_NONE; - mts_ap2_product_id = MTDC_NONE; + 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_MTDC_GPIOB)) { - mts_ap1_product_id = MTDC_GPIOB_0_0; + 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 MTDC_GPIOB_0_0: + 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"); @@ -775,15 +775,15 @@ static int __init mts_io_init(void) 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; + 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 MTDC_GPIOB_0_0: + 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"); @@ -953,7 +953,7 @@ error2: if (have_accessory_card_slot_1) { switch (mts_ap1_product_id) { - case MTDC_GPIOB_0_0: + 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); @@ -966,7 +966,7 @@ error2: if (have_accessory_card_slot_2) { switch (mts_ap2_product_id) { - case MTDC_GPIOB_0_0: + 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); @@ -1006,7 +1006,7 @@ static void __exit mts_io_exit(void) if (have_accessory_card_slot_1) { switch (mts_ap1_product_id) { - case MTDC_GPIOB_0_0: + 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); @@ -1019,7 +1019,7 @@ static void __exit mts_io_exit(void) if (have_accessory_card_slot_2) { switch (mts_ap2_product_id) { - case MTDC_GPIOB_0_0: + 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); diff --git a/io-module/mts_io.h b/io-module/mts_io.h index c76471c..b91423e 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -48,9 +48,9 @@ struct device_attribute _dev_name = { \ #define PRODUCT_ID_MTOCGD "MTOCGD" #define PRODUCT_ID_MTR2D2 "MTR2D2" -#define PRODUCT_ID_MTDC_GPIOB "MTDC-GPIOB" +#define PRODUCT_ID_MTAC_GPIOB "MTAC-GPIOB" #define PRODUCT_ID_MTAC_MFSER "MTAC-MFSER" -#define PRODUCT_ID_MTDC_ETH "MTDC-ETH" +#define PRODUCT_ID_MTAC_ETH "MTAC-ETH" #define HW_VERSION_MTCBA2_2_0 "MTCBA2-2.0" #define HW_VERSION_MTCDP_0_0 "MTCDP-0.0" @@ -78,8 +78,8 @@ enum { }; enum { - MTDC_NONE, - MTDC_GPIOB_0_0, + MTAC_NONE, + MTAC_GPIOB_0_0, MTAC_MFSER_0_0, }; diff --git a/io-module/spi.c b/io-module/spi.c index df663ae..e652b90 100644 --- a/io-module/spi.c +++ b/io-module/spi.c @@ -602,7 +602,7 @@ static int mts_spi_ap1_dout_probe(struct spi_device *spi) { int tmp; - if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTAC_GPIOB_0_0) { log_error("accessory card 1 digital outputs not available"); return -ENODEV; } @@ -648,7 +648,7 @@ static int mts_spi_ap1_din_probe(struct spi_device *spi) { int tmp; - if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTAC_GPIOB_0_0) { log_error("accessory card 1 digital inputs not available"); return -ENODEV; } @@ -691,7 +691,7 @@ static int mts_spi_ap1_adc_probe(struct spi_device *spi) { int tmp; - if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTAC_GPIOB_0_0) { log_error("accessory card 1 analog to digital not available"); return -ENODEV; } @@ -735,7 +735,7 @@ static int mts_spi_ap2_dout_probe(struct spi_device *spi) { int tmp; - if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTAC_GPIOB_0_0) { log_error("accessory card 2 digital outputs not available"); return -ENODEV; } @@ -781,7 +781,7 @@ static int mts_spi_ap2_din_probe(struct spi_device *spi) { int tmp; - if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTAC_GPIOB_0_0) { log_error("accessory card 2 digital inputs not available"); return -ENODEV; } @@ -824,7 +824,7 @@ static int mts_spi_ap2_adc_probe(struct spi_device *spi) { int tmp; - if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTAC_GPIOB_0_0) { log_error("accessory card 2 analog to digital not available"); return -ENODEV; } -- cgit v1.2.3 From a21c24fa2486e4d4a3b25d0dcbf873ae62fdbcec Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Tue, 23 Sep 2014 10:35:11 -0500 Subject: 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 --- io-module/Makefile | 1 - io-module/mtac.c | 22 ++ io-module/mtac_gpiob.c | 552 +++++++++++++++++++++++++++++-------------------- io-module/mtac_mfser.c | 106 ++++++---- io-module/mtr2d2.c | 7 +- io-module/mts_io.c | 376 ++++++++------------------------- io-module/mts_io.h | 20 ++ io-module/spi.c | 295 -------------------------- 8 files changed, 532 insertions(+), 847 deletions(-) create mode 100644 io-module/mtac.c diff --git a/io-module/Makefile b/io-module/Makefile index f95a55e..5d036f4 100644 --- a/io-module/Makefile +++ b/io-module/Makefile @@ -1,5 +1,4 @@ obj-m := mts_io.o -CFLAGS_mts_io.o := ${DAUGHTER_CARD} clean: rm -f *.ko *.o diff --git a/io-module/mtac.c b/io-module/mtac.c new file mode 100644 index 0000000..b9a2520 --- /dev/null +++ b/io-module/mtac.c @@ -0,0 +1,22 @@ +static struct kobj_attribute* create_attribute(const char* _name, umode_t _mode) { + char* attr_name; + struct kobj_attribute* _attr; + + _attr = kzalloc(sizeof(struct kobj_attribute), GFP_KERNEL); + if (! _attr) { + log_error("kzalloc of attribute %s failed", _name); + return NULL; + } + + sysfs_attr_init(_attr); + attr_name = kstrdup(_name, GFP_KERNEL); + if (! attr_name) { + log_error("GFP_KERNEL dup failed for attribute [%s]", _name); + return NULL; + } + + _attr->attr.name = attr_name; + _attr->attr.mode = _mode; + + return _attr; +} diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c index 5a592b7..728634d 100644 --- a/io-module/mtac_gpiob.c +++ b/io-module/mtac_gpiob.c @@ -1,22 +1,130 @@ +struct spi_device *gpiob_spi[NUM_AP][3]; +struct spi_driver gpiob_spi_drivers[NUM_AP][3]; + +static u8 spi_ap_dout_value; +static DEFINE_MUTEX(spi_ap_dout_mutex); +static unsigned int ap_dout_max_speed_hz = 1 * 1000 * 1000; +module_param(ap_dout_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + ap_dout_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +static unsigned int ap_din_max_speed_hz = 1 * 1000 * 1000; +module_param(ap_din_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + ap_din_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +static unsigned int ap_adc_max_speed_hz = 20 * 1000 * 1000; +module_param(ap_adc_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + ap_adc_max_speed_hz, + "Maximum clock rate to be used with this device (default: 20 MHz)" +); + +static bool gpiob_get_dev_info_from_modalias(const char* modalias, int* port, char* buf) { + sscanf(modalias, "mts-io-ap%d-%s", port, buf); + + return true; +} + +static int mts_spi_ap_probe(struct spi_device *spi) +{ + int tmp; + int port; + int port_index; + char buf[16]; + enum spi_devices dev; + + gpiob_get_dev_info_from_modalias(spi->modalias, &port, buf); + port_index = port - 1; + if (port < 1 || port > NUM_AP) { + log_error("port [%d] is invalid", port); + return -ENODEV; + } + + if (strstr(buf, "dout")) { + dev = dout; + spi->max_speed_hz = ap_dout_max_speed_hz; + spi->mode = 0; + } else if (strstr(buf, "din")) { + dev = din; + spi->max_speed_hz = ap_din_max_speed_hz; + spi->mode = SPI_CPOL; + } else if (strstr(buf, "adc")) { + dev = adc; + spi->max_speed_hz = ap_adc_max_speed_hz; + spi->mode = 0; + } else { + log_error("unknown gpiob spi device type [%s]", buf); + return -ENODEV; + } + + gpiob_spi[port_index][dev] = spi; + + tmp = spi_setup(gpiob_spi[port_index][dev]); + if (tmp < 0) { + log_error("spi_setup ap %d %s failed", port, buf); + return tmp; + } + + if (dev == dout) { + spi_ap_dout_value = 0x00; + spi_writen(gpiob_spi[port_index][dev], &spi_ap_dout_value, 1); + } + + return 0; +} + +static int mts_spi_ap_remove(struct spi_device *spi) +{ + int port; + int port_index; + char buf[16]; + + gpiob_get_dev_info_from_modalias(spi->modalias, &port, buf); + port_index = port - 1; + if (port < 1 || port > NUM_AP) { + log_error("port [%d] is invalid", port); + return -ENODEV; + } + + if (strstr(buf, "dout")) { + gpiob_spi[port_index][dout] = NULL; + } else if (strstr(buf, "din")) { + gpiob_spi[port_index][din] = NULL; + } else if (strstr(buf, "adc")) { + gpiob_spi[port_index][adc] = NULL; + } else { + log_error("unknown gpiob spi device type [%s]", buf); + return -ENODEV; + } + + return 0; +} + +// Is there a way to make this dynamic as well? struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { struct gpio_pin *pin; char *pin_attr_name; - if (!strcmp(name, "ap1-led1")) { + if (!strcmp(name, "ap-led1:1")) { pin_attr_name = "ap1-gpio3"; - } else if (!strcmp(name, "ap1-led2")) { + } else if (!strcmp(name, "ap-led2:1")) { pin_attr_name = "ap1-gpio4"; - } else if (!strcmp(name, "ap1-dout-enable")) { + } else if (!strcmp(name, "ap-dout-enable:1")) { pin_attr_name = "ap1-gpio1"; - } else if (!strcmp(name, "ap1-reset")) { + } else if (!strcmp(name, "ap-reset:1")) { pin_attr_name = "ap1-reset"; - } else if (!strcmp(name, "ap2-led1")) { + } else if (!strcmp(name, "ap-led1:2")) { pin_attr_name = "ap2-gpio3"; - } else if (!strcmp(name, "ap2-led2")) { + } else if (!strcmp(name, "ap-led2:2")) { pin_attr_name = "ap2-gpio4"; - } else if (!strcmp(name, "ap2-dout-enable")) { + } else if (!strcmp(name, "ap-dout-enable:2")) { pin_attr_name = "ap2-gpio1"; - } else if (!strcmp(name, "ap2-reset")) { + } else if (!strcmp(name, "ap-reset:2")) { pin_attr_name = "ap2-reset"; } else { log_error("accessory card attribute %s not available", name); @@ -35,8 +143,8 @@ struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { } -static ssize_t mts_attr_show_ap_gpio_pin(struct device *dev, - struct device_attribute *attr, +static ssize_t mts_attr_show_ap_gpio_pin(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) { int value; @@ -63,8 +171,8 @@ static ssize_t mts_attr_show_ap_gpio_pin(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t mts_attr_store_ap_gpio_pin(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mts_attr_store_ap_gpio_pin(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) { int value; struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); @@ -90,46 +198,29 @@ static ssize_t mts_attr_store_ap_gpio_pin(struct device *dev, return count; } -static ssize_t mts_attr_show_ap_din(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_din(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int tmp; + int channel; + int port; + int port_index; u8 bit; u8 byte; - struct spi_device* spi_dev; - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_din_dev) { - log_error("accessory card 1 din device not present"); - return -ENODEV; - } - - spi_dev = spi_ap1_din_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_din_dev) { - log_error("accessory card 2 din device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_din_dev; - } else { - log_error("unknown din device %s", attr->attr.name); - return -ENODEV; + sscanf(attr->attr.name, "din%d:%d", &channel, &port); + port_index = port - 1; + if (channel < 0 || channel > 3) { + log_error("channel [%d] is invalid", channel); + return -ENOENT; } - - if (strstr(attr->attr.name, "din0")) { - bit = BIT(0); - } else if (strstr(attr->attr.name, "din1")) { - bit = BIT(1); - } else if (strstr(attr->attr.name, "din2")) { - bit = BIT(2); - } else if (strstr(attr->attr.name, "din3")) { - bit = BIT(3); - } else { - log_error("accessory card din attr does not exist"); + if (port < 1 || port > NUM_AP) { + log_error("port [%d] is invalid", port); return -ENOENT; } - tmp = spi_readn(spi_dev, &byte, 1); + bit = BIT(channel); + + tmp = spi_readn(gpiob_spi[port_index][din], &byte, 1); if (tmp) { log_error("spi_read failed %d", tmp); return tmp; @@ -140,46 +231,29 @@ static ssize_t mts_attr_show_ap_din(struct device *dev, struct device_attribute return sprintf(buf, "%d\n", tmp); } -static ssize_t mts_attr_store_ap_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mts_attr_store_ap_dout(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int value; + int channel; + int port; + int port_index; u8 bit; - struct spi_device* spi_dev; - - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_dout_dev) { - log_error("accessory card 1 dout device not present"); - return -ENODEV; - } - spi_dev = spi_ap1_dout_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_dout_dev) { - log_error("accessory card 2 dout device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_dout_dev; - } else { - log_error("unknown dout device %s", attr->attr.name); - return -ENODEV; + sscanf(attr->attr.name, "dout%d:%d", &channel, &port); + port_index = port - 1; + if (channel < 0 || channel > 3) { + log_error("channel [%d] is invalid", channel); + return -ENOENT; } - - if (strstr(attr->attr.name, "dout0")) { - bit = BIT(0); - } else if (strstr(attr->attr.name, "dout1")) { - bit = BIT(1); - } else if (strstr(attr->attr.name, "dout2")) { - bit = BIT(2); - } else if (strstr(attr->attr.name, "dout3")) { - bit = BIT(3); - } else { - log_error("accessory card dout attr does not exist"); + if (port < 1 || port > NUM_AP) { + log_error("port [%d] is invalid", port); return -ENOENT; } + bit = BIT(channel); + if (sscanf(buf, "%i", &value) != 1) { - log_error("accessory card dout attr invalid argument"); + log_error("accessory card dout attr invalid argument [%d]", value); return -EINVAL; } @@ -191,51 +265,32 @@ static ssize_t mts_attr_store_ap_dout(struct device *dev, struct device_attribut spi_ap_dout_value |= bit; } - spi_writen(spi_dev, &spi_ap_dout_value, 1); + spi_writen(gpiob_spi[port_index][dout], &spi_ap_dout_value, 1); mutex_unlock(&spi_ap_dout_mutex); return count; } -static ssize_t mts_attr_show_ap_dout(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_dout(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int value; + int channel; + int port; u8 bit; - struct spi_device* spi_dev; - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_dout_dev) { - log_error("accessory card 1 dout device not present"); - return -ENODEV; - } - - spi_dev = spi_ap1_dout_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_dout_dev) { - log_error("accessory card 2 dout device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_dout_dev; - } else { - log_error("unknown dout device %s", attr->attr.name); - return -ENODEV; + sscanf(attr->attr.name, "dout%d:%d", &channel, &port); + if (channel < 0 || channel > 3) { + log_error("channel [%d] is invalid", channel); + return -ENOENT; } - - if (strstr(attr->attr.name, "dout0")) { - bit = BIT(0); - } else if (strstr(attr->attr.name, "dout1")) { - bit = BIT(1); - } else if (strstr(attr->attr.name, "dout2")) { - bit = BIT(2); - } else if (strstr(attr->attr.name, "dout3")) { - bit = BIT(3); - } else { - log_error("accessory card dout attr does not exist"); + if (port < 1 || port > NUM_AP) { + log_error("port [%d] is invalid", port); return -ENOENT; } + bit = BIT(channel); + mutex_lock(&spi_ap_dout_mutex); value = spi_ap_dout_value & bit ? 0 : 1; @@ -245,48 +300,30 @@ static ssize_t mts_attr_show_ap_dout(struct device *dev, struct device_attribute return sprintf(buf, "%d\n", value); } -static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_adc(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int tmp; int tx_data; int rx_data; int channel; + int port; + int port_index; int channel_mask = 0x0180; /* 0b 0000 0001 1000 0000 */ int manual_mode = 0x1840; /* 0b 0001 1000 0100 0000 */ uint8_t tx[2]; uint8_t rx[2]; - struct spi_device* spi_dev; memset(tx, 0, sizeof(tx)); memset(rx, 0, sizeof(rx)); - if (strstr(attr->attr.name, ":0")) { - if (!spi_ap1_adc_dev) { - log_error("accessory card 1 adc device not present"); - return -ENODEV; - } - - spi_dev = spi_ap1_adc_dev; - } else if (strstr(attr->attr.name, ":1")) { - if (!spi_ap2_adc_dev) { - log_error("accessory card 2 adc device not present"); - return -ENODEV; - } - - spi_dev = spi_ap2_adc_dev; - } else { - log_error("unknown adc device %s", attr->attr.name); - return -ENODEV; + sscanf(attr->attr.name, "adc%d:%d", &channel, &port); + port_index = port - 1; + if (channel < 0 || channel > 2) { + log_error("channel [%d] is invalid", channel); + return -ENOENT; } - - if (strstr(attr->attr.name, "adc0")) { - channel = 0; - } else if (strstr(attr->attr.name, "adc1")) { - channel = 1; - } else if (strstr(attr->attr.name, "adc2")) { - channel = 2; - } else { - log_error("accessory card adc attr does not exist"); + if (port < 1 || port > NUM_AP) { + log_error("port [%d] is invalid", port); return -ENOENT; } @@ -294,7 +331,7 @@ static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute tx_data = manual_mode | ((channel << 7) & channel_mask); tx[0] = tx_data >> 8; tx[1] = tx_data & 0xFF; - tmp = spi_writen(spi_dev, tx, 2); + tmp = spi_writen(gpiob_spi[port_index][adc], tx, 2); if (tmp) { log_error("spi_write failed %d", tmp); return tmp; @@ -305,14 +342,14 @@ static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute * the ADC just needs the clock running so it can convert */ tx[0] = 0; tx[1] = 0; - tmp = spi_writen(spi_dev, tx, 2); + tmp = spi_writen(gpiob_spi[port_index][adc], tx, 2); if (tmp) { log_error("2nd spi_write failed %d", tmp); return tmp; } /* 3rd transfer to read data */ - tmp = spi_readn(spi_dev, rx, 2); + tmp = spi_readn(gpiob_spi[port_index][adc], rx, 2); if (tmp) { log_error("spi_read failed %d", tmp); return tmp; @@ -322,88 +359,165 @@ static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute return sprintf(buf, "%lu\n", (unsigned long) rx_data); } -/* accessory port 1 gpiob attributes */ -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din0, "din0:0", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din1, "din1:0", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din2, "din2:0", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din3, "din3:0", mts_attr_show_ap_din); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout0, "dout0:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout1, "dout1:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout2, "dout2:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout3, "dout3:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc0, "adc0:0", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc1, "adc1:0", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc2, "adc2:0", mts_attr_show_ap_adc); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led1, "ap1-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led2, "ap1-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_oe, "ap1-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap1_reset, "ap1-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); - -static int ap1_gpio_attributes_size = 15; // not including NULL at end - -static struct attribute *ap1_gpio_attributes[] = { - &dev_attr_ap1_reset.attr, - - &dev_attr_ap1_gpio_oe.attr, // gpio1 - &dev_attr_ap1_gpio_led1.attr, // gpio3 - &dev_attr_ap1_gpio_led2.attr, // gpio4 - - &dev_attr_ap1_gpio_din0.attr, - &dev_attr_ap1_gpio_din1.attr, - &dev_attr_ap1_gpio_din2.attr, - &dev_attr_ap1_gpio_din3.attr, - - &dev_attr_ap1_gpio_dout0.attr, - &dev_attr_ap1_gpio_dout1.attr, - &dev_attr_ap1_gpio_dout2.attr, - &dev_attr_ap1_gpio_dout3.attr, - - &dev_attr_ap1_gpio_adc0.attr, - &dev_attr_ap1_gpio_adc1.attr, - &dev_attr_ap1_gpio_adc2.attr, - - NULL, -}; +static bool gpiob_spi_driver_setup(struct spi_driver *driver, const char *driver_name) { + char* name = kstrdup(driver_name, GFP_KERNEL); + if (! name) { + log_error("GFP_KERNEL dup failed for driver [%s]", driver_name); + return false; + } + driver->driver.name = name; + driver->driver.bus = &spi_bus_type; + driver->driver.owner = THIS_MODULE; + driver->probe = mts_spi_ap_probe; + driver->remove = mts_spi_ap_remove; + + return true; +} + +// 4 digital inputs +// 4 digital outputs +// 3 analog to digital +// 2 LEDs +// 1 digital out enable +// 1 reset +static int ap_gpiob_attrs_size = 15; + +static bool gpiob_setup(enum ap port) { + int i; + int port_index = port - 1; + struct kobj_attribute *attr; + char buf[32]; + + log_info("loading GPIOB accessory card in port %d", port); + + if (device_attrs_size + ap_gpiob_attrs_size >= device_attrs_max_size) { + log_error("can't load GPIOB accessory card in port %d - not enough room for attributes", port); + return false; + } + + // add digital inputs + for (i = 0; i < 4; i++) { + sprintf(buf, "din%d:%d", i, port); + attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_din; + device_attrs[device_attrs_size++] = &attr->attr; + } + + // add digital outputs + for (i = 0; i < 4; i++) { + sprintf(buf, "dout%d:%d", i, port); + attr = create_attribute(buf, MTS_ATTR_MODE_RW); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_dout; + attr->store = mts_attr_store_ap_dout; + device_attrs[device_attrs_size++] = &attr->attr; + } + + // add analog to digital + for (i = 0; i < 3; i++) { + sprintf(buf, "adc%d:%d", i, port); + attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_adc; + device_attrs[device_attrs_size++] = &attr->attr; + } + + // add LEDs + for (i = 1; i <= 2; i++) { + sprintf(buf, "ap-led%d:%d", i, port); + attr = create_attribute(buf, MTS_ATTR_MODE_RW); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_gpio_pin; + attr->store = mts_attr_store_ap_gpio_pin; + device_attrs[device_attrs_size++] = &attr->attr; + } + + // misc attributes + sprintf(buf, "ap-dout-enable:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RW); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_gpio_pin; + attr->store = mts_attr_store_ap_gpio_pin; + device_attrs[device_attrs_size++] = &attr->attr; + + sprintf(buf, "ap-reset:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RW); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_gpio_pin; + attr->store = mts_attr_store_ap_gpio_pin; + device_attrs[device_attrs_size++] = &attr->attr; + + // setup and register drivers + log_debug("registering accessory card %d dout driver", port); + sprintf(buf, "mts-io-ap%d-dout", port); + if (! gpiob_spi_driver_setup(&gpiob_spi_drivers[port_index][dout], buf)) { + log_error("failed to set up spi driver [%s]", buf); + return false; + } + if (spi_register_driver(&gpiob_spi_drivers[port_index][dout])) { + log_error("failed to register accessory card %d dout driver", port); + spi_unregister_driver(&gpiob_spi_drivers[port_index][dout]); + return false; + } + + log_debug("registering accessory card %d din driver", port); + sprintf(buf, "mts-io-ap%d-din", port); + if (! gpiob_spi_driver_setup(&gpiob_spi_drivers[port_index][din], buf)) { + log_error("failed to set up spi driver [%s]", buf); + return false; + } + if (spi_register_driver(&gpiob_spi_drivers[port_index][din])) { + log_error("failed to register accessory card %d din driver", port); + spi_unregister_driver(&gpiob_spi_drivers[port_index][din]); + return false; + } + + log_debug("registering accessory card %d adc driver", port); + sprintf(buf, "mts-io-ap%d-adc", port); + if (! gpiob_spi_driver_setup(&gpiob_spi_drivers[port_index][adc], buf)) { + log_error("failed to set up spi driver [%s]", buf); + return false; + } + if (spi_register_driver(&gpiob_spi_drivers[port_index][adc])) { + log_error("failed to register accessory card %d adc driver", port); + spi_unregister_driver(&gpiob_spi_drivers[port_index][adc]); + return false; + } + return true; +} + +static bool gpiob_teardown(enum ap port) { + int port_index = port - 1; + + // do we need to clean up allocated memory here as well? + log_info("unloading GPIOB accessory card in port %d", port); + spi_unregister_driver(&gpiob_spi_drivers[port_index][dout]); + spi_unregister_driver(&gpiob_spi_drivers[port_index][din]); + spi_unregister_driver(&gpiob_spi_drivers[port_index][adc]); + return true; +} -/* accessory port 2 gpiob attributes */ -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din0, "din0:1", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din1, "din1:1", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din2, "din2:1", mts_attr_show_ap_din); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din3, "din3:1", mts_attr_show_ap_din); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout0, "dout0:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout1, "dout1:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout2, "dout2:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout3, "dout3:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc0, "adc0:1", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc1, "adc1:1", mts_attr_show_ap_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc2, "adc2:1", mts_attr_show_ap_adc); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led1, "ap2-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led2, "ap2-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_oe, "ap2-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_ap2_reset, "ap2-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); - -static int ap2_gpio_attributes_size = 15; // not including NULL at end - -static struct attribute *ap2_gpio_attributes[] = { - &dev_attr_ap2_reset.attr, - - &dev_attr_ap2_gpio_oe.attr, // gpio1 - &dev_attr_ap2_gpio_led1.attr, // gpio3 - &dev_attr_ap2_gpio_led2.attr, // gpio4 - - &dev_attr_ap2_gpio_din0.attr, - &dev_attr_ap2_gpio_din1.attr, - &dev_attr_ap2_gpio_din2.attr, - &dev_attr_ap2_gpio_din3.attr, - - &dev_attr_ap2_gpio_dout0.attr, - &dev_attr_ap2_gpio_dout1.attr, - &dev_attr_ap2_gpio_dout2.attr, - &dev_attr_ap2_gpio_dout3.attr, - - &dev_attr_ap2_gpio_adc0.attr, - &dev_attr_ap2_gpio_adc1.attr, - &dev_attr_ap2_gpio_adc2.attr, - - NULL, +static struct ap_info gpiob_info = { + .product_id = MTAC_GPIOB_0_0, + .setup = &gpiob_setup, + .teardown = &gpiob_teardown }; diff --git a/io-module/mtac_mfser.c b/io-module/mtac_mfser.c index 14eddd1..5871bfe 100644 --- a/io-module/mtac_mfser.c +++ b/io-module/mtac_mfser.c @@ -2,13 +2,13 @@ struct gpio_pin *ap_mfser_pin_by_attr_name(const char *name) { struct gpio_pin *pin; char *pin_attr_name; - if (!strcmp(name, "rs4xx-term-res:0")) { + if (!strcmp(name, "rs4xx-term-res:1")) { pin_attr_name = "ap1-gpio3"; - } else if (!strcmp(name, "rts-override:0")) { + } else if (!strcmp(name, "rts-override:1")) { pin_attr_name = "ap1-gpio4"; - } else if (!strcmp(name, "rs4xx-term-res:1")) { + } else if (!strcmp(name, "rs4xx-term-res:2")) { pin_attr_name = "ap2-gpio3"; - } else if (!strcmp(name, "rts-override:1")) { + } else if (!strcmp(name, "rts-override:2")) { pin_attr_name = "ap2-gpio4"; } else { log_error("accessory card attribute %s not available", name); @@ -27,8 +27,8 @@ struct gpio_pin *ap_mfser_pin_by_attr_name(const char *name) { } -static ssize_t mts_attr_show_ap_mfser_pin(struct device *dev, - struct device_attribute *attr, +static ssize_t mts_attr_show_ap_mfser_pin(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) { int value; @@ -55,8 +55,8 @@ static ssize_t mts_attr_show_ap_mfser_pin(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t mts_attr_store_ap_mfser_pin(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mts_attr_store_ap_mfser_pin(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) { int value; struct gpio_pin *pin = ap_mfser_pin_by_attr_name(attr->attr.name); @@ -82,8 +82,8 @@ static ssize_t mts_attr_store_ap_mfser_pin(struct device *dev, return count; } -static ssize_t mts_attr_show_mfser_mode(struct device *dev, - struct device_attribute *attr, +static ssize_t mts_attr_show_mfser_mode(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) { int ret; @@ -93,11 +93,11 @@ static ssize_t mts_attr_show_mfser_mode(struct device *dev, struct gpio_pin *pin_modesel0; struct gpio_pin *pin_modesel1; - if (strstr(attr->attr.name, ":0")) { + if (strstr(attr->attr.name, ":1")) { pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); } - else if (strstr(attr->attr.name, ":1")) { + else if (strstr(attr->attr.name, ":2")) { pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); } @@ -130,19 +130,19 @@ static ssize_t mts_attr_show_mfser_mode(struct device *dev, return ret; } -static ssize_t mts_attr_store_mfser_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mts_attr_store_mfser_mode(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) { int modesel0; int modesel1; struct gpio_pin *pin_modesel0; struct gpio_pin *pin_modesel1; - if (strstr(attr->attr.name, ":0")) { + if (strstr(attr->attr.name, ":1")) { pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); } - else if (strstr(attr->attr.name, ":1")) { + else if (strstr(attr->attr.name, ":2")) { pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); } @@ -184,32 +184,62 @@ static ssize_t mts_attr_store_mfser_mode(struct device *dev, return count; } -/* accessory port 1 serial attributes */ -static DEVICE_ATTR_MTS(dev_attr_ap1_serial_mode, "serial-mode:0", mts_attr_show_mfser_mode, mts_attr_store_mfser_mode); -static DEVICE_ATTR_MTS(dev_attr_ap1_rs4xx_term_res, "rs4xx-term-res:0", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); -static DEVICE_ATTR_MTS(dev_attr_ap1_rts_override, "rts-override:0", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); +// 1 serial mode +// 1 rs4xx term resistor +// 1 rts override +static int ap_mfser_attrs_size = 3; -static int ap1_mfser_attributes_size = 3; // not including NULL at end +static bool mfser_setup(enum ap port) { + struct kobj_attribute *attr; + char buf[32]; -static struct attribute *ap1_mfser_attributes[] = { - &dev_attr_ap1_serial_mode.attr, - &dev_attr_ap1_rs4xx_term_res.attr, // gpio3 - &dev_attr_ap1_rts_override.attr, // gpio4 - NULL, -}; + log_info("loading MFSER accessory card in port %d", port); -/* accessory port 2 serial attributes */ -static DEVICE_ATTR_MTS(dev_attr_ap2_serial_mode, "serial-mode:1", mts_attr_show_mfser_mode, mts_attr_store_mfser_mode); -static DEVICE_ATTR_MTS(dev_attr_ap2_rs4xx_term_res, "rs4xx-term-res:1", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); -static DEVICE_ATTR_MTS(dev_attr_ap2_rts_override, "rts-override:1", mts_attr_show_ap_mfser_pin, mts_attr_store_ap_mfser_pin); + if (device_attrs_size + ap_mfser_attrs_size >= device_attrs_max_size) { + log_error("can't load MFSER accessory card in port %d - not enough room for attributes", port); + return false; + } -static int ap2_mfser_attributes_size = 3; // not including NULL at end + sprintf(buf, "serial-mode:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RW); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_mfser_mode; + attr->store = mts_attr_store_mfser_mode; + device_attrs[device_attrs_size++] = &attr->attr; -static struct attribute *ap2_mfser_attributes[] = { - &dev_attr_ap2_serial_mode.attr, - &dev_attr_ap2_rs4xx_term_res.attr, // gpio3 - &dev_attr_ap2_rts_override.attr, // gpio4 - NULL, -}; + sprintf(buf, "rs4xx-term-res:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RW); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_mfser_pin; + attr->store = mts_attr_store_ap_mfser_pin; + device_attrs[device_attrs_size++] = &attr->attr; + sprintf(buf, "rts-override:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RW); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = mts_attr_show_ap_mfser_pin; + attr->store = mts_attr_store_ap_mfser_pin; + device_attrs[device_attrs_size++] = &attr->attr; + + return true; +} +static bool mfser_teardown(enum ap port) { + log_info("unloading MFSER accessory card in port %d", port); + return true; +} + +static struct ap_info mfser_info = { + .product_id = MTAC_MFSER_0_0, + .setup = &mfser_setup, + .teardown = &mfser_teardown +}; diff --git a/io-module/mtr2d2.c b/io-module/mtr2d2.c index 0926952..24a99f3 100644 --- a/io-module/mtr2d2.c +++ b/io-module/mtr2d2.c @@ -1,4 +1,3 @@ - static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { { .name = "RADIO_RESET", @@ -266,7 +265,8 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { { }, }; -static int mtr2d2_platform_attributes_size = 64; // not including NULL at end +static int mtr2d2_platform_attributes_max_size = 64; // including NULL at end +static int mtr2d2_platform_attributes_size = 21; static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_vendor_id.attr, @@ -295,6 +295,8 @@ static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_board_temperature.attr, /* extra space for the accessory card attributes */ + NULL, // index 21 + NULL, // index 22 NULL, // index 23 NULL, // index 24 NULL, // index 25 @@ -336,7 +338,6 @@ static struct attribute *mtr2d2_platform_attributes[] = { NULL, // index 61 NULL, // index 62 NULL, // index 63 - NULL, // index 64 NULL, }; 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"); } diff --git a/io-module/mts_io.h b/io-module/mts_io.h index b91423e..ac39463 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -102,5 +102,25 @@ enum { LED_FLASHING, }; +enum ap { + port_1 = 1, + port_2, +}; + +enum spi_devices { + din = 0, + dout = 1, + adc = 2, +}; + +// info for accessory port +// contains function pointers for setup and teardown and useful info +// each type of accessory card should have one of these +struct ap_info { + uint8_t product_id; + bool (*setup)(enum ap port); + bool (*teardown)(enum ap port); +}; + #endif /* ~__MTS_IO_H */ diff --git a/io-module/spi.c b/io-module/spi.c index e652b90..210371c 100644 --- a/io-module/spi.c +++ b/io-module/spi.c @@ -40,35 +40,6 @@ MODULE_PARM_DESC( "Maximum clock rate to be used with this device (default: 1 MHz)" ); -static struct spi_device *spi_ap1_dout_dev; -static struct spi_device *spi_ap2_dout_dev; -static u8 spi_ap_dout_value; -static DEFINE_MUTEX(spi_ap_dout_mutex); -static unsigned int ap_dout_max_speed_hz = 1 * 1000 * 1000; -module_param(ap_dout_max_speed_hz, uint, S_IRUGO); -MODULE_PARM_DESC( - ap_dout_max_speed_hz, - "Maximum clock rate to be used with this device (default: 1 MHz)" -); - -static struct spi_device *spi_ap1_din_dev; -static struct spi_device *spi_ap2_din_dev; -static unsigned int ap_din_max_speed_hz = 1 * 1000 * 1000; -module_param(ap_din_max_speed_hz, uint, S_IRUGO); -MODULE_PARM_DESC( - ap_din_max_speed_hz, - "Maximum clock rate to be used with this device (default: 1 MHz)" -); - -static struct spi_device *spi_ap1_adc_dev; -static struct spi_device *spi_ap2_adc_dev; -static unsigned int ap_adc_max_speed_hz = 20 * 1000 * 1000; -module_param(ap_adc_max_speed_hz, uint, S_IRUGO); -MODULE_PARM_DESC( - ap_adc_max_speed_hz, - "Maximum clock rate to be used with this device (default: 20 MHz)" -); - static struct spi_device *spi_board_temp_dev; static unsigned int board_temp_max_speed_hz = 1 * 1000 * 1000; module_param(board_temp_max_speed_hz, uint, S_IRUGO); @@ -598,272 +569,6 @@ static struct spi_driver mts_spi_din_driver = { .remove = mts_spi_din_remove, }; -static int mts_spi_ap1_dout_probe(struct spi_device *spi) -{ - int tmp; - - if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTAC_GPIOB_0_0) { - log_error("accessory card 1 digital outputs not available"); - return -ENODEV; - } - - spi->max_speed_hz = ap_dout_max_speed_hz; - spi->mode = 0; - - log_debug("ap1_dout_max_speed_hz: %d", ap_dout_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup accessory card 1 dout failed"); - return tmp; - } - - spi_ap_dout_value = 0x00; - spi_writen(spi, &spi_ap_dout_value, 1); - - spi_ap1_dout_dev = spi; - - return 0; -} - -static int mts_spi_ap1_dout_remove(struct spi_device *spi) -{ - spi_ap1_dout_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_ap1_dout_driver = { - .driver = { - .name = "mts-io-ap1-dout", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_ap1_dout_probe, - .remove = mts_spi_ap1_dout_remove, -}; - -static int mts_spi_ap1_din_probe(struct spi_device *spi) -{ - int tmp; - - if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTAC_GPIOB_0_0) { - log_error("accessory card 1 digital inputs not available"); - return -ENODEV; - } - - spi->max_speed_hz = ap_din_max_speed_hz; - spi->mode = SPI_CPOL; - - log_debug("ap1_din_max_speed_hz: %d", ap_din_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup accessory card 1 din failed"); - return tmp; - } - - spi_ap1_din_dev = spi; - - return 0; -} - -static int mts_spi_ap1_din_remove(struct spi_device *spi) -{ - spi_ap1_din_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_ap1_din_driver = { - .driver = { - .name = "mts-io-ap1-din", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_ap1_din_probe, - .remove = mts_spi_ap1_din_remove, -}; - -static int mts_spi_ap1_adc_probe(struct spi_device *spi) -{ - int tmp; - - if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTAC_GPIOB_0_0) { - log_error("accessory card 1 analog to digital not available"); - return -ENODEV; - } - - spi->max_speed_hz = ap_adc_max_speed_hz; - spi->mode = 0; - - log_debug("ap1_adc_max_speed_hz: %d", ap_adc_max_speed_hz); - log_debug("ap1_adc_mode: %d", spi->mode); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup accessory card 1 adc failed"); - return tmp; - } - - spi_ap1_adc_dev = spi; - - return 0; -} - -static int mts_spi_ap1_adc_remove(struct spi_device *spi) -{ - spi_ap1_adc_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_ap1_adc_driver = { - .driver = { - .name = "mts-io-ap1-adc", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_ap1_adc_probe, - .remove = mts_spi_ap1_adc_remove, -}; - -static int mts_spi_ap2_dout_probe(struct spi_device *spi) -{ - int tmp; - - if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTAC_GPIOB_0_0) { - log_error("accessory card 2 digital outputs not available"); - return -ENODEV; - } - - spi->max_speed_hz = ap_dout_max_speed_hz; - spi->mode = 0; - - log_debug("ap2_dout_max_speed_hz: %d", ap_dout_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup accessory card 2 dout failed"); - return tmp; - } - - spi_ap_dout_value = 0x00; - spi_writen(spi, &spi_ap_dout_value, 2); - - spi_ap2_dout_dev = spi; - - return 0; -} - -static int mts_spi_ap2_dout_remove(struct spi_device *spi) -{ - spi_ap2_dout_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_ap2_dout_driver = { - .driver = { - .name = "mts-io-ap2-dout", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_ap2_dout_probe, - .remove = mts_spi_ap2_dout_remove, -}; - -static int mts_spi_ap2_din_probe(struct spi_device *spi) -{ - int tmp; - - if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTAC_GPIOB_0_0) { - log_error("accessory card 2 digital inputs not available"); - return -ENODEV; - } - - spi->max_speed_hz = ap_din_max_speed_hz; - spi->mode = SPI_CPOL; - - log_debug("ap2_din_max_speed_hz: %d", ap_din_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup accessory card 2 din failed"); - return tmp; - } - - spi_ap2_din_dev = spi; - - return 0; -} - -static int mts_spi_ap2_din_remove(struct spi_device *spi) -{ - spi_ap2_din_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_ap2_din_driver = { - .driver = { - .name = "mts-io-ap2-din", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_ap2_din_probe, - .remove = mts_spi_ap2_din_remove, -}; - -static int mts_spi_ap2_adc_probe(struct spi_device *spi) -{ - int tmp; - - if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTAC_GPIOB_0_0) { - log_error("accessory card 2 analog to digital not available"); - return -ENODEV; - } - - spi->max_speed_hz = ap_adc_max_speed_hz; - spi->mode = 0; - - log_debug("ap2_adc_max_speed_hz: %d", ap_adc_max_speed_hz); - log_debug("ap2_adc_mode: %d", spi->mode); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup accessory card 2 adc failed"); - return tmp; - } - - spi_ap2_adc_dev = spi; - - return 0; -} - -static int mts_spi_ap2_adc_remove(struct spi_device *spi) -{ - spi_ap2_adc_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_ap2_adc_driver = { - .driver = { - .name = "mts-io-ap2-adc", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_ap2_adc_probe, - .remove = mts_spi_ap2_adc_remove, -}; - static int mts_spi_board_temp_probe(struct spi_device *spi) { int tmp; -- cgit v1.2.3 From c83b0cf41999478d31c86fb50740d1fdf0fbb003 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Thu, 25 Sep 2014 14:03:36 -0500 Subject: mts-io: clean up memory allocated for accessory cards on module unload or setup failure --- io-module/mtac_gpiob.c | 45 +++++++++++++++++++++++++++++++++++++++------ io-module/mtac_mfser.c | 36 +++++++++++++++++++++++++++++++----- io-module/mts_io.c | 41 +++++++++++++++++++++++++++++------------ io-module/mts_io.h | 2 ++ 4 files changed, 101 insertions(+), 23 deletions(-) diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c index 728634d..f2cd9b2 100644 --- a/io-module/mtac_gpiob.c +++ b/io-module/mtac_gpiob.c @@ -395,6 +395,10 @@ static bool gpiob_setup(enum ap port) { return false; } + // mark the attribute indices we're using so we know what to clean up + port_info[port_index]->attrs_start = device_attrs_size; + port_info[port_index]->attrs_end = device_attrs_size + ap_gpiob_attrs_size; + // add digital inputs for (i = 0; i < 4; i++) { sprintf(buf, "din%d:%d", i, port); @@ -506,18 +510,47 @@ static bool gpiob_setup(enum ap port) { } static bool gpiob_teardown(enum ap port) { + int i; int port_index = port - 1; - // do we need to clean up allocated memory here as well? log_info("unloading GPIOB accessory card in port %d", port); + + // clean up allocated memory for attributes + for (i = port_info[port_index]->attrs_start; i < port_info[port_index]->attrs_end; i++) { + if (device_attrs[i]) { + if (device_attrs[i]->name) + kfree(device_attrs[i]->name); + + kfree(device_attrs[i]); + } + } + + // clean up allocated memory for SPI drivers + if (gpiob_spi_drivers[port_index][dout].driver.name) + kfree(gpiob_spi_drivers[port_index][dout].driver.name); + if (gpiob_spi_drivers[port_index][din].driver.name) + kfree(gpiob_spi_drivers[port_index][din].driver.name); + if (gpiob_spi_drivers[port_index][adc].driver.name) + kfree(gpiob_spi_drivers[port_index][adc].driver.name); + + // unregister SPI drivers spi_unregister_driver(&gpiob_spi_drivers[port_index][dout]); spi_unregister_driver(&gpiob_spi_drivers[port_index][din]); spi_unregister_driver(&gpiob_spi_drivers[port_index][adc]); + + // reset attribute index markers + port_info[port_index]->attrs_start = 0; + port_info[port_index]->attrs_end = 0; + return true; } -static struct ap_info gpiob_info = { - .product_id = MTAC_GPIOB_0_0, - .setup = &gpiob_setup, - .teardown = &gpiob_teardown -}; +bool set_gpiob_info(struct ap_info* info) { + info->product_id = MTAC_GPIOB_0_0; + info->setup = &gpiob_setup; + info->teardown = &gpiob_teardown; + info->attrs_start = 0; + info->attrs_end = 0; + + return true; +} diff --git a/io-module/mtac_mfser.c b/io-module/mtac_mfser.c index 5871bfe..207180f 100644 --- a/io-module/mtac_mfser.c +++ b/io-module/mtac_mfser.c @@ -190,6 +190,7 @@ static ssize_t mts_attr_store_mfser_mode(struct kobject *kobj, static int ap_mfser_attrs_size = 3; static bool mfser_setup(enum ap port) { + int port_index = port - 1; struct kobj_attribute *attr; char buf[32]; @@ -200,6 +201,10 @@ static bool mfser_setup(enum ap port) { return false; } + // mark the attribute indices we're using so we know what to clean up + port_info[port_index]->attrs_start = device_attrs_size; + port_info[port_index]->attrs_end = device_attrs_size + ap_mfser_attrs_size; + sprintf(buf, "serial-mode:%d", port); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { @@ -234,12 +239,33 @@ static bool mfser_setup(enum ap port) { } static bool mfser_teardown(enum ap port) { + int i; + int port_index = port - 1; + log_info("unloading MFSER accessory card in port %d", port); + + // clean up allocated memory for attributes + for (i = port_info[port_index]->attrs_start; i < port_info[port_index]->attrs_end; i++) { + if (device_attrs[i]) { + if (device_attrs[i]->name) + kfree(device_attrs[i]->name); + + kfree(device_attrs[i]); + } + } + + port_info[port_index]->attrs_start = 0; + port_info[port_index]->attrs_end = 0; + return true; } -static struct ap_info mfser_info = { - .product_id = MTAC_MFSER_0_0, - .setup = &mfser_setup, - .teardown = &mfser_teardown -}; +bool set_mfser_info(struct ap_info* info) { + info->product_id = MTAC_MFSER_0_0; + info->setup = &mfser_setup; + info->teardown = &mfser_teardown; + info->attrs_start = 0; + info->attrs_end = 0; + + return true; +} diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 936d0d2..8b982c6 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -434,10 +434,22 @@ static bool load_port(int port) { } else if (mts_ap_eeprom[port_index][0] == 0x00) { log_info("no accessory card inserted in port %d", port); } else { + port_info[port_index] = kzalloc(sizeof(struct ap_info), GFP_KERNEL); + if (! port_info[port_index]) { + log_error("alloc of port info failed"); + return false; + } + if (strstr(ap_eeprom[port_index].product_id, PRODUCT_ID_MTAC_GPIOB)) { - port_info[port_index] = &gpiob_info; + if (! set_gpiob_info(port_info[port_index])) { + log_error("failed to set up gpiob port info"); + return false; + } } else if (strstr(ap_eeprom[port_index].product_id, PRODUCT_ID_MTAC_MFSER)) { - port_info[port_index] = &mfser_info; + if (! set_mfser_info(port_info[port_index])) { + log_error("failed to set up mfser port info"); + return false; + } } else { log_error("unknown accessory card [%s] in port %d", ap_eeprom[port_index].product_id, port); return false; @@ -461,6 +473,7 @@ static bool load_port(int port) { if (! port_info[port_index]->setup(port)) { log_error("accessory port %d setup failed", port); port_info[port_index]->teardown(port); + kfree(port_info[port]); return false; } } @@ -645,7 +658,8 @@ static int __init mts_io_init(void) int ret; size_t device_attributes_size; size_t card_attributes_size; - int i; + int port; + int port_index; log_info("init: " DRIVER_VERSION); @@ -655,8 +669,8 @@ static int __init mts_io_init(void) } if (NUM_AP) { - for (i = 0; i < NUM_AP; i++) { - port_info[i] = NULL; + for (port = 0; port < NUM_AP; port++) { + port_info[port] = NULL; } init_accessory_ports(); } @@ -785,9 +799,10 @@ error2: platform_device_put(mts_io_platform_device); error1: log_error("init failed: %d", ret); - for (i = 0; i < NUM_AP; i++) { - if (port_info[i]) { - port_info[i]->teardown(i); + for (port = 0, port_index = 1; port < NUM_AP; port++, port_index++) { + if (port_info[port]) { + port_info[port]->teardown(port_index); + kfree(port_info[port]); } } @@ -796,7 +811,8 @@ error1: static void __exit mts_io_exit(void) { - int i; + int port; + int port_index; if ( mts_product_id != MT100EOCG_0_0 ) { cancel_delayed_work_sync(&reset_work); @@ -824,9 +840,10 @@ static void __exit mts_io_exit(void) platform_device_unregister(mts_io_platform_device); - for (i = 0; i < NUM_AP; i++) { - if (port_info[i]) { - port_info[i]->teardown(i); + for (port = 0, port_index = 1; port < NUM_AP; port++, port_index++) { + if (port_info[port]) { + port_info[port]->teardown(port_index); + kfree(port_info[port]); } } diff --git a/io-module/mts_io.h b/io-module/mts_io.h index ac39463..2aedd3e 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -120,6 +120,8 @@ struct ap_info { uint8_t product_id; bool (*setup)(enum ap port); bool (*teardown)(enum ap port); + int attrs_start; + int attrs_end; }; #endif /* ~__MTS_IO_H */ -- cgit v1.2.3 From 8f1a0efb9e68a955544bce4bbc9dec6e4cb57f61 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Thu, 25 Sep 2014 15:52:29 -0500 Subject: mts-io: add accessory card eeprom contents as read-only sysfs attribtues --- io-module/mtac.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ io-module/mtac_gpiob.c | 14 ++++++-- io-module/mtac_mfser.c | 12 ++++++- io-module/mts_io.h | 1 + 4 files changed, 115 insertions(+), 3 deletions(-) diff --git a/io-module/mtac.c b/io-module/mtac.c index b9a2520..99e2ce7 100644 --- a/io-module/mtac.c +++ b/io-module/mtac.c @@ -20,3 +20,94 @@ static struct kobj_attribute* create_attribute(const char* _name, umode_t _mode) return _attr; } + +static ssize_t ap_show_product_info(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { + ssize_t value; + int port; + + if (sscanf(attr->attr.name, "vendor-id:%d", &port) > 0) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].vendor_id); + } else if (sscanf(attr->attr.name, "product-id:%d", &port) > 0) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].product_id); + } else if (sscanf(attr->attr.name, "device-id:%d", &port) > 0) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].device_id); + } else if (sscanf(attr->attr.name, "hw-version:%d", &port) > 0) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].hw_version); + } else if (sscanf(attr->attr.name, "mac-eth:%d", &port) > 0) { + value = sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", + ap_eeprom[port - 1].mac_addr[0], + ap_eeprom[port - 1].mac_addr[1], + ap_eeprom[port - 1].mac_addr[2], + ap_eeprom[port - 1].mac_addr[3], + ap_eeprom[port - 1].mac_addr[4], + ap_eeprom[port - 1].mac_addr[5]); + } else { + log_error("attribute '%s' not found", attr->attr.name); + value = -1; + } + + return value; +} + +static bool ap_add_product_info_attributes(int port, int type) { + struct kobj_attribute *attr; + char buf[32]; + + switch (type) { + case MTAC_ETH_0_0: + sprintf(buf, "mac-eth:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = ap_show_product_info; + device_attrs[device_attrs_size++] = &attr->attr; + break; + + case MTAC_GPIOB_0_0: + case MTAC_MFSER_0_0: + break; + default: + log_error("invalid accessory card type"); + return false; + } + + sprintf(buf, "vendor-id:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = ap_show_product_info; + device_attrs[device_attrs_size++] = &attr->attr; + + sprintf(buf, "product-id:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = ap_show_product_info; + device_attrs[device_attrs_size++] = &attr->attr; + + sprintf(buf, "device-id:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = ap_show_product_info; + device_attrs[device_attrs_size++] = &attr->attr; + + sprintf(buf, "hw-version:%d", port); + attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! attr) { + log_error("failed to create attribute[%s]", buf); + return false; + } + attr->show = ap_show_product_info; + device_attrs[device_attrs_size++] = &attr->attr; + + return true; +} diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c index f2cd9b2..ebbe0c6 100644 --- a/io-module/mtac_gpiob.c +++ b/io-module/mtac_gpiob.c @@ -380,7 +380,11 @@ static bool gpiob_spi_driver_setup(struct spi_driver *driver, const char *driver // 2 LEDs // 1 digital out enable // 1 reset -static int ap_gpiob_attrs_size = 15; +// 1 vendor-id +// 1 product-id +// 1 device-id +// 1 hw-version +static int ap_gpiob_attrs_size = 19; static bool gpiob_setup(enum ap port) { int i; @@ -449,7 +453,13 @@ static bool gpiob_setup(enum ap port) { device_attrs[device_attrs_size++] = &attr->attr; } - // misc attributes + // add attributes for eeprom contents + if (! ap_add_product_info_attributes(port, MTAC_GPIOB_0_0)) { + log_error("failed to add product info attributes"); + return false; + } + + // add misc attributes sprintf(buf, "ap-dout-enable:%d", port); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { diff --git a/io-module/mtac_mfser.c b/io-module/mtac_mfser.c index 207180f..ed97cc6 100644 --- a/io-module/mtac_mfser.c +++ b/io-module/mtac_mfser.c @@ -187,7 +187,11 @@ static ssize_t mts_attr_store_mfser_mode(struct kobject *kobj, // 1 serial mode // 1 rs4xx term resistor // 1 rts override -static int ap_mfser_attrs_size = 3; +// 1 vendor-id +// 1 product-id +// 1 device-id +// 1 hw-version +static int ap_mfser_attrs_size = 7; static bool mfser_setup(enum ap port) { int port_index = port - 1; @@ -235,6 +239,12 @@ static bool mfser_setup(enum ap port) { attr->store = mts_attr_store_ap_mfser_pin; device_attrs[device_attrs_size++] = &attr->attr; + // add attributes for eeprom contents + if (! ap_add_product_info_attributes(port, MTAC_MFSER_0_0)) { + log_error("failed to add product info attributes"); + return false; + } + return true; } diff --git a/io-module/mts_io.h b/io-module/mts_io.h index 2aedd3e..44fb03c 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -81,6 +81,7 @@ enum { MTAC_NONE, MTAC_GPIOB_0_0, MTAC_MFSER_0_0, + MTAC_ETH_0_0, }; // GPIO pin types:input, output, open drain (1 = high Z, 0 = output low) -- cgit v1.2.3 From 4c4f2f12985dc811898ebbf6d14de43874e3ca9d Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Mon, 29 Sep 2014 09:48:24 -0500 Subject: mts-io: remove support for mtr2/mtocgd2/mtocgd hardware since they aren't actual products add Mike Fiore to list of maintainers remove unused variables --- io-module/mtr2.c | 515 ----------------------------------------------------- io-module/mts_io.c | 42 +---- io-module/mts_io.h | 11 -- 3 files changed, 1 insertion(+), 567 deletions(-) delete mode 100644 io-module/mtr2.c diff --git a/io-module/mtr2.c b/io-module/mtr2.c deleted file mode 100644 index 2efc85d..0000000 --- a/io-module/mtr2.c +++ /dev/null @@ -1,515 +0,0 @@ - -static struct gpio_pin gpio_pins_mtr2_0_0[] = { - { - .name = "NETH_RST", - .pin = { - .gpio = AT91_PIN_PC6, - .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH, - .label = "eth-switch-enabled", - }, - }, - { - .name = "RADIO_RESET", - .pin = { - .gpio = AT91_PIN_PC5, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "radio-reset", - }, - }, - { - .name = "RADIO_RESET", - .pin = { - .gpio = AT91_PIN_PC5, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "radio-power", - }, - }, - { - .name = "DEVICE_RESET", - .pin = { - .gpio = AT91_PIN_PC4, - .flags = GPIOF_IN, - .label = "reset", - }, - .active_low = 1, - }, - { - .name = "LS_LED", - .pin = { - .gpio = AT91_PIN_PA14, -#if LED_LS_CONTROLLABLE - .flags = GPIOF_OUT_INIT_HIGH, -#else - .flags = GPIOF_IN, -#endif - .label = "led-ls", - }, - .active_low = 1, - }, - { - .name = "STATUS_LED", - .pin = { - .gpio = AT91_PIN_PA24, - .flags = GPIOF_OUT_INIT_LOW, - .label = "led-status", - }, - .active_low = 1, - }, - { - .name = "STATUS_LED", - .pin = { - .gpio = AT91_PIN_PA24, - .flags = GPIOF_OUT_INIT_LOW, - .label = "led-a", - }, - .active_low = 1, - }, - { - .name = "LED7", - .pin = { - .gpio = AT91_PIN_PA25, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-cd", - }, - .active_low = 1, - }, - { - .name = "LED7", - .pin = { - .gpio = AT91_PIN_PA25, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-c", - }, - .active_low = 1, - }, - { - .name = "LED10", - .pin = { - .gpio = AT91_PIN_PA26, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig1", - }, - .active_low = 1, - }, - { - .name = "LED10", - .pin = { - .gpio = AT91_PIN_PA26, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-d", - }, - .active_low = 1, - }, - { - .name = "LED11", - .pin = { - .gpio = AT91_PIN_PA27, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig2", - }, - .active_low = 1, - }, - { - .name = "LED11", - .pin = { - .gpio = AT91_PIN_PA27, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-e", - }, - .active_low = 1, - }, - { - .name = "LED12", - .pin = { - .gpio = AT91_PIN_PA28, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig3", - }, - .active_low = 1, - }, - { - .name = "LED12", - .pin = { - .gpio = AT91_PIN_PA28, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-f", - }, - .active_low = 1, - }, - { - .name = "LED13", - .pin = { - .gpio = AT91_PIN_PA29, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-wifi", - }, - .active_low = 1, - }, - { - .name = "LED13", - .pin = { - .gpio = AT91_PIN_PA29, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-b", - }, - .active_low = 1, - }, - { - .name = "UART3_DTR", - .pin = { - .gpio = AT91_PIN_PC12, - .flags = GPIOF_IN, - .label = "extserial-dtr", - }, - .active_low = 1, - }, - { - .name = "UART3_DSR", - .pin = { - .gpio = AT91_PIN_PC11, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-dsr", - }, - .active_low = 1, - }, - { - .name = "UART3_DCD", - .pin = { - .gpio = AT91_PIN_PC10, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-dcd", - }, - .active_low = 1, - }, - { - .name = "UART3_RI", - .pin = { - .gpio = AT91_PIN_PC13, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-ri", - }, - .active_low = 1, - }, - { - .name = "NDC_RESET", - .pin = { - .gpio = AT91_PIN_PC3, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "ndc-reset", - }, - }, - { - .name = "NDC_EEPROM_WRITE_PROTECT", - .pin = { - .gpio = AT91_PIN_PC26, - .flags = GPIOF_OUT_INIT_LOW, - .label = "ndc-eeprom-wp", - }, - }, - { - .name = "BT_EN", - .pin = { - .gpio = AT91_PIN_PD21, - .flags = GPIOF_OUT_INIT_LOW, - .label = "bt-enabled", - }, - }, - { - .name = "WLAN_EN", - .pin = { - .gpio = AT91_PIN_PC1, - .flags = GPIOF_OUT_INIT_LOW, - .label = "wlan-enabled", - }, - }, - { - .name = "SERIAL_MODE0", - .pin = { - .gpio = AT91_PIN_PC23, - .flags = GPIOF_OUT_INIT_LOW, - .label = "serial-mode", - }, - }, - { - .name = "SERIAL_MODE1", - .pin = { - .gpio = AT91_PIN_PC24, - .flags = GPIOF_OUT_INIT_LOW, - .label = "serial-mode", - }, - }, - { - .name = "SERIAL_MODE2", - .pin = { - .gpio = AT91_PIN_PC25, - .flags = GPIOF_OUT_INIT_LOW, - .label = "serial-mode", - }, - }, - { - .name = "RS4XX_TERM_RES", - .pin = { - .gpio = AT91_PIN_PC26, - .flags = GPIOF_OUT_INIT_LOW, - .label = "rs4xx-term-res", - }, - }, - { - .name = "NDC_GPIO1", - .pin = { - .gpio = AT91_PIN_PC0, - .flags = GPIOF_OUT_INIT_LOW, - .label = "dc-gpio1", - }, - }, - { - .name = "NDC_GPIO2", - .pin = { - .gpio = AT91_PIN_PC14, - .flags = GPIOF_OUT_INIT_LOW, - .label = "dc-gpio2", - }, - }, - { - .name = "NDC_GPIO3", - .pin = { - .gpio = AT91_PIN_PC29, - .flags = GPIOF_OUT_INIT_LOW, - .label = "dc-gpio3", - }, - }, - { - .name = "NDC_GPIO4", - .pin = { - .gpio = AT91_PIN_PC30, - .flags = GPIOF_OUT_INIT_LOW, - .label = "dc-gpio4", - }, - }, - { - .name = "NDC_INTERRUPT1", - .pin = { - .gpio = AT91_PIN_PC20, - .flags = GPIOF_IN, - .label = "dc-int1", - }, - }, - { - .name = "NDC_INTERRUPT2", - .pin = { - .gpio = AT91_PIN_PC21, - .flags = GPIOF_IN, - .label = "dc-int2", - }, - }, - { }, -}; - -/* MTOCGD2 specific functions */ -static ssize_t mts_attr_show_serial_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - int smode0; - int smode1; - int smode2; - - struct gpio_pin *pin_smode0 = gpio_pin_by_name("SERIAL_MODE0"); - struct gpio_pin *pin_smode1 = gpio_pin_by_name("SERIAL_MODE1"); - struct gpio_pin *pin_smode2 = gpio_pin_by_name("SERIAL_MODE2"); - - if (!pin_smode0 || !pin_smode1 || !pin_smode2) - return -ENODEV; - - mutex_lock(&mts_io_mutex); - - smode0 = gpio_get_value(pin_smode0->pin.gpio); - smode1 = gpio_get_value(pin_smode1->pin.gpio); - smode2 = gpio_get_value(pin_smode2->pin.gpio); - - if (smode2 == 0 && smode1 == 0 && smode0 == 1) - ret = sprintf(buf, "rs232\n"); - else if (smode2 == 0 && smode1 == 1 && smode0 == 0) - ret = sprintf(buf, "rs485\n"); - else if (smode2 == 1 && smode1 == 0 && smode0 == 0) - ret = sprintf(buf, "rs422\n"); - else if (smode2 == 0 && smode1 == 0 && smode0 == 0) - ret = sprintf(buf, "loopback\n"); - else - ret = sprintf(buf, "error\n"); - - mutex_unlock(&mts_io_mutex); - - return ret; -} - -static ssize_t mts_attr_store_serial_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int smode0; - int smode1; - int smode2; - struct gpio_pin *pin_smode0 = gpio_pin_by_name("SERIAL_MODE0"); - struct gpio_pin *pin_smode1 = gpio_pin_by_name("SERIAL_MODE1"); - struct gpio_pin *pin_smode2 = gpio_pin_by_name("SERIAL_MODE2"); - - if (!pin_smode0 || !pin_smode1 || !pin_smode2) - return -ENODEV; - - if (!strcasecmp(buf, "rs232")) { - smode2 = 0; - smode1 = 0; - smode0 = 1; - } - else if (!strcasecmp(buf, "rs485")) { - smode2 = 0; - smode1 = 1; - smode0 = 0; - } - else if (!strcasecmp(buf, "rs422")) { - smode2 = 1; - smode1 = 0; - smode0 = 0; - } - else if (!strcasecmp(buf, "loopback")) { - smode2 = 0; - smode1 = 0; - smode0 = 0; - } - else { - return -EINVAL; - } - - mutex_lock(&mts_io_mutex); - - gpio_set_value(pin_smode2->pin.gpio, smode2); - gpio_set_value(pin_smode1->pin.gpio, smode1); - gpio_set_value(pin_smode0->pin.gpio, smode0); - - mutex_unlock(&mts_io_mutex); - - return count; -} - -/* MTOCGD2 specific attributes */ -static DEVICE_ATTR_MTS(dev_attr_serial_mode, "serial-mode", - mts_attr_show_serial_mode, mts_attr_store_serial_mode); -static DEVICE_ATTR_MTS(dev_attr_eth_switch_enabled, "eth-switch-enabled", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_rs4xx_term_res, "rs4xx-term-res", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); - -static struct attribute *mtr2_platform_attributes[] = { - &dev_attr_vendor_id.attr, - &dev_attr_product_id.attr, - &dev_attr_device_id.attr, - &dev_attr_hw_version.attr, - &dev_attr_imei.attr, - &dev_attr_eth_mac.attr, - &dev_attr_wifi_mac.attr, - &dev_attr_reset.attr, - &dev_attr_reset_monitor.attr, - &dev_attr_radio_power.attr, - &dev_attr_radio_reset.attr, - &dev_attr_ndc_reset.attr, - &dev_attr_extserial_dtr.attr, - &dev_attr_extserial_dsr_gpio.attr, - &dev_attr_extserial_ri_gpio.attr, - &dev_attr_extserial_dcd_gpio.attr, - &dev_attr_eth_switch_enabled.attr, - &dev_attr_bt_enabled.attr, - &dev_attr_wlan_enabled.attr, - - &dev_attr_serial_mode.attr, - &dev_attr_rs4xx_term_res.attr, - - &dev_attr_led_status.attr, - &dev_attr_led_wifi_gpio.attr, - &dev_attr_led_cd_gpio.attr, - &dev_attr_led_sig1_gpio.attr, - &dev_attr_led_sig2_gpio.attr, - &dev_attr_led_sig3_gpio.attr, - - &dev_attr_led_a_gpio.attr, - &dev_attr_led_b_gpio.attr, - &dev_attr_led_c_gpio.attr, - &dev_attr_led_d_gpio.attr, - &dev_attr_led_e_gpio.attr, - &dev_attr_led_f_gpio.attr, - - &dev_attr_board_temperature.attr, - - /* extra space for the daughter card attributes */ - NULL, // index 34 - NULL, // index 35 - NULL, // index 36 - NULL, // index 37 - NULL, // index 38 - NULL, // index 39 - NULL, // index 40 - NULL, // index 41 - NULL, // index 42 - NULL, // index 43 - NULL, // index 44 - NULL, // index 45 - NULL, // index 46 - NULL, // index 47 - NULL, // index 48 - NULL, // index 49 - NULL, // index 50 - NULL, // index 51 - NULL, -}; - -static struct attribute *mtr2_daughter_card_attributes[] = { - &dev_attr_dc_din0.attr, - &dev_attr_dc_din1.attr, - &dev_attr_dc_din2.attr, - &dev_attr_dc_din3.attr, - - &dev_attr_dc_dout0.attr, - &dev_attr_dc_dout1.attr, - &dev_attr_dc_dout2.attr, - &dev_attr_dc_dout3.attr, - - &dev_attr_dc_adc0.attr, - &dev_attr_dc_adc1.attr, - &dev_attr_dc_adc2.attr, - - &dev_attr_dc_led1.attr, - &dev_attr_dc_led2.attr, - &dev_attr_dc_oe.attr, - - NULL, -}; - -static bool mtr2_add_daughter_card_attributes(void) -{ - size_t platform_attrs_size = sizeof(mtr2_platform_attributes) / sizeof(struct attribute *); - size_t daughter_card_attrs_size = sizeof(mtr2_daughter_card_attributes) / sizeof(struct attribute *); - size_t platform_attrs_index; - size_t daughter_card_attrs_index; - size_t copy_length = daughter_card_attrs_size - 1; /* don't need to copy the NULL at the end */ - - for (platform_attrs_index = 0; platform_attrs_index < platform_attrs_size; platform_attrs_index++) { - if (! mtr2_platform_attributes[platform_attrs_index]) { - break; - } - } - - if (platform_attrs_size < platform_attrs_index + daughter_card_attrs_size) { - log_error("not enough room for MTR2 daughter card attributes!"); - return false; - } - - for (daughter_card_attrs_index = 0; daughter_card_attrs_index < copy_length; daughter_card_attrs_index++, platform_attrs_index++) { - mtr2_platform_attributes[platform_attrs_index] = mtr2_daughter_card_attributes[daughter_card_attrs_index]; - } - - return true; -} - -static struct attribute_group mtr2_platform_attribute_group = { - .attrs = mtr2_platform_attributes -}; diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 8b982c6..15a70a3 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -5,6 +5,7 @@ * * Authors: James Maki * Jesse Gilles + * Mike Fiore * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -416,7 +417,6 @@ 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 "mtr.c" #include "mtr2d2.c" @@ -526,15 +526,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; - mts_product_id = MTR2_0_0; - has_spi_sout = 0; - has_spi_din = 0; - 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; @@ -554,35 +545,6 @@ 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; - mts_product_id = MTOCGD2_0_0; - has_spi_sout = 0; - has_spi_din = 0; - 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; - mts_product_id = MTOCGD_0_0; - has_spi_sout = 0; - has_spi_din = 0; - has_spi_dout = 0; - has_spi_temp = 0; - log_info("detected board %s", HW_VERSION_MTOCGD_0_0); - } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTOCGD_0_1, strlen(HW_VERSION_MTOCGD_0_1)) == 0) { - attr_group = &mtr_platform_attribute_group; - gpio_pins = gpio_pins_mtr_0_1; - mts_product_id = MTOCGD_0_1; - has_spi_sout = 0; - has_spi_din = 0; - has_spi_dout = 0; - 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 @@ -656,8 +618,6 @@ static int __init mts_io_init(void) { struct gpio_pin *pin; int ret; - size_t device_attributes_size; - size_t card_attributes_size; int port; int port_index; diff --git a/io-module/mts_io.h b/io-module/mts_io.h index 44fb03c..f469b83 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -42,10 +42,7 @@ struct device_attribute _dev_name = { \ #define VENDOR_ID_MULTITECH "Multi-Tech Systems" #define PRODUCT_ID_MTCDP_E1_DK "MTCDP-E1-DK" #define PRODUCT_ID_MT100EOCG "MT100EOCG" -#define PRODUCT_ID_MTR2 "MTR2" #define PRODUCT_ID_MTR "MTR" -#define PRODUCT_ID_MTOCGD2 "MTOCGD2" -#define PRODUCT_ID_MTOCGD "MTOCGD" #define PRODUCT_ID_MTR2D2 "MTR2D2" #define PRODUCT_ID_MTAC_GPIOB "MTAC-GPIOB" @@ -56,24 +53,16 @@ struct device_attribute _dev_name = { \ #define HW_VERSION_MTCDP_0_0 "MTCDP-0.0" #define HW_VERSION_MTCDP_1_0 "MTCDP-1.0" #define HW_VERSION_MT100EOCG_0_0 "MT100EOCG-0.0" -#define HW_VERSION_MTR2_0_0 "MTR2-0.0" #define HW_VERSION_MTR_0_0 "MTR-0.0" #define HW_VERSION_MTR_0_1 "MTR-0.1" -#define HW_VERSION_MTOCGD2_0_0 "MTOCGD2-0.0" -#define HW_VERSION_MTOCGD_0_0 "MTOCGD-0.0" -#define HW_VERSION_MTOCGD_0_1 "MTOCGD-0.1" #define HW_VERSION_MTR2D2_0_0 "MTR2D2-0.0" enum { MTCDP_E1_DK_0_0, MTCDP_E1_DK_1_0, MT100EOCG_0_0, - MTR2_0_0, MTR_0_0, MTR_0_1, - MTOCGD2_0_0, - MTOCGD_0_0, - MTOCGD_0_1, MTR2D2_0_0, }; -- cgit v1.2.3 From 0f27f5666932274a30ca018c7dacfd7a9e5fc8bb Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 1 Oct 2014 08:41:26 -0500 Subject: mts-io: standardize lookup of pin name by attribute name 1 set of functions for ap gpio pin store and show each type of card defines a callback that specifies the mapping of attribute names to pin names --- io-module/mtac.c | 86 ++++++++++++++++++++++++++++++++++++++ io-module/mtac_gpiob.c | 109 +++++++++---------------------------------------- io-module/mtac_mfser.c | 100 ++++++++------------------------------------- io-module/mts_io.h | 1 + 4 files changed, 123 insertions(+), 173 deletions(-) diff --git a/io-module/mtac.c b/io-module/mtac.c index 99e2ce7..1c88b40 100644 --- a/io-module/mtac.c +++ b/io-module/mtac.c @@ -111,3 +111,89 @@ static bool ap_add_product_info_attributes(int port, int type) { return true; } + +struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { + struct gpio_pin *pin; + char *pin_attr_name; + long port; + int port_index; + char *colon; + + colon = strstr(name, ":"); + if (colon && ++colon) { + if (kstrtol(colon, 10, &port)) { + log_error("kstrtol failed on [%s]", colon); + return NULL; + } + } else { + log_error("could not read port from attr name [%s]", name); + return NULL; + } + port_index = port - 1; + + pin_attr_name = port_info[port_index]->gpio_pin_name_by_attr_name(name); + + for (pin = gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->pin.label, pin_attr_name)) { + return pin; + } + } + + log_error("pin with attr name [%s] not found", name); + return NULL; +} + +static ssize_t mts_attr_show_ap_gpio_pin(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int value; + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + mutex_lock(&mts_io_mutex); + + value = gpio_get_value(pin->pin.gpio); + + mutex_unlock(&mts_io_mutex); + + if (value < 0) { + return value; + } + + if (pin->active_low) { + value = !value; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t mts_attr_store_ap_gpio_pin(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int value; + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + if (sscanf(buf, "%i", &value) != 1) { + return -EINVAL; + } + + if (pin->active_low) { + value = !value; + } + + mutex_lock(&mts_io_mutex); + + gpio_set_value(pin->pin.gpio, value); + + mutex_unlock(&mts_io_mutex); + + return count; +} diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c index ebbe0c6..ce1d7de 100644 --- a/io-module/mtac_gpiob.c +++ b/io-module/mtac_gpiob.c @@ -105,97 +105,27 @@ static int mts_spi_ap_remove(struct spi_device *spi) return 0; } -// Is there a way to make this dynamic as well? -struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { - struct gpio_pin *pin; - char *pin_attr_name; - - if (!strcmp(name, "ap-led1:1")) { - pin_attr_name = "ap1-gpio3"; - } else if (!strcmp(name, "ap-led2:1")) { - pin_attr_name = "ap1-gpio4"; - } else if (!strcmp(name, "ap-dout-enable:1")) { - pin_attr_name = "ap1-gpio1"; - } else if (!strcmp(name, "ap-reset:1")) { - pin_attr_name = "ap1-reset"; - } else if (!strcmp(name, "ap-led1:2")) { - pin_attr_name = "ap2-gpio3"; - } else if (!strcmp(name, "ap-led2:2")) { - pin_attr_name = "ap2-gpio4"; - } else if (!strcmp(name, "ap-dout-enable:2")) { - pin_attr_name = "ap2-gpio1"; - } else if (!strcmp(name, "ap-reset:2")) { - pin_attr_name = "ap2-reset"; +static char* gpiob_gpio_pin_name_by_attr_name(const char* name) { + if (! strcmp(name, "ap-led1:1")) { + return "ap1-gpio3"; + } else if (! strcmp(name, "ap-led2:1")) { + return "ap1-gpio4"; + } else if (! strcmp(name, "ap-dout-enable:1")) { + return "ap1-gpio1"; + } else if (! strcmp(name, "ap-reset:1")) { + return "ap1-reset"; + } else if (! strcmp(name, "ap-led1:2")) { + return "ap2-gpio3"; + } else if (! strcmp(name, "ap-led2:2")) { + return "ap2-gpio4"; + } else if (! strcmp(name, "ap-dout-enable:2")) { + return "ap2-gpio1"; + } else if (! strcmp(name, "ap-reset:2")) { + return "ap2-reset"; } else { - log_error("accessory card attribute %s not available", name); - return NULL; + log_error("attirbute name [%s] is invalid for GPIOB", name); + return ""; } - - for (pin = gpio_pins; *pin->name; pin++) { - if (!strcmp(pin->pin.label, pin_attr_name)) { - return pin; - } - } - - log_error("pin with attr name %s not found", name); - - return NULL; -} - - -static ssize_t mts_attr_show_ap_gpio_pin(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - int value; - struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); - - if (!pin) { - return -ENODEV; - } - - mutex_lock(&mts_io_mutex); - - value = gpio_get_value(pin->pin.gpio); - - mutex_unlock(&mts_io_mutex); - - if (value < 0) { - return value; - } - - if (pin->active_low) { - value = !value; - } - - return sprintf(buf, "%d\n", value); -} - -static ssize_t mts_attr_store_ap_gpio_pin(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - int value; - struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); - - if (!pin) { - return -ENODEV; - } - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - - if (pin->active_low) { - value = !value; - } - - mutex_lock(&mts_io_mutex); - - gpio_set_value(pin->pin.gpio, value); - - mutex_unlock(&mts_io_mutex); - - return count; } static ssize_t mts_attr_show_ap_din(struct kobject *kobj, struct kobj_attribute *attr, char *buf) @@ -561,6 +491,7 @@ bool set_gpiob_info(struct ap_info* info) { info->teardown = &gpiob_teardown; info->attrs_start = 0; info->attrs_end = 0; + info->gpio_pin_name_by_attr_name = &gpiob_gpio_pin_name_by_attr_name; return true; } diff --git a/io-module/mtac_mfser.c b/io-module/mtac_mfser.c index ed97cc6..7c5862c 100644 --- a/io-module/mtac_mfser.c +++ b/io-module/mtac_mfser.c @@ -1,85 +1,16 @@ -struct gpio_pin *ap_mfser_pin_by_attr_name(const char *name) { - struct gpio_pin *pin; - char *pin_attr_name; - - if (!strcmp(name, "rs4xx-term-res:1")) { - pin_attr_name = "ap1-gpio3"; - } else if (!strcmp(name, "rts-override:1")) { - pin_attr_name = "ap1-gpio4"; - } else if (!strcmp(name, "rs4xx-term-res:2")) { - pin_attr_name = "ap2-gpio3"; - } else if (!strcmp(name, "rts-override:2")) { - pin_attr_name = "ap2-gpio4"; +static char* mfser_gpio_pin_name_by_attr_name(const char* name) { + if (! strcmp(name, "rs4xx-term-res:1")) { + return "ap1-gpio3"; + } else if (! strcmp(name, "rts-override:1")) { + return "ap1-gpio4"; + } else if (! strcmp(name, "rs4xx-term-res:2")) { + return "ap2-gpio3"; + } else if (! strcmp(name, "rts-override:2")) { + return "ap2-gpio4"; } else { - log_error("accessory card attribute %s not available", name); - return NULL; + log_error("attirbute name [%s] is invalid for MFSER", name); + return ""; } - - for (pin = gpio_pins; *pin->name; pin++) { - if (!strcmp(pin->pin.label, pin_attr_name)) { - return pin; - } - } - - log_error("pin with attr name %s not found", name); - - return NULL; -} - - -static ssize_t mts_attr_show_ap_mfser_pin(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - int value; - struct gpio_pin *pin = ap_mfser_pin_by_attr_name(attr->attr.name); - - if (!pin) { - return -ENODEV; - } - - mutex_lock(&mts_io_mutex); - - value = gpio_get_value(pin->pin.gpio); - - mutex_unlock(&mts_io_mutex); - - if (value < 0) { - return value; - } - - if (pin->active_low) { - value = !value; - } - - return sprintf(buf, "%d\n", value); -} - -static ssize_t mts_attr_store_ap_mfser_pin(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - int value; - struct gpio_pin *pin = ap_mfser_pin_by_attr_name(attr->attr.name); - - if (!pin) { - return -ENODEV; - } - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - - if (pin->active_low) { - value = !value; - } - - mutex_lock(&mts_io_mutex); - - gpio_set_value(pin->pin.gpio, value); - - mutex_unlock(&mts_io_mutex); - - return count; } static ssize_t mts_attr_show_mfser_mode(struct kobject *kobj, @@ -225,8 +156,8 @@ static bool mfser_setup(enum ap port) { log_error("failed to create attribute[%s]", buf); return false; } - attr->show = mts_attr_show_ap_mfser_pin; - attr->store = mts_attr_store_ap_mfser_pin; + attr->show = mts_attr_show_ap_gpio_pin; + attr->store = mts_attr_store_ap_gpio_pin; device_attrs[device_attrs_size++] = &attr->attr; sprintf(buf, "rts-override:%d", port); @@ -235,8 +166,8 @@ static bool mfser_setup(enum ap port) { log_error("failed to create attribute[%s]", buf); return false; } - attr->show = mts_attr_show_ap_mfser_pin; - attr->store = mts_attr_store_ap_mfser_pin; + attr->show = mts_attr_show_ap_gpio_pin; + attr->store = mts_attr_store_ap_gpio_pin; device_attrs[device_attrs_size++] = &attr->attr; // add attributes for eeprom contents @@ -276,6 +207,7 @@ bool set_mfser_info(struct ap_info* info) { info->teardown = &mfser_teardown; info->attrs_start = 0; info->attrs_end = 0; + info->gpio_pin_name_by_attr_name = &mfser_gpio_pin_name_by_attr_name; return true; } diff --git a/io-module/mts_io.h b/io-module/mts_io.h index f469b83..cc88392 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -112,6 +112,7 @@ struct ap_info { bool (*teardown)(enum ap port); int attrs_start; int attrs_end; + char* (*gpio_pin_name_by_attr_name)(const char* name); }; #endif /* ~__MTS_IO_H */ -- cgit v1.2.3 From 0f0c9bb72a3be330512e60677c4e3693347bf66b Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 1 Oct 2014 11:11:12 -0500 Subject: mts-io: remove "ap-" from gpiob gpio pin attributes --- io-module/mtac_gpiob.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c index ce1d7de..f8652c6 100644 --- a/io-module/mtac_gpiob.c +++ b/io-module/mtac_gpiob.c @@ -106,21 +106,21 @@ static int mts_spi_ap_remove(struct spi_device *spi) } static char* gpiob_gpio_pin_name_by_attr_name(const char* name) { - if (! strcmp(name, "ap-led1:1")) { + if (! strcmp(name, "led1:1")) { return "ap1-gpio3"; - } else if (! strcmp(name, "ap-led2:1")) { + } else if (! strcmp(name, "led2:1")) { return "ap1-gpio4"; - } else if (! strcmp(name, "ap-dout-enable:1")) { + } else if (! strcmp(name, "dout-enable:1")) { return "ap1-gpio1"; - } else if (! strcmp(name, "ap-reset:1")) { + } else if (! strcmp(name, "reset:1")) { return "ap1-reset"; - } else if (! strcmp(name, "ap-led1:2")) { + } else if (! strcmp(name, "led1:2")) { return "ap2-gpio3"; - } else if (! strcmp(name, "ap-led2:2")) { + } else if (! strcmp(name, "led2:2")) { return "ap2-gpio4"; - } else if (! strcmp(name, "ap-dout-enable:2")) { + } else if (! strcmp(name, "dout-enable:2")) { return "ap2-gpio1"; - } else if (! strcmp(name, "ap-reset:2")) { + } else if (! strcmp(name, "reset:2")) { return "ap2-reset"; } else { log_error("attirbute name [%s] is invalid for GPIOB", name); @@ -372,7 +372,7 @@ static bool gpiob_setup(enum ap port) { // add LEDs for (i = 1; i <= 2; i++) { - sprintf(buf, "ap-led%d:%d", i, port); + sprintf(buf, "led%d:%d", i, port); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { log_error("failed to create attribute[%s]", buf); @@ -390,7 +390,7 @@ static bool gpiob_setup(enum ap port) { } // add misc attributes - sprintf(buf, "ap-dout-enable:%d", port); + sprintf(buf, "dout-enable:%d", port); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { log_error("failed to create attribute[%s]", buf); @@ -400,7 +400,7 @@ static bool gpiob_setup(enum ap port) { attr->store = mts_attr_store_ap_gpio_pin; device_attrs[device_attrs_size++] = &attr->attr; - sprintf(buf, "ap-reset:%d", port); + sprintf(buf, "reset:%d", port); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { log_error("failed to create attribute[%s]", buf); -- cgit v1.2.3 From f9010f0863063e6836394469edf43e86c98d49fe Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Fri, 3 Oct 2014 15:09:42 -0500 Subject: mts-io: reorganize accessory card attributes, move them into subdirs under mts-io subdirs named ap1, ap2, etc create links to subdirs with name of card in port, e.g. gpiob, mfser, eth, etc if 2 of same type of card, still make links but use gpiob-2, mfser-2, etc --- io-module/mtac.c | 169 ++++++++++++++++++------------- io-module/mtac_gpiob.c | 262 ++++++++++++++++++++++++++++++------------------- io-module/mtac_mfser.c | 192 +++++++++++++++++++++++++----------- io-module/mts_io.c | 28 +++--- io-module/mts_io.h | 6 +- 5 files changed, 408 insertions(+), 249 deletions(-) diff --git a/io-module/mtac.c b/io-module/mtac.c index 1c88b40..9b27e0d 100644 --- a/io-module/mtac.c +++ b/io-module/mtac.c @@ -4,7 +4,7 @@ static struct kobj_attribute* create_attribute(const char* _name, umode_t _mode) _attr = kzalloc(sizeof(struct kobj_attribute), GFP_KERNEL); if (! _attr) { - log_error("kzalloc of attribute %s failed", _name); + log_error("kzalloc of attribute [%s] failed", _name); return NULL; } @@ -21,48 +21,79 @@ static struct kobj_attribute* create_attribute(const char* _name, umode_t _mode) return _attr; } +static int port_from_kobject(struct kobject *kobj) { + int port; + const char *name; + + name = kobj->name; + if (! name) { + log_error("kobject->name is NULL"); + return -1; + } + + if (sscanf(name, "ap%d", &port) < 1) { + log_error("failed to scan port from kobject->name [%s]", name); + return -1; + } + + if (port < 1 || port > NUM_AP) { + log_error("port number %d is invalid", port); + return -1; + } + + return port; +} + static ssize_t ap_show_product_info(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { ssize_t value; int port; + int port_index; - if (sscanf(attr->attr.name, "vendor-id:%d", &port) > 0) { - value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].vendor_id); - } else if (sscanf(attr->attr.name, "product-id:%d", &port) > 0) { - value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].product_id); - } else if (sscanf(attr->attr.name, "device-id:%d", &port) > 0) { - value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].device_id); - } else if (sscanf(attr->attr.name, "hw-version:%d", &port) > 0) { - value = snprintf(buf, 32, "%s\n", ap_eeprom[port - 1].hw_version); - } else if (sscanf(attr->attr.name, "mac-eth:%d", &port) > 0) { + port = port_from_kobject(kobj); + if (port < 1) { + log_error("port_from_kobject returned %d", port); + return -1; + } + port_index = port - 1; + + if (! strcmp(attr->attr.name, "vendor-id")) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port_index].vendor_id); + } else if (! strcmp(attr->attr.name, "product-id")) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port_index].product_id); + } else if (! strcmp(attr->attr.name, "device-id")) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port_index].device_id); + } else if (! strcmp(attr->attr.name, "hw-version")) { + value = snprintf(buf, 32, "%s\n", ap_eeprom[port_index].hw_version); + } else if (! strcmp(attr->attr.name, "mac-eth")) { value = sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", - ap_eeprom[port - 1].mac_addr[0], - ap_eeprom[port - 1].mac_addr[1], - ap_eeprom[port - 1].mac_addr[2], - ap_eeprom[port - 1].mac_addr[3], - ap_eeprom[port - 1].mac_addr[4], - ap_eeprom[port - 1].mac_addr[5]); + 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]); } else { - log_error("attribute '%s' not found", attr->attr.name); + log_error("attribute [%s] not found", attr->attr.name); value = -1; } return value; } -static bool ap_add_product_info_attributes(int port, int type) { - struct kobj_attribute *attr; +static bool ap_add_product_info_attributes(int port, int type, struct attribute** attrs, int* index) { char buf[32]; + struct kobj_attribute* kobj_attr; switch (type) { case MTAC_ETH_0_0: - sprintf(buf, "mac-eth:%d", port); - attr = create_attribute(buf, MTS_ATTR_MODE_RO); - if (! attr) { - log_error("failed to create attribute[%s]", buf); + sprintf(buf, "mac-eth"); + kobj_attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); return false; } - attr->show = ap_show_product_info; - device_attrs[device_attrs_size++] = &attr->attr; + kobj_attr->show = ap_show_product_info; + attrs[*index++] = &kobj_attr->attr; break; case MTAC_GPIOB_0_0: @@ -73,65 +104,51 @@ static bool ap_add_product_info_attributes(int port, int type) { return false; } - sprintf(buf, "vendor-id:%d", port); - attr = create_attribute(buf, MTS_ATTR_MODE_RO); - if (! attr) { - log_error("failed to create attribute[%s]", buf); + sprintf(buf, "vendor-id"); + kobj_attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); return false; } - attr->show = ap_show_product_info; - device_attrs[device_attrs_size++] = &attr->attr; + kobj_attr->show = ap_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; - sprintf(buf, "product-id:%d", port); - attr = create_attribute(buf, MTS_ATTR_MODE_RO); - if (! attr) { - log_error("failed to create attribute[%s]", buf); + sprintf(buf, "product-id"); + kobj_attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); return false; } - attr->show = ap_show_product_info; - device_attrs[device_attrs_size++] = &attr->attr; + kobj_attr->show = ap_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; - sprintf(buf, "device-id:%d", port); - attr = create_attribute(buf, MTS_ATTR_MODE_RO); - if (! attr) { - log_error("failed to create attribute[%s]", buf); + sprintf(buf, "device-id"); + kobj_attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); return false; } - attr->show = ap_show_product_info; - device_attrs[device_attrs_size++] = &attr->attr; + kobj_attr->show = ap_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; - sprintf(buf, "hw-version:%d", port); - attr = create_attribute(buf, MTS_ATTR_MODE_RO); - if (! attr) { - log_error("failed to create attribute[%s]", buf); + sprintf(buf, "hw-version"); + kobj_attr = create_attribute(buf, MTS_ATTR_MODE_RO); + if (! kobj_attr) { + log_error("failed to create attribute [%s] in port %d", buf, port); return false; } - attr->show = ap_show_product_info; - device_attrs[device_attrs_size++] = &attr->attr; + kobj_attr->show = ap_show_product_info; + attrs[(*index)++] = &kobj_attr->attr; return true; } -struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { +struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name, int port) { struct gpio_pin *pin; char *pin_attr_name; - long port; - int port_index; - char *colon; + int port_index = port - 1; - colon = strstr(name, ":"); - if (colon && ++colon) { - if (kstrtol(colon, 10, &port)) { - log_error("kstrtol failed on [%s]", colon); - return NULL; - } - } else { - log_error("could not read port from attr name [%s]", name); - return NULL; - } - port_index = port - 1; - - pin_attr_name = port_info[port_index]->gpio_pin_name_by_attr_name(name); + pin_attr_name = port_info[port_index]->gpio_pin_name_by_attr_name(name, port); for (pin = gpio_pins; *pin->name; pin++) { if (!strcmp(pin->pin.label, pin_attr_name)) { @@ -148,8 +165,16 @@ static ssize_t mts_attr_show_ap_gpio_pin(struct kobject *kobj, char *buf) { int value; - struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + int port; + struct gpio_pin *pin; + + port = port_from_kobject(kobj); + if (port < 1) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; + } + pin = ap_gpio_pin_by_attr_name(attr->attr.name, port); if (!pin) { return -ENODEV; } @@ -175,8 +200,16 @@ static ssize_t mts_attr_store_ap_gpio_pin(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { int value; - struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + int port; + struct gpio_pin *pin; + port = port_from_kobject(kobj); + if (port < 1) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; + } + + pin = ap_gpio_pin_by_attr_name(attr->attr.name, port); if (!pin) { return -ENODEV; } diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c index f8652c6..3f9631d 100644 --- a/io-module/mtac_gpiob.c +++ b/io-module/mtac_gpiob.c @@ -1,7 +1,7 @@ struct spi_device *gpiob_spi[NUM_AP][3]; struct spi_driver gpiob_spi_drivers[NUM_AP][3]; -static u8 spi_ap_dout_value; +static u8 spi_ap_dout_value[NUM_AP]; static DEFINE_MUTEX(spi_ap_dout_mutex); static unsigned int ap_dout_max_speed_hz = 1 * 1000 * 1000; module_param(ap_dout_max_speed_hz, uint, S_IRUGO); @@ -41,7 +41,7 @@ static int mts_spi_ap_probe(struct spi_device *spi) gpiob_get_dev_info_from_modalias(spi->modalias, &port, buf); port_index = port - 1; if (port < 1 || port > NUM_AP) { - log_error("port [%d] is invalid", port); + log_error("port %d is invalid", port); return -ENODEV; } @@ -66,13 +66,13 @@ static int mts_spi_ap_probe(struct spi_device *spi) tmp = spi_setup(gpiob_spi[port_index][dev]); if (tmp < 0) { - log_error("spi_setup ap %d %s failed", port, buf); + log_error("spi_setup ap %d [%s] failed", port, buf); return tmp; } if (dev == dout) { - spi_ap_dout_value = 0x00; - spi_writen(gpiob_spi[port_index][dev], &spi_ap_dout_value, 1); + spi_ap_dout_value[port_index] = 0x00; + spi_writen(gpiob_spi[port_index][dev], &spi_ap_dout_value[port_index], 1); } return 0; @@ -87,7 +87,7 @@ static int mts_spi_ap_remove(struct spi_device *spi) gpiob_get_dev_info_from_modalias(spi->modalias, &port, buf); port_index = port - 1; if (port < 1 || port > NUM_AP) { - log_error("port [%d] is invalid", port); + log_error("port %d is invalid", port); return -ENODEV; } @@ -105,26 +105,35 @@ static int mts_spi_ap_remove(struct spi_device *spi) return 0; } -static char* gpiob_gpio_pin_name_by_attr_name(const char* name) { - if (! strcmp(name, "led1:1")) { - return "ap1-gpio3"; - } else if (! strcmp(name, "led2:1")) { - return "ap1-gpio4"; - } else if (! strcmp(name, "dout-enable:1")) { - return "ap1-gpio1"; - } else if (! strcmp(name, "reset:1")) { - return "ap1-reset"; - } else if (! strcmp(name, "led1:2")) { - return "ap2-gpio3"; - } else if (! strcmp(name, "led2:2")) { - return "ap2-gpio4"; - } else if (! strcmp(name, "dout-enable:2")) { - return "ap2-gpio1"; - } else if (! strcmp(name, "reset:2")) { - return "ap2-reset"; - } else { - log_error("attirbute name [%s] is invalid for GPIOB", name); - return ""; +static char* gpiob_gpio_pin_name_by_attr_name(const char* name, int port) { + switch (port) { + case port_1: + if (! strcmp(name, "led1")) { + return "ap1-gpio3"; + } else if (! strcmp(name, "led2")) { + return "ap1-gpio4"; + } else if (! strcmp(name, "dout-enable")) { + return "ap1-gpio1"; + } else if (! strcmp(name, "reset")) { + return "ap1-reset"; + } else { + log_error("attirbute name [%s] is invalid for GPIOB in port %d", name, port); + return ""; + } + + case port_2: + if (! strcmp(name, "led1")) { + return "ap2-gpio3"; + } else if (! strcmp(name, "led2")) { + return "ap2-gpio4"; + } else if (! strcmp(name, "dout-enable")) { + return "ap2-gpio1"; + } else if (! strcmp(name, "reset")) { + return "ap2-reset"; + } else { + log_error("attirbute name [%s] is invalid for GPIOB in port %d", name, port); + return ""; + } } } @@ -137,16 +146,18 @@ static ssize_t mts_attr_show_ap_din(struct kobject *kobj, struct kobj_attribute u8 bit; u8 byte; - sscanf(attr->attr.name, "din%d:%d", &channel, &port); - port_index = port - 1; + sscanf(attr->attr.name, "din%d", &channel); if (channel < 0 || channel > 3) { - log_error("channel [%d] is invalid", channel); + log_error("channel %d is invalid", channel); return -ENOENT; } - if (port < 1 || port > NUM_AP) { - log_error("port [%d] is invalid", port); - return -ENOENT; + + port = port_from_kobject(kobj); + if (port < 0) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; } + port_index = port - 1; bit = BIT(channel); @@ -169,33 +180,35 @@ static ssize_t mts_attr_store_ap_dout(struct kobject *kobj, struct kobj_attribut int port_index; u8 bit; - sscanf(attr->attr.name, "dout%d:%d", &channel, &port); - port_index = port - 1; + sscanf(attr->attr.name, "dout%d", &channel); if (channel < 0 || channel > 3) { - log_error("channel [%d] is invalid", channel); + log_error("channel %d is invalid", channel); return -ENOENT; } - if (port < 1 || port > NUM_AP) { - log_error("port [%d] is invalid", port); - return -ENOENT; + + port = port_from_kobject(kobj); + if (port < 0) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; } + port_index = port - 1; bit = BIT(channel); if (sscanf(buf, "%i", &value) != 1) { - log_error("accessory card dout attr invalid argument [%d]", value); + log_error("accessory card dout attr invalid argument %d", value); return -EINVAL; } mutex_lock(&spi_ap_dout_mutex); if (value) { - spi_ap_dout_value &= ~bit; + spi_ap_dout_value[port_index] &= ~bit; } else { - spi_ap_dout_value |= bit; + spi_ap_dout_value[port_index] |= bit; } - spi_writen(gpiob_spi[port_index][dout], &spi_ap_dout_value, 1); + spi_writen(gpiob_spi[port_index][dout], &spi_ap_dout_value[port_index], 1); mutex_unlock(&spi_ap_dout_mutex); @@ -207,23 +220,27 @@ static ssize_t mts_attr_show_ap_dout(struct kobject *kobj, struct kobj_attribute int value; int channel; int port; + int port_index; u8 bit; - sscanf(attr->attr.name, "dout%d:%d", &channel, &port); + sscanf(attr->attr.name, "dout%d", &channel); if (channel < 0 || channel > 3) { - log_error("channel [%d] is invalid", channel); + log_error("channel %d is invalid", channel); return -ENOENT; } - if (port < 1 || port > NUM_AP) { - log_error("port [%d] is invalid", port); - return -ENOENT; + + port = port_from_kobject(kobj); + if (port < 0) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; } + port_index = port - 1; bit = BIT(channel); mutex_lock(&spi_ap_dout_mutex); - value = spi_ap_dout_value & bit ? 0 : 1; + value = spi_ap_dout_value[port_index] & bit ? 0 : 1; mutex_unlock(&spi_ap_dout_mutex); @@ -246,16 +263,18 @@ static ssize_t mts_attr_show_ap_adc(struct kobject *kobj, struct kobj_attribute memset(tx, 0, sizeof(tx)); memset(rx, 0, sizeof(rx)); - sscanf(attr->attr.name, "adc%d:%d", &channel, &port); - port_index = port - 1; + sscanf(attr->attr.name, "adc%d", &channel); if (channel < 0 || channel > 2) { - log_error("channel [%d] is invalid", channel); + log_error("channel %d is invalid", channel); return -ENOENT; } - if (port < 1 || port > NUM_AP) { - log_error("port [%d] is invalid", port); - return -ENOENT; + + port = port_from_kobject(kobj); + if (port < 0) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; } + port_index = port - 1; /* 1st transfer to set up (5V reference, channel to read from) */ tx_data = manual_mode | ((channel << 7) & channel_mask); @@ -314,107 +333,142 @@ static bool gpiob_spi_driver_setup(struct spi_driver *driver, const char *driver // 1 product-id // 1 device-id // 1 hw-version -static int ap_gpiob_attrs_size = 19; +// NULL +static int ap_gpiob_attrs_size = 20; static bool gpiob_setup(enum ap port) { int i; int port_index = port - 1; - struct kobj_attribute *attr; + int index = 0; + int count = 0; + int ret; char buf[32]; + struct kobj_attribute* attr; + struct attribute **attrs; log_info("loading GPIOB accessory card in port %d", port); - if (device_attrs_size + ap_gpiob_attrs_size >= device_attrs_max_size) { - log_error("can't load GPIOB accessory card in port %d - not enough room for attributes", port); + sprintf(buf, "ap%d", port); + ap_subdirs[port_index] = kobject_create_and_add(buf, &mts_io_platform_device->dev.kobj); + if (! ap_subdirs[port_index]) { + log_error("kobject_create_and_add for port %d failed", port); return false; } - // mark the attribute indices we're using so we know what to clean up - port_info[port_index]->attrs_start = device_attrs_size; - port_info[port_index]->attrs_end = device_attrs_size + ap_gpiob_attrs_size; + // create the link to the apX directory this card is in + // if we're in the first slot, we get plain "gpiob" + // if we're in a different slot, we might need to use "gpiob-2" to differentiate + if (port > 1) { + for (i = 1; i < port; i++) { + if (port_info[i - 1]) { + if (strstr(port_info[i - 1]->product_id, PRODUCT_ID_MTAC_GPIOB)) { + count++; + } + } + } + } + if (count > 0) { + sprintf(buf, "gpiob-%d", count + 1); + } else { + sprintf(buf, "gpiob"); + } + ret = sysfs_create_link(ap_subdirs[port_index]->parent, ap_subdirs[port_index], buf); + if (ret) { + log_error("failed to link [%s] to [%s], %d", buf, ap_subdirs[port_index]->name, ret); + } + + attrs = kzalloc(sizeof(struct attribute*) * ap_gpiob_attrs_size, GFP_KERNEL); + if (! attrs) { + log_error("failed to allocate attribute space for port %d", port); + return false; + } // add digital inputs for (i = 0; i < 4; i++) { - sprintf(buf, "din%d:%d", i, port); + sprintf(buf, "din%d", i); attr = create_attribute(buf, MTS_ATTR_MODE_RO); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s]", buf); return false; } attr->show = mts_attr_show_ap_din; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; } // add digital outputs for (i = 0; i < 4; i++) { - sprintf(buf, "dout%d:%d", i, port); + sprintf(buf, "dout%d", i); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for GPIOB in port %d", buf, port); return false; } attr->show = mts_attr_show_ap_dout; attr->store = mts_attr_store_ap_dout; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; } // add analog to digital for (i = 0; i < 3; i++) { - sprintf(buf, "adc%d:%d", i, port); + sprintf(buf, "adc%d", i); attr = create_attribute(buf, MTS_ATTR_MODE_RO); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for GPIOB in port %d", buf, port); return false; } attr->show = mts_attr_show_ap_adc; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; } // add LEDs for (i = 1; i <= 2; i++) { - sprintf(buf, "led%d:%d", i, port); + sprintf(buf, "led%d", i); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for GPIOB in port %d", buf, port); return false; } attr->show = mts_attr_show_ap_gpio_pin; attr->store = mts_attr_store_ap_gpio_pin; - device_attrs[device_attrs_size++] = &attr->attr; - } - - // add attributes for eeprom contents - if (! ap_add_product_info_attributes(port, MTAC_GPIOB_0_0)) { - log_error("failed to add product info attributes"); - return false; + attrs[index++] = &attr->attr; } // add misc attributes - sprintf(buf, "dout-enable:%d", port); + sprintf(buf, "dout-enable"); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for GPIOB in port %d", buf, port); return false; } attr->show = mts_attr_show_ap_gpio_pin; attr->store = mts_attr_store_ap_gpio_pin; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; - sprintf(buf, "reset:%d", port); + sprintf(buf, "reset"); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for GPIOB in port %d", buf, port); return false; } attr->show = mts_attr_show_ap_gpio_pin; attr->store = mts_attr_store_ap_gpio_pin; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; + + // add attributes for eeprom contents + if (! ap_add_product_info_attributes(port, MTAC_GPIOB_0_0, attrs, &index)) { + log_error("failed to add product info attributes for GPIOB in port %d", port); + return false; + } + + attrs[index] = NULL; + + ap_attr_groups[port_index].attrs = attrs; // setup and register drivers log_debug("registering accessory card %d dout driver", port); sprintf(buf, "mts-io-ap%d-dout", port); if (! gpiob_spi_driver_setup(&gpiob_spi_drivers[port_index][dout], buf)) { - log_error("failed to set up spi driver [%s]", buf); + log_error("failed to set up spi driver [%s] for GPIOB in port %d", buf, port); return false; } if (spi_register_driver(&gpiob_spi_drivers[port_index][dout])) { @@ -426,7 +480,7 @@ static bool gpiob_setup(enum ap port) { log_debug("registering accessory card %d din driver", port); sprintf(buf, "mts-io-ap%d-din", port); if (! gpiob_spi_driver_setup(&gpiob_spi_drivers[port_index][din], buf)) { - log_error("failed to set up spi driver [%s]", buf); + log_error("failed to set up spi driver [%s] for GPIOB in port %d", buf, port); return false; } if (spi_register_driver(&gpiob_spi_drivers[port_index][din])) { @@ -438,7 +492,7 @@ static bool gpiob_setup(enum ap port) { log_debug("registering accessory card %d adc driver", port); sprintf(buf, "mts-io-ap%d-adc", port); if (! gpiob_spi_driver_setup(&gpiob_spi_drivers[port_index][adc], buf)) { - log_error("failed to set up spi driver [%s]", buf); + log_error("failed to set up spi driver [%s] for GPIOB in port %d", buf, port); return false; } if (spi_register_driver(&gpiob_spi_drivers[port_index][adc])) { @@ -446,25 +500,39 @@ static bool gpiob_setup(enum ap port) { spi_unregister_driver(&gpiob_spi_drivers[port_index][adc]); return false; } + + if (sysfs_create_group(ap_subdirs[port_index], &ap_attr_groups[port_index])) { + log_error("sysfs_create_group failed for GPIOB in port %d", port); + return false; + } + return true; } static bool gpiob_teardown(enum ap port) { int i; int port_index = port - 1; + struct attribute **attrs = ap_attr_groups[port_index].attrs; log_info("unloading GPIOB accessory card in port %d", port); // clean up allocated memory for attributes - for (i = port_info[port_index]->attrs_start; i < port_info[port_index]->attrs_end; i++) { - if (device_attrs[i]) { - if (device_attrs[i]->name) - kfree(device_attrs[i]->name); + for (i = 0; i < ap_gpiob_attrs_size; i++) { + if (attrs[i]) { + if (attrs[i]->name) + kfree(attrs[i]->name); - kfree(device_attrs[i]); + kfree(attrs[i]); } } + kfree(attrs); + + // clean up our "apX/" kobject if it exists + if (ap_subdirs[port_index]) { + kobject_put(ap_subdirs[port_index]); + } + // clean up allocated memory for SPI drivers if (gpiob_spi_drivers[port_index][dout].driver.name) kfree(gpiob_spi_drivers[port_index][dout].driver.name); @@ -478,19 +546,13 @@ static bool gpiob_teardown(enum ap port) { spi_unregister_driver(&gpiob_spi_drivers[port_index][din]); spi_unregister_driver(&gpiob_spi_drivers[port_index][adc]); - // reset attribute index markers - port_info[port_index]->attrs_start = 0; - port_info[port_index]->attrs_end = 0; - return true; } bool set_gpiob_info(struct ap_info* info) { - info->product_id = MTAC_GPIOB_0_0; + snprintf(info->product_id, 32, "%s", PRODUCT_ID_MTAC_GPIOB); info->setup = &gpiob_setup; info->teardown = &gpiob_teardown; - info->attrs_start = 0; - info->attrs_end = 0; info->gpio_pin_name_by_attr_name = &gpiob_gpio_pin_name_by_attr_name; return true; diff --git a/io-module/mtac_mfser.c b/io-module/mtac_mfser.c index 7c5862c..27ca4dc 100644 --- a/io-module/mtac_mfser.c +++ b/io-module/mtac_mfser.c @@ -1,15 +1,24 @@ -static char* mfser_gpio_pin_name_by_attr_name(const char* name) { - if (! strcmp(name, "rs4xx-term-res:1")) { - return "ap1-gpio3"; - } else if (! strcmp(name, "rts-override:1")) { - return "ap1-gpio4"; - } else if (! strcmp(name, "rs4xx-term-res:2")) { - return "ap2-gpio3"; - } else if (! strcmp(name, "rts-override:2")) { - return "ap2-gpio4"; - } else { - log_error("attirbute name [%s] is invalid for MFSER", name); - return ""; +static char* mfser_gpio_pin_name_by_attr_name(const char* name, int port) { + switch (port) { + case port_1: + if (! strcmp(name, "rs4xx-term-res")) { + return "ap1-gpio3"; + } else if (! strcmp(name, "rts-override")) { + return "ap1-gpio4"; + } else { + log_error("attirbute name [%s] is invalid for MFSER in port %d", name, port); + return ""; + } + + case port_2: + if (! strcmp(name, "rs4xx-term-res")) { + return "ap2-gpio3"; + } else if (! strcmp(name, "rts-override")) { + return "ap2-gpio4"; + } else { + log_error("attirbute name [%s] is invalid for MFSER in port %d", name, port); + return ""; + } } } @@ -18,23 +27,33 @@ static ssize_t mts_attr_show_mfser_mode(struct kobject *kobj, char *buf) { int ret; + int port; int modesel0; int modesel1; struct gpio_pin *pin_modesel0; struct gpio_pin *pin_modesel1; - if (strstr(attr->attr.name, ":1")) { - pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); - pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); - } - else if (strstr(attr->attr.name, ":2")) { - pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); - pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); + port = port_from_kobject(kobj); + if (port < 0) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; } - else { - log_error("unknown serial-mode attr %s", attr->attr.name); - return -ENODEV; + + switch (port) { + case port_1: + pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); + break; + + case port_2: + pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); + break; + + default: + log_error("unknown serial-mode attr [%s]", attr->attr.name); + return -ENODEV; } if (!pin_modesel0 || !pin_modesel1) @@ -64,22 +83,32 @@ static ssize_t mts_attr_show_mfser_mode(struct kobject *kobj, static ssize_t mts_attr_store_mfser_mode(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { + int port; int modesel0; int modesel1; struct gpio_pin *pin_modesel0; struct gpio_pin *pin_modesel1; - if (strstr(attr->attr.name, ":1")) { - pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); - pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); - } - else if (strstr(attr->attr.name, ":2")) { - pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); - pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); + port = port_from_kobject(kobj); + if (port < 0) { + log_error("port_from_kobject returned %d", port); + return -EINVAL; } - else { - log_error("unknown serial-mode attr %s", attr->attr.name); - return -ENODEV; + + switch (port) { + case port_1: + pin_modesel0 = gpio_pin_by_name("AP1_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP1_GPIO2"); + break; + + case port_2: + pin_modesel0 = gpio_pin_by_name("AP2_GPIO1"); + pin_modesel1 = gpio_pin_by_name("AP2_GPIO2"); + break; + + default: + log_error("unknown serial-mode attr [%s]", attr->attr.name); + return -ENODEV; } if (!pin_modesel0 || !pin_modesel1) @@ -122,57 +151,97 @@ static ssize_t mts_attr_store_mfser_mode(struct kobject *kobj, // 1 product-id // 1 device-id // 1 hw-version -static int ap_mfser_attrs_size = 7; +// NULL +static size_t ap_mfser_attrs_size = 8; static bool mfser_setup(enum ap port) { + int i; int port_index = port - 1; - struct kobj_attribute *attr; + int index = 0; + int count = 0; + int ret; char buf[32]; + struct kobj_attribute* attr; + struct attribute **attrs; log_info("loading MFSER accessory card in port %d", port); - if (device_attrs_size + ap_mfser_attrs_size >= device_attrs_max_size) { - log_error("can't load MFSER accessory card in port %d - not enough room for attributes", port); + sprintf(buf, "ap%d", port); + ap_subdirs[port_index] = kobject_create_and_add(buf, &mts_io_platform_device->dev.kobj); + if (! ap_subdirs[port_index]) { + log_error("kobject_create_and_add for MFSER in port %d failed", port); return false; } - // mark the attribute indices we're using so we know what to clean up - port_info[port_index]->attrs_start = device_attrs_size; - port_info[port_index]->attrs_end = device_attrs_size + ap_mfser_attrs_size; + // create the link to the apX directory this card is in + // if we're in the first slot, we get plain "mfser" + // if we're in a different slot, we might need to use "mfser-2" to differentiate + if (port > 1) { + for (i = 1; i < port; i++) { + if (port_info[i - 1]) { + if (strstr(port_info[i - 1]->product_id, PRODUCT_ID_MTAC_MFSER)) { + count++; + } + } + } + } + if (count > 0) { + sprintf(buf, "mfser-%d", count + 1); + } else { + sprintf(buf, "mfser"); + } + ret = sysfs_create_link(ap_subdirs[port_index]->parent, ap_subdirs[port_index], buf); + if (ret) { + log_error("failed to link [%s] to [%s], %d", buf, ap_subdirs[port_index]->name, ret); + } + + attrs = kzalloc(sizeof(struct attribute*) * ap_mfser_attrs_size, GFP_KERNEL); + if (! attrs) { + log_error("failed to allocate attribute space for port %d", port); + return false; + } - sprintf(buf, "serial-mode:%d", port); + sprintf(buf, "serial-mode"); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for MFSER in port %d", buf, port); return false; } attr->show = mts_attr_show_mfser_mode; attr->store = mts_attr_store_mfser_mode; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; - sprintf(buf, "rs4xx-term-res:%d", port); + sprintf(buf, "rs4xx-term-res"); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for MFSER in port %d", buf, port); return false; } attr->show = mts_attr_show_ap_gpio_pin; attr->store = mts_attr_store_ap_gpio_pin; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; - sprintf(buf, "rts-override:%d", port); + sprintf(buf, "rts-override"); attr = create_attribute(buf, MTS_ATTR_MODE_RW); if (! attr) { - log_error("failed to create attribute[%s]", buf); + log_error("failed to create attribute [%s] for MFSER in port %d", buf, port); return false; } attr->show = mts_attr_show_ap_gpio_pin; attr->store = mts_attr_store_ap_gpio_pin; - device_attrs[device_attrs_size++] = &attr->attr; + attrs[index++] = &attr->attr; // add attributes for eeprom contents - if (! ap_add_product_info_attributes(port, MTAC_MFSER_0_0)) { - log_error("failed to add product info attributes"); + if (! ap_add_product_info_attributes(port, MTAC_MFSER_0_0, attrs, &index)) { + log_error("failed to add product info attributes for MFSER in port %d", port); + return false; + } + + attrs[index] = NULL; + + ap_attr_groups[port_index].attrs = attrs; + if (sysfs_create_group(ap_subdirs[port_index], &ap_attr_groups[port_index])) { + log_error("sysfs_create_group failed for MFSER in port %d", port); return false; } @@ -182,31 +251,34 @@ static bool mfser_setup(enum ap port) { static bool mfser_teardown(enum ap port) { int i; int port_index = port - 1; + struct attribute **attrs = ap_attr_groups[port_index].attrs; log_info("unloading MFSER accessory card in port %d", port); // clean up allocated memory for attributes - for (i = port_info[port_index]->attrs_start; i < port_info[port_index]->attrs_end; i++) { - if (device_attrs[i]) { - if (device_attrs[i]->name) - kfree(device_attrs[i]->name); + for (i = 0; i < ap_mfser_attrs_size; i++) { + if (attrs[i]) { + if (attrs[i]->name) + kfree(attrs[i]->name); - kfree(device_attrs[i]); + kfree(attrs[i]); } } - port_info[port_index]->attrs_start = 0; - port_info[port_index]->attrs_end = 0; + kfree(attrs); + + // clean up our "apX/" kobject if it exists + if (ap_subdirs[port_index]) { + kobject_put(ap_subdirs[port_index]); + } return true; } bool set_mfser_info(struct ap_info* info) { - info->product_id = MTAC_MFSER_0_0; + snprintf(info->product_id, 32, "%s", PRODUCT_ID_MTAC_MFSER); info->setup = &mfser_setup; info->teardown = &mfser_teardown; - info->attrs_start = 0; - info->attrs_end = 0; info->gpio_pin_name_by_attr_name = &mfser_gpio_pin_name_by_attr_name; return true; diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 15a70a3..048f96d 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -78,14 +78,14 @@ static struct mts_id_eeprom_layout id_eeprom; /* accessory card EEPROMs */ extern uint8_t mts_ap_eeprom[NUM_AP][512]; static struct mts_ap_eeprom_layout ap_eeprom[NUM_AP]; +/* kobject pointers for the apX subdirectories that correspond to the accessory ports */ +static struct kobject *ap_subdirs[NUM_AP]; +/* attribute groups for the accessory ports*/ +static struct attribute_group ap_attr_groups[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 has_spi_sout; static uint8_t has_spi_din; @@ -546,12 +546,6 @@ static int mts_id_eeprom_load(void) has_spi_temp = 0; log_info("detected board %s", HW_VERSION_MTR_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; @@ -628,13 +622,6 @@ static int __init mts_io_init(void) goto error1; } - if (NUM_AP) { - for (port = 0; port < NUM_AP; port++) { - port_info[port] = NULL; - } - init_accessory_ports(); - } - mts_io_platform_device = platform_device_alloc(PLATFORM_NAME, -1); if (!mts_io_platform_device) { ret = -ENOMEM; @@ -655,6 +642,13 @@ static int __init mts_io_init(void) goto error3; } + if (NUM_AP) { + for (port = 0; port < NUM_AP; port++) { + port_info[port] = NULL; + } + init_accessory_ports(); + } + ret = sysfs_create_group(&mts_io_platform_device->dev.kobj, attr_group); if (ret) { goto error4; diff --git a/io-module/mts_io.h b/io-module/mts_io.h index cc88392..3645e17 100644 --- a/io-module/mts_io.h +++ b/io-module/mts_io.h @@ -107,12 +107,10 @@ enum spi_devices { // contains function pointers for setup and teardown and useful info // each type of accessory card should have one of these struct ap_info { - uint8_t product_id; + char product_id[32]; bool (*setup)(enum ap port); bool (*teardown)(enum ap port); - int attrs_start; - int attrs_end; - char* (*gpio_pin_name_by_attr_name)(const char* name); + char* (*gpio_pin_name_by_attr_name)(const char* name, int port); }; #endif /* ~__MTS_IO_H */ -- cgit v1.2.3 From 13718072814328b8b119e3c30e4acf8607d62b28 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 8 Oct 2014 08:48:32 -0500 Subject: mts-io-sysfs: update script to correctly show accessory card attributes --- io-tool/mts-io-sysfs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/io-tool/mts-io-sysfs b/io-tool/mts-io-sysfs index 3961c03..3ecb100 100755 --- a/io-tool/mts-io-sysfs +++ b/io-tool/mts-io-sysfs @@ -76,15 +76,15 @@ usage() { #items for SHOW printf " SHOW-NAME := {\n" >&${out} - for f in $MTS_IO_DIR/*; + for f in `find $MTS_IO_DIR/* -follow -maxdepth 1 -type f`; do - FILENAME=${f##*/} + FILENAME=${f##*/mts-io/} case $FILENAME in modalias ) ;; power ) ;; - subsystem ) + subsystem* ) ;; uevent ) ;; @@ -97,9 +97,9 @@ usage() { #items for STORE printf " STORE-NAME := {\n" >&${out} - for f in $MTS_IO_DIR/*; + for f in `find $MTS_IO_DIR/* -follow -maxdepth 1 -type f`; do - FILENAME=${f##*/} + FILENAME=${f##*/mts-io/} case $FILENAME in #mac addresses are read-only mac-* ) @@ -108,7 +108,7 @@ usage() { *-id ) ;; #hw-version is read-only - hw-version ) + *hw-version ) ;; #imei is read-only imei ) @@ -117,17 +117,15 @@ usage() { ;; power ) ;; - subsystem ) + subsystem* ) ;; uevent ) ;; board-temperature ) ;; - extserial-dtr ) + *adc[0-9] ) ;; - adc[0-9] ) - ;; - din[0-9] ) + *din[0-9] ) ;; gpi[0-9] ) ;; @@ -145,8 +143,8 @@ usage() { printf " $FILENAME { 0 }\n" >&${out} ;; reset-monitor ) printf " $FILENAME { pid short-signal long-signal [extra-long-signal] }\n" >&${out} ;; - serial-mode ) - printf " $FILENAME { loopback | rs232 | rs422 | rs485 }\n" >&${out} ;; + *serial-mode ) + printf " $FILENAME { loopback | rs232 | rs485-half | rs422-485-full }\n" >&${out} ;; * ) printf " $FILENAME BOOLEAN\n" >&${out} ;; esac -- cgit v1.2.3 From b4e12fd5092d6de675da8c6a3629a23dcb5a34f2 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 8 Oct 2014 10:01:34 -0500 Subject: mts-io: make mtcdt only supported hardware remove including of mtr.c, mtcdp.c, mt100eocg.c remove wifi related attributes --- io-module/mts_io.c | 70 +----------------------------------------------------- 1 file changed, 1 insertion(+), 69 deletions(-) diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 048f96d..38d1086 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -377,14 +377,6 @@ static ssize_t mts_attr_show_product_info(struct device *dev, value = sprintf(buf, "%.32s\n", id_eeprom.hw_version); } else if (strcmp(attr->attr.name, "imei") == 0) { value = sprintf(buf, "%.32s\n", id_eeprom.imei); - } else if (strcmp(attr->attr.name, "mac-wifi") == 0) { - value = sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", - id_eeprom.mac_wifi[0], - id_eeprom.mac_wifi[1], - id_eeprom.mac_wifi[2], - id_eeprom.mac_wifi[3], - id_eeprom.mac_wifi[4], - id_eeprom.mac_wifi[5]); } else if (strcmp(attr->attr.name, "mac-eth") == 0) { value = sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", id_eeprom.mac_addr[0], @@ -411,20 +403,12 @@ static DEVICE_ATTR_RO_MTS(dev_attr_hw_version, "hw-version", mts_attr_show_product_info); static DEVICE_ATTR_RO_MTS(dev_attr_imei, "imei", mts_attr_show_product_info); -static DEVICE_ATTR_RO_MTS(dev_attr_wifi_mac, "mac-wifi", - mts_attr_show_product_info); static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth", mts_attr_show_product_info); /* include per-device pins and attributes */ -#include "mtr.c" #include "mtr2d2.c" -/* currently not supported -#include "mtcdp.c" -#include "mt100eocg.c" -*/ - 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])); @@ -504,48 +488,7 @@ static int mts_id_eeprom_load(void) if (mts_id_eeprom[0] == 0xFF) { log_error("uninitialized eeprom"); return -EIO; - /* - } else if (mts_id_eeprom[0] == 0x00) { - strncpy(id_eeprom.vendor_id, VENDOR_ID_MULTITECH, sizeof(id_eeprom.vendor_id) - 1); - strncpy(id_eeprom.product_id, PRODUCT_ID_MTCDP_E1_DK, sizeof(id_eeprom.product_id) - 1); - strncpy(id_eeprom.device_id, "", sizeof(id_eeprom.device_id) - 1); - strncpy(id_eeprom.hw_version, HW_VERSION_MTCDP_0_0, sizeof(id_eeprom.hw_version) - 1); - - DEVICE_CAPA_SET(id_eeprom.capa, CAPA_GPS); - - attr_group = &mtcdp_platform_attribute_group; - gpio_pins = gpio_pins_mtcdp_0_0; - mts_product_id = MTCDP_E1_DK_0_0; - log_info("detected board %s", HW_VERSION_MTCDP_0_0); - } else if (strncmp(id_eeprom.product_id, PRODUCT_ID_MT100EOCG, strlen(PRODUCT_ID_MT100EOCG)) == 0) { - attr_group = &mt100eocg_platform_attribute_group; - gpio_pins = gpio_pins_mt100eocg_0_0; - mts_product_id = MT100EOCG_0_0; - has_spi_sout = 0; - has_spi_din = 1; - 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_MTR_0_0, strlen(HW_VERSION_MTR_0_0)) == 0) { - attr_group = &mtr_platform_attribute_group; - gpio_pins = gpio_pins_mtr_0_0; - mts_product_id = MTR_0_0; - has_spi_sout = 0; - has_spi_din = 0; - has_spi_dout = 0; - has_spi_temp = 0; - log_info("detected board %s", HW_VERSION_MTR_0_0); - } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTR_0_1, strlen(HW_VERSION_MTR_0_1)) == 0) { - attr_group = &mtr_platform_attribute_group; - gpio_pins = gpio_pins_mtr_0_1; - mts_product_id = MTR_0_1; - has_spi_sout = 0; - has_spi_din = 0; - 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_MTR2D2_0_0, strlen(HW_VERSION_MTR2D2_0_0)) == 0) { + } else { attr_group = &mtr2d2_platform_attribute_group; gpio_pins = gpio_pins_mtr2d2_0_0; mts_product_id = MTR2D2_0_0; @@ -554,17 +497,6 @@ static int mts_id_eeprom_load(void) has_spi_dout = 0; has_spi_temp = 0; log_info("detected board %s", HW_VERSION_MTR2D2_0_0); - /* - } else { - attr_group = &mtcdp_platform_attribute_group; - gpio_pins = gpio_pins_mtcdp_1_0; - mts_product_id = MTCDP_E1_DK_1_0; - has_spi_sout = 1; - has_spi_din = 1; - has_spi_dout = 1; - has_spi_temp = 1; - log_info("detected board %s", HW_VERSION_MTCDP_1_0); - */ } log_info("sizeof: %lu", (unsigned long) sizeof(struct mts_id_eeprom_layout)); -- cgit v1.2.3 From 72412963e66f4a2448fd87f455b33f3a5115f4bd Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 8 Oct 2014 10:38:26 -0500 Subject: mts-io: remove all unused spi and adc code from mtcdp remote board-temperature attribute --- io-module/adc.c | 87 ------- io-module/mtac_gpiob.c | 37 +++ io-module/mtr2d2.c | 3 +- io-module/mts_io.c | 133 +---------- io-module/spi.c | 608 ------------------------------------------------- 5 files changed, 42 insertions(+), 826 deletions(-) delete mode 100644 io-module/adc.c delete mode 100644 io-module/spi.c diff --git a/io-module/adc.c b/io-module/adc.c deleted file mode 100644 index bcb3598..0000000 --- a/io-module/adc.c +++ /dev/null @@ -1,87 +0,0 @@ - -#define ADC_SHTIME_DEFAULT 0x05 -#define ADC_STARTUP_DEFAULT 0x04 -#define ADC_PRESCALE_DEFAULT 0x3F -#define ADC_MODE_DEFAULT \ - ((ADC_SHTIME_DEFAULT & 0x0F) << 24) | \ - ((ADC_STARTUP_DEFAULT & 0x1F) << 16) | \ - ((ADC_PRESCALE_DEFAULT & 0x3F) << 8) - -#define ADC_CR_OFFSET 0x00 -#define ADC_MR_OFFSET 0x04 -#define ADC_CHER_OFFSET 0x10 -#define ADC_CHDR_OFFSET 0x14 -#define ADC_CHSR_OFFSET 0x18 -#define ADC_SR_OFFSET 0x1C -#define ADC_LDCR_OFFSET 0x20 -#define ADC_IER_OFFSET 0x14 -#define ADC_IDR_OFFSET 0x28 -#define ADC_IMR_OFFSET 0x2C -#define ADC_CDR0_OFFSET 0x30 -#define ADC_CDR1_OFFSET 0x34 -#define ADC_CDR2_OFFSET 0x38 -#define ADC_CDR3_OFFSET 0x3C - -void __iomem *adc_base; -struct clk *adc_clk; - -#define ADC_CONVERT_RESET(base) writel(0x01, (base) + ADC_CR_OFFSET) -#define ADC_CONVERT_START(base) writel(0x02, (base) + ADC_CR_OFFSET) - -static ssize_t mts_attr_show_adc(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int offset; - u32 value; - u32 chan_mask; - - if (!DEVICE_CAPA(id_eeprom.capa, CAPA_ADC)) { - log_debug("ADC not available"); - return -ENODEV; - } - - if (!strcmp(attr->attr.name, "adc0")) { - offset = ADC_CDR0_OFFSET; - chan_mask = 0x01; - } else if (!strcmp(attr->attr.name, "adc1")) { - offset = ADC_CDR1_OFFSET; - chan_mask = 0x02; - } else if (!strcmp(attr->attr.name, "adc2")) { - offset = ADC_CDR2_OFFSET; - chan_mask = 0x04; - } else if (!strcmp(attr->attr.name, "adc3")) { - offset = ADC_CDR3_OFFSET; - chan_mask = 0x08; - } else { - log_notice("adc attr does not exist"); - return -ENOENT; - } - - mutex_lock(&mts_io_mutex); - - // disable all channels and enable the one we want - writel(0x0F, adc_base + ADC_CHDR_OFFSET); - writel(chan_mask, adc_base + ADC_CHER_OFFSET); - - ADC_CONVERT_START(adc_base); - - // wait for conversion to complete (EOC bit set) - value = 0; - while (value != chan_mask) { - value = readl(adc_base + ADC_SR_OFFSET) & chan_mask; - log_debug("ADC_SR EOC [%X]", value); - } - - // read result - value = readl(adc_base + offset); - - mutex_unlock(&mts_io_mutex); - - return sprintf(buf, "%lu\n", (unsigned long) value); -} - -static DEVICE_ATTR_RO_MTS(dev_attr_adc0, "adc0", mts_attr_show_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_adc1, "adc1", mts_attr_show_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_adc2, "adc2", mts_attr_show_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_adc3, "adc3", mts_attr_show_adc); diff --git a/io-module/mtac_gpiob.c b/io-module/mtac_gpiob.c index 3f9631d..0485494 100644 --- a/io-module/mtac_gpiob.c +++ b/io-module/mtac_gpiob.c @@ -30,6 +30,43 @@ static bool gpiob_get_dev_info_from_modalias(const char* modalias, int* port, ch return true; } +/* Generic SPI functions */ +static inline int spi_writen(struct spi_device *spi, const u8 *buf, size_t len) +{ + int tmp; + u8 *tx; + + tx = kmalloc(len, GFP_KERNEL); + if (!tx) { + return -ENOMEM; + } + + memcpy(tx, buf, len); + tmp = spi_write(spi, tx, len); + + kfree(tx); + + return tmp; +} + +static inline int spi_readn(struct spi_device *spi, u8 *buf, size_t len) +{ + int tmp; + u8 *rx; + + rx = kmalloc(len, GFP_KERNEL); + if (!rx) { + return -ENOMEM; + } + + tmp = spi_read(spi, rx, len); + memcpy(buf, rx, len); + + kfree(rx); + + return tmp; +} + static int mts_spi_ap_probe(struct spi_device *spi) { int tmp; diff --git a/io-module/mtr2d2.c b/io-module/mtr2d2.c index 24a99f3..428d71c 100644 --- a/io-module/mtr2d2.c +++ b/io-module/mtr2d2.c @@ -292,9 +292,8 @@ static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_led_d_gpio.attr, &dev_attr_led_e_gpio.attr, - &dev_attr_board_temperature.attr, - /* extra space for the accessory card attributes */ + NULL, // index 20 NULL, // index 21 NULL, // index 22 NULL, // index 23 diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 38d1086..fa61e1f 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -54,8 +54,6 @@ #define LED_LS_CONTROLLABLE 0 -#define AT91SAM9X5_BASE_ADC 0xf804c000 - /* on-board EEPROM */ extern uint8_t mts_id_eeprom[512]; static struct mts_id_eeprom_layout id_eeprom; @@ -86,12 +84,6 @@ static struct attribute_group ap_attr_groups[NUM_AP]; static struct ap_info* port_info[NUM_AP]; -static uint8_t mts_product_id; -static uint8_t has_spi_sout; -static uint8_t has_spi_din; -static uint8_t has_spi_dout; -static uint8_t has_spi_temp; - static struct platform_device *mts_io_platform_device; static struct attribute_group *attr_group; static struct gpio_pin *gpio_pins; @@ -101,12 +93,6 @@ static DEFINE_MUTEX(mts_io_mutex); /* generic GPIO support */ #include "gpio.c" -/* AT91 built-in ADC */ -#include "adc.c" - -/* SPI-based stuff */ -#include "spi.c" - /* accessory card support */ #include "mtac.c" #include "mtac_gpiob.c" @@ -479,23 +465,12 @@ static int mts_id_eeprom_load(void) { memcpy(&id_eeprom, mts_id_eeprom, sizeof(mts_id_eeprom)); - mts_product_id = MTCDP_E1_DK_1_0; - has_spi_sout = 1; - has_spi_din = 1; - has_spi_dout = 1; - has_spi_temp = 1; - if (mts_id_eeprom[0] == 0xFF) { log_error("uninitialized eeprom"); return -EIO; } else { attr_group = &mtr2d2_platform_attribute_group; gpio_pins = gpio_pins_mtr2d2_0_0; - mts_product_id = MTR2D2_0_0; - has_spi_sout = 0; - has_spi_din = 0; - has_spi_dout = 0; - has_spi_temp = 0; log_info("detected board %s", HW_VERSION_MTR2D2_0_0); } @@ -586,56 +561,6 @@ static int __init mts_io_init(void) goto error4; } - if ( has_spi_sout ) { - ret = spi_register_driver(&mts_spi_sout_driver); - if (ret) { - goto error5; - } - } - - if ( has_spi_dout ) { - ret = spi_register_driver(&mts_spi_dout_driver); - if (ret) { - goto error6; - } - } - if ( has_spi_din ) { - ret = spi_register_driver(&mts_spi_din_driver); - if (ret) { - goto error7; - } - } - - if ( has_spi_temp ) { - ret = spi_register_driver(&mts_spi_board_temp_driver); - if (ret) { - goto error8; - } - } - - /* ADC Setup */ -#ifdef CONFIG_SOC_AT91SAM9X5 - adc_base = ioremap(AT91SAM9X5_BASE_ADC, SZ_16K); -#else - adc_base = ioremap(AT91SAM9260_BASE_ADC, SZ_16K); -#endif - if (!adc_base) { - goto error9; - } - - adc_clk = clk_get(NULL, "adc_clk"); - if (!adc_clk) { - goto error10; - } - clk_enable(adc_clk); - - ADC_CONVERT_RESET(adc_base); - writel(ADC_MODE_DEFAULT, adc_base + ADC_MR_OFFSET); - writel(0x000F0F0F, adc_base + ADC_IDR_OFFSET); - if (!DEVICE_CAPA(id_eeprom.capa, CAPA_ADC)) { - writel(0x0F, adc_base + ADC_CHDR_OFFSET); - } - for (pin = gpio_pins; *pin->name; pin++) { ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label); if (ret) { @@ -643,41 +568,13 @@ static int __init mts_io_init(void) } } - if ( has_spi_sout || has_spi_dout || has_spi_din ) { - pin = gpio_pin_by_name("ENIO"); - if (pin) { - gpio_set_value(pin->pin.gpio, 0); - } - } - - // No reset_callback for MT100EOCG - if ( mts_product_id != MT100EOCG_0_0 ) { - reset_callback(NULL); - } + // start the reset handler + reset_callback(NULL); return 0; -error10: - iounmap(adc_base); -error9: - if ( has_spi_temp ) { - spi_unregister_driver(&mts_spi_board_temp_driver); - } -error8: - if ( has_spi_din ) { - spi_unregister_driver(&mts_spi_din_driver); - } -error7: - if ( has_spi_dout ) { - spi_unregister_driver(&mts_spi_dout_driver); - } -error6: - if ( has_spi_sout ) { - spi_unregister_driver(&mts_spi_sout_driver); - } -error5: - sysfs_remove_group(&mts_io_platform_device->dev.kobj, attr_group); error4: + sysfs_remove_group(&mts_io_platform_device->dev.kobj, attr_group); sysfs_remove_link(&mts_io_platform_device->dev.parent->kobj, "mtcdp"); error3: platform_device_del(mts_io_platform_device); @@ -700,25 +597,7 @@ static void __exit mts_io_exit(void) int port; int port_index; - if ( mts_product_id != MT100EOCG_0_0 ) { - cancel_delayed_work_sync(&reset_work); - } - - iounmap(adc_base); - clk_disable(adc_clk); - clk_put(adc_clk); - - if (has_spi_temp) - spi_unregister_driver(&mts_spi_board_temp_driver); - - if (has_spi_din) - spi_unregister_driver(&mts_spi_din_driver); - - if (has_spi_dout) - spi_unregister_driver(&mts_spi_dout_driver); - - if (has_spi_sout) - spi_unregister_driver(&mts_spi_sout_driver); + cancel_delayed_work_sync(&reset_work); sysfs_remove_group(&mts_io_platform_device->dev.kobj, attr_group); @@ -744,10 +623,6 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); -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-ap1-dout"); MODULE_ALIAS("mts-io-ap1-din"); MODULE_ALIAS("mts-io-ap1-adc"); diff --git a/io-module/spi.c b/io-module/spi.c deleted file mode 100644 index 210371c..0000000 --- a/io-module/spi.c +++ /dev/null @@ -1,608 +0,0 @@ -/* SPI devices, functions, and attributes */ - -static int ADT7302_to_celsius(int value) -{ - if (value & 0x2000) { - value = value - 16384; - } - - value = value / 32 + 1 * ((value % 32) >= 16); - - return value; -} - -/* SPI Devices */ -static struct spi_device *spi_sout_dev; -static u8 spi_sout_value; -static DEFINE_MUTEX(spi_sout_mutex); -static unsigned int sout_max_speed_hz = 1 * 1000 * 1000; -module_param(sout_max_speed_hz, uint, S_IRUGO); -MODULE_PARM_DESC( - sout_max_speed_hz, - "Maximum clock rate to be used with this device (default: 1 MHz)" -); - -static struct spi_device *spi_dout_dev; -static u8 spi_dout_value; -static DEFINE_MUTEX(spi_dout_mutex); -static unsigned int dout_max_speed_hz = 1 * 1000 * 1000; -module_param(dout_max_speed_hz, uint, S_IRUGO); -MODULE_PARM_DESC( - dout_max_speed_hz, - "Maximum clock rate to be used with this device (default: 1 MHz)" -); - -static struct spi_device *spi_din_dev; -static unsigned int din_max_speed_hz = 1 * 1000 * 1000; -module_param(din_max_speed_hz, uint, S_IRUGO); -MODULE_PARM_DESC( - din_max_speed_hz, - "Maximum clock rate to be used with this device (default: 1 MHz)" -); - -static struct spi_device *spi_board_temp_dev; -static unsigned int board_temp_max_speed_hz = 1 * 1000 * 1000; -module_param(board_temp_max_speed_hz, uint, S_IRUGO); -MODULE_PARM_DESC( - board_temp_max_speed_hz, - "Maximum clock rate to be used with this device (default: 1 MHz)" -); - -/* Generic SPI functions */ -static inline int spi_writen(struct spi_device *spi, const u8 *buf, size_t len) -{ - int tmp; - u8 *tx; - - tx = kmalloc(len, GFP_KERNEL); - if (!tx) { - return -ENOMEM; - } - - memcpy(tx, buf, len); - tmp = spi_write(spi, tx, len); - - kfree(tx); - - return tmp; -} - -static inline int spi_readn(struct spi_device *spi, u8 *buf, size_t len) -{ - int tmp; - u8 *rx; - - rx = kmalloc(len, GFP_KERNEL); - if (!rx) { - return -ENOMEM; - } - - tmp = spi_read(spi, rx, len); - memcpy(buf, rx, len); - - kfree(rx); - - return tmp; -} - -/* ---------------------------------------------------------------------------- - * - * SPI-based attribute show/store functions - * - * ---------------------------------------------------------------------------- -*/ - -#define SOUT_LED_CD_BIT BIT(0) -#define SOUT_EXTSERIAL_RI_BIT BIT(1) -#define SOUT_EXTSERIAL_DSR_BIT BIT(2) -#define SOUT_LED_DTR BIT(3) -#define SOUT_LED_SIG1_BIT BIT(4) -#define SOUT_LED_SIG2_BIT BIT(5) -#define SOUT_LED_SIG3_BIT BIT(6) -#define SOUT_EXTSERIAL_DCD_BIT BIT(7) - -static ssize_t mts_attr_store_sout(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int value; - u8 bit; - - if (!spi_sout_dev) { - log_notice("sout device not present"); - return -ENODEV; - } - - if (!strcmp(attr->attr.name, "extserial-ri")) { - bit = SOUT_EXTSERIAL_RI_BIT; - } else if (!strcmp(attr->attr.name, "extserial-dsr")) { - bit = SOUT_EXTSERIAL_DSR_BIT; - } else if (!strcmp(attr->attr.name, "extserial-dcd")) { - bit = SOUT_EXTSERIAL_DCD_BIT; - } else if (!strcmp(attr->attr.name, "led-cd") || - !strcmp(attr->attr.name, "led-sdk-b")) { - bit = SOUT_LED_CD_BIT; - } else if (!strcmp(attr->attr.name, "led-dtr") || - !strcmp(attr->attr.name, "led-sdk-f")) { - bit = SOUT_LED_DTR; - } else if (!strcmp(attr->attr.name, "led-sig1") || - !strcmp(attr->attr.name, "led-sdk-c")) { - bit = SOUT_LED_SIG1_BIT; - } else if (!strcmp(attr->attr.name, "led-sig2") || - !strcmp(attr->attr.name, "led-sdk-d")) { - bit = SOUT_LED_SIG2_BIT; - } else if (!strcmp(attr->attr.name, "led-sig3") || - !strcmp(attr->attr.name, "led-sdk-e")) { - bit = SOUT_LED_SIG3_BIT; - } else { - log_notice("sout attr does not exist"); - return -ENOENT; - } - - if (sscanf(buf, "%i", &value) != 1) { - log_notice("sout attr invalid argument"); - return -EINVAL; - } - - mutex_lock(&spi_sout_mutex); - - if (value) { - spi_sout_value &= ~bit; - } else { - spi_sout_value |= bit; - } - spi_writen(spi_sout_dev, &spi_sout_value, 1); - - mutex_unlock(&spi_sout_mutex); - - return count; -} - -static ssize_t mts_attr_show_sout(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int value; - u8 bit; - - if (!spi_sout_dev) { - log_error("sout device not present"); - return -ENODEV; - } - - if (!strcmp(attr->attr.name, "extserial-ri")) { - bit = SOUT_EXTSERIAL_RI_BIT; - } else if (!strcmp(attr->attr.name, "extserial-dsr")) { - bit = SOUT_EXTSERIAL_DSR_BIT; - } else if (!strcmp(attr->attr.name, "extserial-dcd")) { - bit = SOUT_EXTSERIAL_DCD_BIT; - } else if (!strcmp(attr->attr.name, "led-cd") || - !strcmp(attr->attr.name, "led-sdk-b")) { - bit = SOUT_LED_CD_BIT; - } else if (!strcmp(attr->attr.name, "led-dtr") || - !strcmp(attr->attr.name, "led-sdk-f")) { - bit = SOUT_LED_DTR; - } else if (!strcmp(attr->attr.name, "led-sig1") || - !strcmp(attr->attr.name, "led-sdk-c")) { - bit = SOUT_LED_SIG1_BIT; - } else if (!strcmp(attr->attr.name, "led-sig2") || - !strcmp(attr->attr.name, "led-sdk-d")) { - bit = SOUT_LED_SIG2_BIT; - } else if (!strcmp(attr->attr.name, "led-sig3") || - !strcmp(attr->attr.name, "led-sdk-e")) { - bit = SOUT_LED_SIG3_BIT; - } else { - log_notice("sout attr does not exist"); - return -ENOENT; - } - - mutex_lock(&spi_sout_mutex); - - value = spi_sout_value & bit ? 0 : 1; - - mutex_unlock(&spi_sout_mutex); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t mts_attr_store_dout(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int value; - u8 bit; - - if (!spi_dout_dev) { - log_notice("dout device not present"); - return -ENODEV; - } - - if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) { - bit = BIT(0); - } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) { - bit = BIT(1); - } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) { - bit = BIT(2); - } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) { - bit = BIT(3); - } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) { - bit = BIT(4); - } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) { - bit = BIT(5); - } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) { - bit = BIT(6); - } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) { - bit = BIT(7); - } else { - log_notice("dout attr does not exist"); - return -ENOENT; - } - - if (sscanf(buf, "%i", &value) != 1) { - log_notice("dout attr invalid argument"); - return -EINVAL; - } - - mutex_lock(&spi_dout_mutex); - - if (value) { - spi_dout_value &= ~bit; - } else { - spi_dout_value |= bit; - } - - spi_writen(spi_dout_dev, &spi_dout_value, 1); - - mutex_unlock(&spi_dout_mutex); - - return count; -} - -static ssize_t mts_attr_show_dout(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int value; - u8 bit; - - if (!spi_dout_dev) { - log_error("dout device not present"); - return -ENODEV; - } - - if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) { - bit = BIT(0); - } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) { - bit = BIT(1); - } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) { - bit = BIT(2); - } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) { - bit = BIT(3); - } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) { - bit = BIT(4); - } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) { - bit = BIT(5); - } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) { - bit = BIT(6); - } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) { - bit = BIT(7); - } else { - log_notice("dout attr does not exist"); - return -ENOENT; - } - - mutex_lock(&spi_dout_mutex); - - value = spi_dout_value & bit ? 0 : 1; - - mutex_unlock(&spi_dout_mutex); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t mts_attr_show_din(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int tmp; - u8 bit; - u8 byte; - - if (!spi_din_dev) { - log_error("din device not present"); - return -ENODEV; - } - - if ((!strcmp(attr->attr.name, "din0")) || (!strcmp(attr->attr.name, "gpi5"))) { - bit = BIT(0); - } else if ((!strcmp(attr->attr.name, "din1")) || (!strcmp(attr->attr.name, "gpi6"))) { - bit = BIT(1); - } else if ((!strcmp(attr->attr.name, "din2")) || (!strcmp(attr->attr.name, "gpi7"))) { - bit = BIT(2); - } else if ((!strcmp(attr->attr.name, "din3")) || (!strcmp(attr->attr.name, "gpi8"))) { - bit = BIT(3); - } else if ((!strcmp(attr->attr.name, "din4")) || (!strcmp(attr->attr.name, "gpi9"))) { - bit = BIT(4); - } 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); - } else if (!strcmp(attr->attr.name, "din7")) { - bit = BIT(7); - } else { - log_notice("din attr does not exist"); - return -ENOENT; - } - - tmp = spi_readn(spi_din_dev, &byte, 1); - if (tmp) { - log_error("spi_read failed %d", tmp); - return tmp; - } - - tmp = byte & bit ? 1 : 0; - - return sprintf(buf, "%d\n", tmp); -} - -static ssize_t mts_attr_show_board_temperature(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int tmp; - u16 temp_raw; - - if (!spi_board_temp_dev) { - log_notice("spi_board_temp device not present"); - return -ENODEV; - } - - tmp = spi_readn(spi_board_temp_dev, (u8 *) buf, 2); - if (tmp) { - log_error("spi_readn failed %d", tmp); - return tmp; - } - temp_raw = ((u8 *) buf)[0] << 8 | ((u8 *) buf)[1]; - - log_debug("temp: 0x%04X", temp_raw); - - return sprintf(buf, "%d\n", ADT7302_to_celsius(temp_raw)); -} - -/* ---------------------------------------------------------------------------- - * - * SPI-based attributes - * - * ---------------------------------------------------------------------------- -*/ - -static DEVICE_ATTR_RO_MTS(dev_attr_board_temperature, "board-temperature", - mts_attr_show_board_temperature); - -static DEVICE_ATTR_MTS(dev_attr_extserial_dcd, "extserial-dcd", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_extserial_ri, "extserial-ri", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_extserial_dsr, "extserial-dsr", - mts_attr_show_sout, mts_attr_store_sout); - -static DEVICE_ATTR_MTS(dev_attr_led_cd, "led-cd", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sdk_b, "led-sdk-b", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sig1, "led-sig1", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sdk_c, "led-sdk-c", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sig2, "led-sig2", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sdk_d, "led-sdk-d", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sig3, "led-sig3", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sdk_e, "led-sdk-e", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_dtr, "led-dtr", - mts_attr_show_sout, mts_attr_store_sout); -static DEVICE_ATTR_MTS(dev_attr_led_sdk_f, "led-sdk-f", - mts_attr_show_sout, mts_attr_store_sout); - -static DEVICE_ATTR_MTS(dev_attr_dout0, "dout0", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_dout1, "dout1", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_dout2, "dout2", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_dout3, "dout3", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_dout4, "dout4", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_dout5, "dout5", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_dout6, "dout6", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_dout7, "dout7", - mts_attr_show_dout, mts_attr_store_dout); - -static DEVICE_ATTR_RO_MTS(dev_attr_din0, "din0", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_din1, "din1", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_din2, "din2", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_din3, "din3", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_din4, "din4", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_din5, "din5", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_din6, "din6", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_din7, "din7", mts_attr_show_din); - -static DEVICE_ATTR_RO_MTS(dev_attr_gpi5, "gpi5", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_gpi6, "gpi6", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_gpi7, "gpi7", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_gpi8, "gpi8", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_gpi9, "gpi9", mts_attr_show_din); -static DEVICE_ATTR_RO_MTS(dev_attr_gpi10, "gpi10", mts_attr_show_din); - -/* SPI driver setup */ -static int mts_spi_sout_probe(struct spi_device *spi) -{ - int tmp; - - spi->max_speed_hz = sout_max_speed_hz; - spi->mode = 0; - - log_debug("sout_max_speed_hz: %d", sout_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup sout failed"); - return tmp; - } - - spi_sout_value = 0xFF; - spi_writen(spi, &spi_sout_value, 1); - - spi_sout_dev = spi; - - return 0; -} - -static int mts_spi_sout_remove(struct spi_device *spi) -{ - spi_sout_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_sout_driver = { - .driver = { - .name = "mts-io-sout", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_sout_probe, - .remove = mts_spi_sout_remove, -}; - -static int mts_spi_dout_probe(struct spi_device *spi) -{ - int tmp; - - if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DOUT)) { - log_debug("digital outputs not available"); - return -ENODEV; - } - - spi->max_speed_hz = dout_max_speed_hz; - spi->mode = 0; - - log_debug("dout_max_speed_hz: %d", dout_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup dout failed"); - return tmp; - } - - spi_dout_value = 0x00; - spi_writen(spi, &spi_dout_value, 1); - - spi_dout_dev = spi; - - return 0; -} - -static int mts_spi_dout_remove(struct spi_device *spi) -{ - spi_dout_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_dout_driver = { - .driver = { - .name = "mts-io-dout", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_dout_probe, - .remove = mts_spi_dout_remove, -}; - -static int mts_spi_din_probe(struct spi_device *spi) -{ - int tmp; - - if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DIN)) { - log_debug("digital inputs not available"); - return -ENODEV; - } - - spi->max_speed_hz = din_max_speed_hz; - spi->mode = SPI_CPOL; - - log_debug("din_max_speed_hz: %d", din_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup din failed"); - return tmp; - } - - spi_din_dev = spi; - - return 0; -} - -static int mts_spi_din_remove(struct spi_device *spi) -{ - spi_din_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_din_driver = { - .driver = { - .name = "mts-io-din", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_din_probe, - .remove = mts_spi_din_remove, -}; - -static int mts_spi_board_temp_probe(struct spi_device *spi) -{ - int tmp; - - spi->max_speed_hz = board_temp_max_speed_hz; - spi->mode = SPI_CPOL | SPI_CPHA; - - log_debug("board_temp_max_speed_hz: %d", board_temp_max_speed_hz); - - tmp = spi_setup(spi); - if (tmp < 0) { - log_error("spi_setup board-temp failed"); - return tmp; - } - - spi_board_temp_dev = spi; - - return 0; -} - -static int mts_spi_board_temp_remove(struct spi_device *spi) -{ - spi_board_temp_dev = NULL; - - return 0; -} - -static struct spi_driver mts_spi_board_temp_driver = { - .driver = { - .name = "mts-io-board-temp", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = mts_spi_board_temp_probe, - .remove = mts_spi_board_temp_remove, -}; -- cgit v1.2.3 From 8be9080418b18941129e56b44f7c5218a5a73932 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 8 Oct 2014 10:45:55 -0500 Subject: mts-io: remove mtt.c, mtcdp.c, mt100eocg.c --- io-module/mt100eocg.c | 221 ------------------------ io-module/mtcdp.c | 310 --------------------------------- io-module/mtr.c | 468 -------------------------------------------------- 3 files changed, 999 deletions(-) delete mode 100644 io-module/mt100eocg.c delete mode 100644 io-module/mtcdp.c delete mode 100644 io-module/mtr.c diff --git a/io-module/mt100eocg.c b/io-module/mt100eocg.c deleted file mode 100644 index 8d2338d..0000000 --- a/io-module/mt100eocg.c +++ /dev/null @@ -1,221 +0,0 @@ - -static struct gpio_pin gpio_pins_mt100eocg_0_0[] = { - { - .name = "ENIO", - .pin = AT91_PIN_PC15, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "ETH0_ENABLED", - .attr_name = "eth0-enabled", - .pin = AT91_PIN_PB31, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "RADIO_RESET", - .attr_name = "radio-reset", - .pin = AT91_PIN_PB30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "DEVICE_RESET", - .attr_name = "reset", - .pin = AT91_PIN_PA22, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "LED3", - .attr_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, - .active_low = 1, - }, - { - .name = "LED2", - .attr_name = "led2", - .pin = AT91_PIN_PA30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "RSERSRC", - .attr_name = "rsersrc", - .pin = AT91_PIN_PC7, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "TXD1", - .pin = AT91_PIN_PB17, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "DTR1", - .attr_name = "extserial-dtr", - .pin = AT91_PIN_PB18, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "DCD1", - .attr_name = "extserial-dcd", - .pin = AT91_PIN_PB3, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "GPIO11", - .attr_name = "gpio11", - .pin = AT91_PIN_PB19, - .direction = GPIO_DIR_OD, - .output_value = 1, - .use_pullup = 1, - }, - { - .name = "GPIO12", - .attr_name = "gpio12", - .pin = AT91_PIN_PB20, - .direction = GPIO_DIR_OD, - .output_value = 1, - .use_pullup = 1, - }, - { - .name = "ADC0", - .pin = AT91_PIN_PC0, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "ADC1", - .pin = AT91_PIN_PC1, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "ADC2", - .pin = AT91_PIN_PC2, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "ADC3", - .pin = AT91_PIN_PC3, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { }, -}; - -/* mt100eocg specific attributes */ -static DEVICE_ATTR_MTS(dev_attr_gpo1, "gpo1", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_gpo2, "gpo2", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_gpo3, "gpo3", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_gpo4, "gpo4", - mts_attr_show_dout, mts_attr_store_dout); - - -static DEVICE_ATTR_MTS(dev_attr_led1, "led1", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_led2, "led2", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); - -#if LED_LS_CONTROLLABLE -static DEVICE_ATTR_MTS(dev_attr_led3, "led3", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -#else -static DEVICE_ATTR_RO_MTS(dev_attr_led3, "led3", mts_attr_show_gpio_pin); -#endif - -static DEVICE_ATTR_MTS(dev_attr_led4, "led4", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_led5, "led5", - mts_attr_show_dout, mts_attr_store_dout); -static DEVICE_ATTR_MTS(dev_attr_led6, "led6", - mts_attr_show_dout, mts_attr_store_dout); - -static DEVICE_ATTR_MTS(dev_attr_gpio11, "gpio11", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_gpio12, "gpio12", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); - -static DEVICE_ATTR_MTS(dev_attr_rsersrc, "rsersrc", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); - -static struct attribute *mt100eocg_platform_attributes[] = { - &dev_attr_vendor_id.attr, - &dev_attr_product_id.attr, - &dev_attr_device_id.attr, - &dev_attr_hw_version.attr, - &dev_attr_imei.attr, - &dev_attr_eth_mac.attr, - &dev_attr_extserial_dtr.attr, - &dev_attr_extserial_dcd_gpio.attr, - &dev_attr_rsersrc.attr, - &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 mt100eocg_platform_attribute_group = { - .attrs = mt100eocg_platform_attributes -}; diff --git a/io-module/mtcdp.c b/io-module/mtcdp.c deleted file mode 100644 index 31551b0..0000000 --- a/io-module/mtcdp.c +++ /dev/null @@ -1,310 +0,0 @@ - -#define USBH2_PS_CONTROLLABLE 0 - -static struct gpio_pin gpio_pins_mtcdp_0_0[] = { - { - .name = "ENIO", - .pin = AT91_PIN_PC15, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "ETH0_ENABLED", - .attr_name = "eth0-enabled", - .pin = AT91_PIN_PB31, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "RADIO_RESET", - .attr_name = "radio-reset", - .pin = AT91_PIN_PB30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "DEVICE_RESET", - .attr_name = "reset", - .pin = AT91_PIN_PA22, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "LS_LED", - .attr_name = "led-ls", - .pin = AT91_PIN_PC9, -#if LED_LS_CONTROLLABLE - .direction = GPIO_DIR_OUTPUT, -#else - .direction = GPIO_DIR_INPUT, -#endif - .output_value = 1, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "STATUS_LED", - .attr_name = "led-status", - .pin = AT91_PIN_PA30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "STATUS_LED", - .attr_name = "led-sdk-a", - .pin = AT91_PIN_PA30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, -#endif - { - .name = "RSERSRC", - .attr_name = "rsersrc", - .pin = AT91_PIN_PC7, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "DTR1", - .attr_name = "extserial-dtr", - .pin = AT91_PIN_PC10, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, - { }, -}; - -static struct gpio_pin gpio_pins_mtcdp_1_0[] = { - { - .name = "ENIO", - .pin = AT91_PIN_PC15, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "ETH0_ENABLED", - .attr_name = "eth0-enabled", - .pin = AT91_PIN_PB31, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "RADIO_RESET", - .attr_name = "radio-reset", - .pin = AT91_PIN_PB30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "DEVICE_RESET", - .attr_name = "reset", - .pin = AT91_PIN_PA22, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "LS_LED", - .attr_name = "led-ls", - .pin = AT91_PIN_PC9, -#if LED_LS_CONTROLLABLE - .direction = GPIO_DIR_OUTPUT, -#else - .direction = GPIO_DIR_INPUT, -#endif - .output_value = 1, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "STATUS_LED", - .attr_name = "led-status", - .pin = AT91_PIN_PA30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "STATUS_LED", - .attr_name = "led-sdk-a", - .pin = AT91_PIN_PA30, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "RSERSRC", - .attr_name = "rsersrc", - .pin = AT91_PIN_PC7, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "TXD1", - .pin = AT91_PIN_PB17, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "DTR1", - .attr_name = "extserial-dtr", - .pin = AT91_PIN_PB18, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, - { - .name = "USBH2_PS_OC", - .attr_name = "usbh2-ps-oc", - .pin = AT91_PIN_PB19, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, -#if USBH2_PS_CONTROLLABLE - { - .name = "USBH2_PS_ENABLED", - .attr_name = "usbh2-ps-enabled", - .pin = AT91_PIN_PB20, - .direction = GPIO_DIR_OUTPUT, - .output_value = 0, - .use_pullup = 0, - .active_low = 1, - }, -#endif - { - .name = "NDC_RESET", - .attr_name = "ndc-reset", - .pin = AT91_PIN_PB21, - .direction = GPIO_DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - }, - { - .name = "ADC0", - .pin = AT91_PIN_PC0, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "ADC1", - .pin = AT91_PIN_PC1, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "ADC2", - .pin = AT91_PIN_PC2, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { - .name = "ADC3", - .pin = AT91_PIN_PC3, - .direction = GPIO_DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - }, - { }, -}; - -/* mtcdp specific attributes */ -static DEVICE_ATTR_MTS(dev_attr_led_sdk_a, "led-sdk-a", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_RO_MTS(dev_attr_usbh2_ps_oc, "usbh2-ps-oc", - mts_attr_show_gpio_pin); - -#if USBH2_PS_CONTROLLABLE -static DEVICE_ATTR_MTS(dev_attr_usbh2_ps_enabled, "usbh2-ps-enabled", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -#endif - -static struct attribute *mtcdp_platform_attributes[] = { - &dev_attr_vendor_id.attr, - &dev_attr_product_id.attr, - &dev_attr_device_id.attr, - &dev_attr_hw_version.attr, - &dev_attr_imei.attr, - &dev_attr_eth_mac.attr, - &dev_attr_reset.attr, - &dev_attr_reset_monitor.attr, - &dev_attr_radio_reset.attr, - &dev_attr_ndc_reset.attr, - &dev_attr_eth0_enabled.attr, - &dev_attr_extserial_dtr.attr, - &dev_attr_led_ls.attr, - &dev_attr_led_status.attr, - &dev_attr_led_sdk_a.attr, - &dev_attr_usbh2_ps_oc.attr, -#if USBH2_PS_CONTROLLABLE - &dev_attr_usbh2_ps_enabled.attr, -#endif - - &dev_attr_extserial_dcd.attr, - &dev_attr_extserial_ri.attr, - &dev_attr_extserial_dsr.attr, - &dev_attr_led_cd.attr, - &dev_attr_led_sdk_b.attr, - &dev_attr_led_sig1.attr, - &dev_attr_led_sdk_c.attr, - &dev_attr_led_sig2.attr, - &dev_attr_led_sdk_d.attr, - &dev_attr_led_sig3.attr, - &dev_attr_led_sdk_e.attr, - &dev_attr_led_dtr.attr, - &dev_attr_led_sdk_f.attr, - - &dev_attr_dout0.attr, - &dev_attr_dout1.attr, - &dev_attr_dout2.attr, - &dev_attr_dout3.attr, - &dev_attr_dout4.attr, - &dev_attr_dout5.attr, - &dev_attr_dout6.attr, - &dev_attr_dout7.attr, - - &dev_attr_din0.attr, - &dev_attr_din1.attr, - &dev_attr_din2.attr, - &dev_attr_din3.attr, - &dev_attr_din4.attr, - &dev_attr_din5.attr, - &dev_attr_din6.attr, - &dev_attr_din7.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 mtcdp_platform_attribute_group = { - .attrs = mtcdp_platform_attributes -}; diff --git a/io-module/mtr.c b/io-module/mtr.c deleted file mode 100644 index cef1560..0000000 --- a/io-module/mtr.c +++ /dev/null @@ -1,468 +0,0 @@ - -static struct gpio_pin gpio_pins_mtr_0_0[] = { - { - .name = "NETH_RST", - .pin = { - .gpio = AT91_PIN_PC6, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "eth0-enabled", - }, - }, - { - .name = "PWRMON", - .pin = { - .gpio = AT91_PIN_PA23, - .flags = GPIOF_IN, - .label = "radio-power", - }, - }, - { - .name = "3G_RST", - .pin = { - .gpio = AT91_PIN_PA22, - .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH, - .label = "radio-reset", - }, - }, - { - .name = "3G_ONOFF", - .pin = { - .gpio = AT91_PIN_PA21, - .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH, - .label = "radio-enabled", - }, - }, - { - .name = "DEVICE_RESET", - .pin = { - .gpio = AT91_PIN_PC4, - .flags = GPIOF_IN, - .label = "reset", - }, - .active_low = 1, - }, - { - .name = "LS_LED", - .pin = { - .gpio = AT91_PIN_PC16, -#if LED_LS_CONTROLLABLE - .flags = GPIOF_OUT_INIT_HIGH, -#else - .flags = GPIOF_IN, -#endif - .label = "led-ls", - }, - .active_low = 1, - }, - { - .name = "STATUS_LED", - .pin = { - .gpio = AT91_PIN_PC21, - .flags = GPIOF_OUT_INIT_LOW, - .label = "led-status", - }, - .active_low = 1, - }, - { - .name = "STATUS_LED", - .pin = { - .gpio = AT91_PIN_PC21, - .flags = GPIOF_OUT_INIT_LOW, - .label = "led-a", - }, - .active_low = 1, - }, - { - .name = "LED3", - .pin = { - .gpio = AT91_PIN_PC15, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-wifi", - }, - .active_low = 1, - }, - { - .name = "LED3", - .pin = { - .gpio = AT91_PIN_PC15, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-b", - }, - .active_low = 1, - }, - { - .name = "LED4", - .pin = { - .gpio = AT91_PIN_PC20, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-cd", - }, - .active_low = 1, - }, - { - .name = "LED4", - .pin = { - .gpio = AT91_PIN_PC20, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-c", - }, - .active_low = 1, - }, - { - .name = "LED6", - .pin = { - .gpio = AT91_PIN_PC19, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig1", - }, - .active_low = 1, - }, - { - .name = "LED6", - .pin = { - .gpio = AT91_PIN_PC19, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-d", - }, - .active_low = 1, - }, - { - .name = "LED7", - .pin = { - .gpio = AT91_PIN_PC18, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig2", - }, - .active_low = 1, - }, - { - .name = "LED7", - .pin = { - .gpio = AT91_PIN_PC18, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-e", - }, - .active_low = 1, - }, - { - .name = "LED8", - .pin = { - .gpio = AT91_PIN_PC17, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig3", - }, - .active_low = 1, - }, - { - .name = "LED8", - .pin = { - .gpio = AT91_PIN_PC17, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-f", - }, - .active_low = 1, - }, - { - .name = "RI_B", - .pin = { - .gpio = AT91_PIN_PC25, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-ri", - }, - .active_low = 1, - }, - { - .name = "DTR_B", - .pin = { - .gpio = AT91_PIN_PC26, - .flags = GPIOF_IN, - .label = "extserial-dtr", - }, - .active_low = 1, - }, - { - .name = "DSR_B", - .pin = { - .gpio = AT91_PIN_PC27, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-dsr", - }, - .active_low = 1, - }, - { - .name = "DCD_B", - .pin = { - .gpio = AT91_PIN_PC28, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-dcd", - }, - .active_low = 1, - }, - { - .name = "BT_EN", - .pin = { - .gpio = AT91_PIN_PA28, - .flags = GPIOF_OUT_INIT_LOW, - .label = "bt-enabled", - }, - }, - { - .name = "WLAN_EN", - .pin = { - .gpio = AT91_PIN_PA27, - .flags = GPIOF_OUT_INIT_LOW, - .label = "wlan-enabled", - }, - }, - { }, -}; - -static struct gpio_pin gpio_pins_mtr_0_1[] = { - { - .name = "NETH_RST", - .pin = { - .gpio = AT91_PIN_PC6, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "eth0-enabled", - }, - }, - { - .name = "PWRMON", - .pin = { - .gpio = AT91_PIN_PA23, - .flags = GPIOF_IN, - .label = "radio-power", - }, - }, - { - .name = "3G_RST", - .pin = { - .gpio = AT91_PIN_PA22, - .flags = GPIOF_OUT_INIT_HIGH | GPIOF_PULLUP, - .label = "radio-reset", - }, - }, - { - .name = "3G_ONOFF", - .pin = { - .gpio = AT91_PIN_PA21, - .flags = GPIOF_OUT_INIT_HIGH | GPIOF_PULLUP, - .label = "radio-enabled", - }, - }, - { - .name = "DEVICE_RESET", - .pin = { - .gpio = AT91_PIN_PC4, - .flags = GPIOF_IN, - .label = "reset", - }, - .active_low = 1, - }, - { - .name = "LS_LED", - .pin = { - .gpio = AT91_PIN_PC16, -#if LED_LS_CONTROLLABLE - .flags = GPIOF_OUT_INIT_HIGH, -#else - .flags = GPIOF_IN, -#endif - .label = "led-ls", - }, - .active_low = 1, - }, - { - .name = "STATUS_LED", - .pin = { - .gpio = AT91_PIN_PC21, - .flags = GPIOF_OUT_INIT_LOW, - .label = "led-status", - }, - .active_low = 1, - }, - { - .name = "LED3", - .pin = { - .gpio = AT91_PIN_PC15, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-wifi", - }, - .active_low = 1, - }, - { - .name = "LED3", - .pin = { - .gpio = AT91_PIN_PC15, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-b", - }, - .active_low = 1, - }, - { - .name = "LED4", - .pin = { - .gpio = AT91_PIN_PC20, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-cd", - }, - .active_low = 1, - }, - { - .name = "LED4", - .pin = { - .gpio = AT91_PIN_PC20, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-c", - }, - .active_low = 1, - }, - { - .name = "LED6", - .pin = { - .gpio = AT91_PIN_PC19, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig1", - }, - .active_low = 1, - }, - { - .name = "LED6", - .pin = { - .gpio = AT91_PIN_PC19, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-d", - }, - .active_low = 1, - }, - { - .name = "LED7", - .pin = { - .gpio = AT91_PIN_PC18, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig2", - }, - .active_low = 1, - }, - { - .name = "LED7", - .pin = { - .gpio = AT91_PIN_PC18, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-e", - }, - .active_low = 1, - }, - { - .name = "LED8", - .pin = { - .gpio = AT91_PIN_PC17, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-sig3", - }, - .active_low = 1, - }, - { - .name = "LED8", - .pin = { - .gpio = AT91_PIN_PC17, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "led-f", - }, - .active_low = 1, - }, - { - .name = "RI_B", - .pin = { - .gpio = AT91_PIN_PC25, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-ri", - }, - .active_low = 1, - }, - { - .name = "DTR_B", - .pin = { - .gpio = AT91_PIN_PC26, - .flags = GPIOF_IN, - .label = "extserial-dtr", - }, - .active_low = 1, - }, - { - .name = "DSR_B", - .pin = { - .gpio = AT91_PIN_PC27, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-dsr", - }, - .active_low = 1, - }, - { - .name = "DCD_B", - .pin = { - .gpio = AT91_PIN_PC28, - .flags = GPIOF_OUT_INIT_HIGH, - .label = "extserial-dcd", - }, - .active_low = 1, - }, - { - .name = "BT_EN", - .pin = { - .gpio = AT91_PIN_PA28, - .flags = GPIOF_OUT_INIT_LOW, - .label = "bt-enabled", - }, - }, - { - .name = "WLAN_EN", - .pin = { - .gpio = AT91_PIN_PA27, - .flags = GPIOF_OUT_INIT_LOW, - .label = "wlan-enabled", - }, - }, - { }, -}; - -static struct attribute *mtr_platform_attributes[] = { - &dev_attr_vendor_id.attr, - &dev_attr_product_id.attr, - &dev_attr_device_id.attr, - &dev_attr_hw_version.attr, - &dev_attr_imei.attr, - &dev_attr_eth_mac.attr, - &dev_attr_wifi_mac.attr, - &dev_attr_reset.attr, - &dev_attr_reset_monitor.attr, - &dev_attr_radio_power_telit.attr, - &dev_attr_radio_reset_telit.attr, - &dev_attr_extserial_ri_gpio.attr, - &dev_attr_extserial_dtr.attr, - &dev_attr_extserial_dsr_gpio.attr, - &dev_attr_extserial_dcd_gpio.attr, - &dev_attr_eth0_enabled.attr, - &dev_attr_bt_enabled.attr, - &dev_attr_wlan_enabled.attr, - - &dev_attr_led_status.attr, - &dev_attr_led_sig1_gpio.attr, - &dev_attr_led_sig2_gpio.attr, - &dev_attr_led_sig3_gpio.attr, - &dev_attr_led_cd_gpio.attr, - &dev_attr_led_wifi_gpio.attr, - - &dev_attr_led_a_gpio.attr, - &dev_attr_led_b_gpio.attr, - &dev_attr_led_c_gpio.attr, - &dev_attr_led_d_gpio.attr, - &dev_attr_led_e_gpio.attr, - &dev_attr_led_f_gpio.attr, - - NULL, -}; - -static struct attribute_group mtr_platform_attribute_group = { - .attrs = mtr_platform_attributes -}; -- cgit v1.2.3 From ddb473a94114a6de7f0ec0dbd3a90021b2baa87f Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 8 Oct 2014 11:24:40 -0500 Subject: mts-io: improve cleanup on module unload or init error remove unused attributes remove unused files clean up mtr2d2.c --- io-module/mtr2d2.c | 49 ----------- io-module/mts_io.c | 138 +++++++----------------------- io-module/telit_radio.c | 219 ------------------------------------------------ 3 files changed, 30 insertions(+), 376 deletions(-) delete mode 100644 io-module/telit_radio.c diff --git a/io-module/mtr2d2.c b/io-module/mtr2d2.c index 428d71c..7e44881 100644 --- a/io-module/mtr2d2.c +++ b/io-module/mtr2d2.c @@ -265,9 +265,6 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { { }, }; -static int mtr2d2_platform_attributes_max_size = 64; // including NULL at end -static int mtr2d2_platform_attributes_size = 21; - static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_vendor_id.attr, &dev_attr_product_id.attr, @@ -291,52 +288,6 @@ static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_led_c_gpio.attr, &dev_attr_led_d_gpio.attr, &dev_attr_led_e_gpio.attr, - - /* extra space for the accessory card attributes */ - NULL, // index 20 - NULL, // index 21 - NULL, // index 22 - NULL, // index 23 - NULL, // index 24 - NULL, // index 25 - NULL, // index 26 - NULL, // index 27 - NULL, // index 28 - NULL, // index 29 - NULL, // index 30 - NULL, // index 31 - NULL, // index 32 - NULL, // index 33 - NULL, // index 34 - NULL, // index 35 - NULL, // index 36 - NULL, // index 37 - NULL, // index 38 - NULL, // index 39 - NULL, // index 40 - NULL, // index 41 - NULL, // index 42 - NULL, // index 43 - NULL, // index 44 - NULL, // index 45 - NULL, // index 46 - NULL, // index 47 - NULL, // index 48 - NULL, // index 49 - NULL, // index 50 - NULL, // index 51 - NULL, // index 52 - NULL, // index 53 - NULL, // index 54 - NULL, // index 55 - NULL, // index 56 - NULL, // index 57 - NULL, // index 58 - NULL, // index 59 - NULL, // index 60 - NULL, // index 61 - NULL, // index 62 - NULL, // index 63 NULL, }; diff --git a/io-module/mts_io.c b/io-module/mts_io.c index fa61e1f..0710345 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -98,9 +98,6 @@ static DEFINE_MUTEX(mts_io_mutex); #include "mtac_gpiob.c" #include "mtac_mfser.c" -/* telit radio reset handling */ -#include "telit_radio.c" - /* reset button handling */ #define RESET_CHECK_PER_SEC 8 #define RESET_INTERVAL (HZ / RESET_CHECK_PER_SEC) @@ -250,62 +247,12 @@ static ssize_t mts_attr_store_radio_reset(struct device *dev, return count; } -static ssize_t mts_attr_store_ndc_reset(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int value; - int err; - struct gpio_pin *pin; - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - if (value != 0) { - return -EINVAL; - } - - pin = gpio_pin_by_name("NDC_RESET"); - - if (!pin) { - return -ENODEV; - } - - mutex_lock(&mts_io_mutex); - - // 1ms low reset - err = reset_gpio_pin(pin, 1, 0); - - mutex_unlock(&mts_io_mutex); - - if (err) { - return err; - } - - return count; -} - static DEVICE_ATTR_MTS(dev_attr_radio_reset, "radio-reset", mts_attr_show_gpio_pin, mts_attr_store_radio_reset); -static DEVICE_ATTR_MTS(dev_attr_ndc_reset, "ndc-reset", - mts_attr_show_gpio_pin, mts_attr_store_ndc_reset); /* shared gpio attributes */ static DEVICE_ATTR_MTS(dev_attr_radio_power, "radio-power", mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_eth0_enabled, "eth0-enabled", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_bt_enabled, "bt-enabled", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_wlan_enabled, "wlan-enabled", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_RO_MTS(dev_attr_extserial_dtr, "extserial-dtr", - mts_attr_show_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_extserial_dsr_gpio, "extserial-dsr", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_extserial_ri_gpio, "extserial-ri", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_extserial_dcd_gpio, "extserial-dcd", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); /* shared gpio-based LEDs */ static DEVICE_ATTR_MTS(dev_attr_led_status, "led-status", @@ -321,8 +268,6 @@ static DEVICE_ATTR_RO_MTS(dev_attr_led_ls, "led-ls", mts_attr_show_gpio_pin); #endif -static DEVICE_ATTR_MTS(dev_attr_led_wifi_gpio, "led-wifi", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); static DEVICE_ATTR_MTS(dev_attr_led_b_gpio, "led-b", mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); @@ -342,9 +287,6 @@ static DEVICE_ATTR_MTS(dev_attr_led_d_gpio, "led-d", mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); static DEVICE_ATTR_MTS(dev_attr_led_e_gpio, "led-e", mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_led_f_gpio, "led-f", - mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); - /* eeprom info */ static ssize_t mts_attr_show_product_info(struct device *dev, @@ -515,29 +457,46 @@ static int mts_id_eeprom_load(void) return 0; } +static void cleanup(void) +{ + int port; + int port_index; + + log_info("cleaning up...."); + sysfs_remove_link(&mts_io_platform_device->dev.parent->kobj, "mtcdp"); + platform_device_unregister(mts_io_platform_device); + for (port_index = 0, port = 1; port_index < NUM_AP; port_index++, port++) { + if (port_info[port_index]) { + port_info[port_index]->teardown(port); + kfree(port_info[port_index]); + } + } + log_info("done cleaning up...."); +} + static int __init mts_io_init(void) { - struct gpio_pin *pin; int ret; - int port; int port_index; log_info("init: " DRIVER_VERSION); ret = mts_id_eeprom_load(); if (ret) { - goto error1; + cleanup(); + return ret; } mts_io_platform_device = platform_device_alloc(PLATFORM_NAME, -1); if (!mts_io_platform_device) { - ret = -ENOMEM; - goto error1; + cleanup(); + return -ENOMEM; } ret = platform_device_add(mts_io_platform_device); if (ret) { - goto error2; + cleanup(); + return ret; } /* preserve backwards compatibility with old mtcdp platform name */ @@ -546,71 +505,34 @@ static int __init mts_io_init(void) "mtcdp"); if (ret) { log_error("sysfs_create_link failed: %d", ret); - goto error3; + cleanup(); + return ret; } if (NUM_AP) { - for (port = 0; port < NUM_AP; port++) { - port_info[port] = NULL; + for (port_index = 0; port_index < NUM_AP; port_index++) { + port_info[port_index] = NULL; } init_accessory_ports(); } ret = sysfs_create_group(&mts_io_platform_device->dev.kobj, attr_group); if (ret) { - goto error4; - } - - for (pin = gpio_pins; *pin->name; pin++) { - ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label); - if (ret) { - log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret); - } + cleanup(); + return ret; } // start the reset handler reset_callback(NULL); return 0; - -error4: - sysfs_remove_group(&mts_io_platform_device->dev.kobj, attr_group); - sysfs_remove_link(&mts_io_platform_device->dev.parent->kobj, "mtcdp"); -error3: - platform_device_del(mts_io_platform_device); -error2: - platform_device_put(mts_io_platform_device); -error1: - log_error("init failed: %d", ret); - for (port = 0, port_index = 1; port < NUM_AP; port++, port_index++) { - if (port_info[port]) { - port_info[port]->teardown(port_index); - kfree(port_info[port]); - } - } - - return ret; } static void __exit mts_io_exit(void) { - int port; - int port_index; - cancel_delayed_work_sync(&reset_work); - 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 (port = 0, port_index = 1; port < NUM_AP; port++, port_index++) { - if (port_info[port]) { - port_info[port]->teardown(port_index); - kfree(port_info[port]); - } - } + cleanup(); log_info("exiting"); } diff --git a/io-module/telit_radio.c b/io-module/telit_radio.c deleted file mode 100644 index fbac4fa..0000000 --- a/io-module/telit_radio.c +++ /dev/null @@ -1,219 +0,0 @@ - -static int radio_off_telit(void) -{ - int value, ret; - struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON"); - struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF"); - struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST"); - - if (!onoff_pin || !pwrmon_pin || !rst_pin) { - return -ENODEV; - } - - value = gpio_get_value(pwrmon_pin->pin.gpio); - if(value == 0) { - log_error("radio is already off"); - return -EINVAL; - } - - // drive on/off pin low for at least 3 sec - log_info("shutting down radio"); - ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - msleep(3500); - - // set on/off pin high - ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - // wait for radio to power off - msleep(5000); - - // check that power is low - value = gpio_get_value(pwrmon_pin->pin.gpio); - if(value != 0) { - log_warning("radio is still on. performing radio reset."); - //Perform Hard Reset - ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - msleep(500); - - // set pin high - ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - } else { - log_info("radio has been shut down"); - } - - return ret; -} - -static int radio_on_telit(void) -{ - int value, ret; - struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON"); - struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF"); - struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST"); - - if (!onoff_pin || !pwrmon_pin || !rst_pin) { - return -ENODEV; - } - - value = gpio_get_value(pwrmon_pin->pin.gpio); - if(value != 0) { - log_error("radio is already on"); - return -EINVAL; - } - - // drive on/off pin low for at least 5 sec - log_info("turning on radio"); - ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - msleep(5500); - - // set on/off pin high - ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - msleep(200); - - // check that power is high - value = gpio_get_value(pwrmon_pin->pin.gpio); - if(value == 0) { - log_warning("radio is still off. performing radio reset"); - //Perform Hard Reset - ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - msleep(500); - - // set pin high - ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - } else { - log_info("radio has been turned on"); - } - - return ret; -} - -static ssize_t mts_attr_store_radio_power_telit(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int value; - int err; - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - if (value == 0) { - mutex_lock(&mts_io_mutex); - err = radio_off_telit(); - mutex_unlock(&mts_io_mutex); - } else { - mutex_lock(&mts_io_mutex); - err = radio_on_telit(); - mutex_unlock(&mts_io_mutex); - } - - if (err) { - return err; - } - - return count; -} - -static int radio_reset_telit(void) -{ - int ret; - struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST"); - struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF"); - - if (!rst_pin || !onoff_pin) { - return -ENODEV; - } - - // drive reset pin low for 500ms - ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - msleep(500); - - // set pin high - ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - // wait for 2 sec before toggling on/off pin - msleep(2000); - - // drive on/off pin low for 6 sec - ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - msleep(6000); - - // set on/off pin high - ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP); - if (ret) { - return ret; - } - - return ret; -} - -static ssize_t mts_attr_store_radio_reset_telit(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int value; - int err; - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - if (value != 0) { - return -EINVAL; - } - - mutex_lock(&mts_io_mutex); - - err = radio_reset_telit(); - - mutex_unlock(&mts_io_mutex); - - if (err) { - return err; - } - - return count; -} - -static DEVICE_ATTR_MTS(dev_attr_radio_power_telit, "radio-power", - mts_attr_show_gpio_pin, mts_attr_store_radio_power_telit); - -static DEVICE_ATTR_MTS(dev_attr_radio_reset_telit, "radio-reset", - mts_attr_show_gpio_pin, mts_attr_store_radio_reset_telit); -- cgit v1.2.3 From 44f859e243f646f3d2bd9540027816e3b4981ab9 Mon Sep 17 00:00:00 2001 From: Mike Fiore Date: Wed, 8 Oct 2014 15:30:24 -0500 Subject: mts_io: init: add registering of gpio pins back to __init, shouldn't have been removed --- io-module/mts_io.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 0710345..6ce8981 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -476,6 +476,7 @@ static void cleanup(void) static int __init mts_io_init(void) { + struct gpio_pin *pin; int ret; int port_index; @@ -522,6 +523,13 @@ static int __init mts_io_init(void) return ret; } + for (pin = gpio_pins; *pin->name; pin++) { + ret = gpio_request_one(pin->pin.gpio, pin->pin.flags, pin->pin.label); + if (ret) { + log_debug("could not request pin %s (%d) but it could have already been requested under a different pin name", pin->name, ret); + } + } + // start the reset handler reset_callback(NULL); -- cgit v1.2.3