summaryrefslogtreecommitdiff
path: root/io-module
diff options
context:
space:
mode:
authorMike Fiore <mfiore@multitech.com>2014-10-09 07:38:20 -0500
committerMike Fiore <mfiore@multitech.com>2014-10-09 07:38:20 -0500
commitaf9b6ed9b53e34ff170645a114f95e82cbfe0101 (patch)
tree591634acb576d39b888d2131de84c6002a11e774 /io-module
parentda1090a73f312b14db0d7a93a9c9373fffd34958 (diff)
parent44f859e243f646f3d2bd9540027816e3b4981ab9 (diff)
downloadmts-io-af9b6ed9b53e34ff170645a114f95e82cbfe0101.tar.gz
mts-io-af9b6ed9b53e34ff170645a114f95e82cbfe0101.tar.bz2
mts-io-af9b6ed9b53e34ff170645a114f95e82cbfe0101.zip
Merge branch 'mtr2d2' into 'master'
Conflicts: io-module/mtdc_gpiob.c - remove, replaced by mtac_gpiob.c io-module/mtr2.c - remove, dropping support for this HW io-module/mts_io.c - keep changes from mtr2d2 branch io-module/spi.c - remove, no longer needed
Diffstat (limited to 'io-module')
-rw-r--r--io-module/Makefile1
-rw-r--r--io-module/adc.c87
-rw-r--r--io-module/mt100eocg.c221
-rw-r--r--io-module/mtac.c232
-rw-r--r--io-module/mtac_gpiob.c596
-rw-r--r--io-module/mtac_mfser.c285
-rw-r--r--io-module/mtcdp.c310
-rw-r--r--io-module/mtdc_gpiob.c270
-rw-r--r--io-module/mtr.c468
-rw-r--r--io-module/mtr2.c515
-rw-r--r--io-module/mtr2d2.c197
-rw-r--r--io-module/mts_io.c584
-rw-r--r--io-module/mts_io.h43
-rw-r--r--io-module/spi.c767
-rw-r--r--io-module/telit_radio.c219
15 files changed, 1427 insertions, 3368 deletions
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/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/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/mtac.c b/io-module/mtac.c
new file mode 100644
index 0000000..9b27e0d
--- /dev/null
+++ b/io-module/mtac.c
@@ -0,0 +1,232 @@
+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;
+}
+
+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;
+
+ 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_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);
+ value = -1;
+ }
+
+ return value;
+}
+
+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");
+ 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;
+ }
+ kobj_attr->show = ap_show_product_info;
+ attrs[*index++] = &kobj_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");
+ 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;
+ }
+ kobj_attr->show = ap_show_product_info;
+ attrs[(*index)++] = &kobj_attr->attr;
+
+ 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;
+ }
+ kobj_attr->show = ap_show_product_info;
+ attrs[(*index)++] = &kobj_attr->attr;
+
+ 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;
+ }
+ kobj_attr->show = ap_show_product_info;
+ attrs[(*index)++] = &kobj_attr->attr;
+
+ 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;
+ }
+ 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, int port) {
+ struct gpio_pin *pin;
+ char *pin_attr_name;
+ int port_index = port - 1;
+
+ 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)) {
+ 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;
+ 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;
+ }
+
+ 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;
+ 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;
+ }
+
+ 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
new file mode 100644
index 0000000..0485494
--- /dev/null
+++ b/io-module/mtac_gpiob.c
@@ -0,0 +1,596 @@
+struct spi_device *gpiob_spi[NUM_AP][3];
+struct spi_driver gpiob_spi_drivers[NUM_AP][3];
+
+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);
+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;
+}
+
+/* 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;
+ 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[port_index] = 0x00;
+ spi_writen(gpiob_spi[port_index][dev], &spi_ap_dout_value[port_index], 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;
+}
+
+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 "";
+ }
+ }
+}
+
+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;
+
+ sscanf(attr->attr.name, "din%d", &channel);
+ if (channel < 0 || channel > 3) {
+ log_error("channel %d is invalid", channel);
+ 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);
+
+ tmp = spi_readn(gpiob_spi[port_index][din], &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 kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int value;
+ int channel;
+ int port;
+ int port_index;
+ u8 bit;
+
+ sscanf(attr->attr.name, "dout%d", &channel);
+ if (channel < 0 || channel > 3) {
+ log_error("channel %d is invalid", channel);
+ 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);
+ return -EINVAL;
+ }
+
+ mutex_lock(&spi_ap_dout_mutex);
+
+ if (value) {
+ spi_ap_dout_value[port_index] &= ~bit;
+ } else {
+ spi_ap_dout_value[port_index] |= bit;
+ }
+
+ spi_writen(gpiob_spi[port_index][dout], &spi_ap_dout_value[port_index], 1);
+
+ mutex_unlock(&spi_ap_dout_mutex);
+
+ return count;
+}
+
+static ssize_t mts_attr_show_ap_dout(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ int value;
+ int channel;
+ int port;
+ int port_index;
+ u8 bit;
+
+ sscanf(attr->attr.name, "dout%d", &channel);
+ if (channel < 0 || channel > 3) {
+ log_error("channel %d is invalid", channel);
+ 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[port_index] & bit ? 0 : 1;
+
+ mutex_unlock(&spi_ap_dout_mutex);
+
+ return sprintf(buf, "%d\n", value);
+}
+
+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];
+
+ memset(tx, 0, sizeof(tx));
+ memset(rx, 0, sizeof(rx));
+
+ sscanf(attr->attr.name, "adc%d", &channel);
+ if (channel < 0 || channel > 2) {
+ log_error("channel %d is invalid", channel);
+ 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);
+ tx[0] = tx_data >> 8;
+ tx[1] = tx_data & 0xFF;
+ tmp = spi_writen(gpiob_spi[port_index][adc], 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(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(gpiob_spi[port_index][adc], 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);
+}
+
+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
+// 1 vendor-id
+// 1 product-id
+// 1 device-id
+// 1 hw-version
+// NULL
+static int ap_gpiob_attrs_size = 20;
+
+static bool gpiob_setup(enum ap port) {
+ int i;
+ int port_index = port - 1;
+ 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);
+
+ 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;
+ }
+
+ // 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", i);
+ 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;
+ attrs[index++] = &attr->attr;
+ }
+
+ // add digital outputs
+ for (i = 0; i < 4; i++) {
+ sprintf(buf, "dout%d", i);
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ 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;
+ attrs[index++] = &attr->attr;
+ }
+
+ // add analog to digital
+ for (i = 0; i < 3; i++) {
+ sprintf(buf, "adc%d", i);
+ attr = create_attribute(buf, MTS_ATTR_MODE_RO);
+ if (! attr) {
+ log_error("failed to create attribute [%s] for GPIOB in port %d", buf, port);
+ return false;
+ }
+ attr->show = mts_attr_show_ap_adc;
+ attrs[index++] = &attr->attr;
+ }
+
+ // add LEDs
+ for (i = 1; i <= 2; i++) {
+ sprintf(buf, "led%d", i);
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ 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;
+ attrs[index++] = &attr->attr;
+ }
+
+ // add misc attributes
+ sprintf(buf, "dout-enable");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ 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;
+ attrs[index++] = &attr->attr;
+
+ sprintf(buf, "reset");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ 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;
+ 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] for GPIOB in port %d", buf, port);
+ 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] for GPIOB in port %d", buf, port);
+ 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] for GPIOB in port %d", buf, port);
+ 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;
+ }
+
+ 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 = 0; i < ap_gpiob_attrs_size; i++) {
+ if (attrs[i]) {
+ if (attrs[i]->name)
+ kfree(attrs[i]->name);
+
+ 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);
+ 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]);
+
+ return true;
+}
+
+bool set_gpiob_info(struct ap_info* info) {
+ snprintf(info->product_id, 32, "%s", PRODUCT_ID_MTAC_GPIOB);
+ info->setup = &gpiob_setup;
+ info->teardown = &gpiob_teardown;
+ 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
new file mode 100644
index 0000000..27ca4dc
--- /dev/null
+++ b/io-module/mtac_mfser.c
@@ -0,0 +1,285 @@
+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 "";
+ }
+ }
+}
+
+static ssize_t mts_attr_show_mfser_mode(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ int ret;
+ int port;
+ int modesel0;
+ int modesel1;
+
+ struct gpio_pin *pin_modesel0;
+ struct gpio_pin *pin_modesel1;
+
+ port = port_from_kobject(kobj);
+ if (port < 0) {
+ log_error("port_from_kobject returned %d", port);
+ return -EINVAL;
+ }
+
+ 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)
+ 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 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;
+
+ port = port_from_kobject(kobj);
+ if (port < 0) {
+ log_error("port_from_kobject returned %d", port);
+ return -EINVAL;
+ }
+
+ 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)
+ 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;
+}
+
+// 1 serial mode
+// 1 rs4xx term resistor
+// 1 rts override
+// 1 vendor-id
+// 1 product-id
+// 1 device-id
+// 1 hw-version
+// NULL
+static size_t ap_mfser_attrs_size = 8;
+
+static bool mfser_setup(enum ap port) {
+ int i;
+ int port_index = port - 1;
+ 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);
+
+ 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;
+ }
+
+ // 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");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ 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;
+ attrs[index++] = &attr->attr;
+
+ sprintf(buf, "rs4xx-term-res");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ 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;
+ attrs[index++] = &attr->attr;
+
+ sprintf(buf, "rts-override");
+ attr = create_attribute(buf, MTS_ATTR_MODE_RW);
+ if (! attr) {
+ 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;
+ attrs[index++] = &attr->attr;
+
+ // add attributes for eeprom contents
+ 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;
+ }
+
+ return true;
+}
+
+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 = 0; i < ap_mfser_attrs_size; i++) {
+ if (attrs[i]) {
+ if (attrs[i]->name)
+ kfree(attrs[i]->name);
+
+ kfree(attrs[i]);
+ }
+ }
+
+ 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) {
+ snprintf(info->product_id, 32, "%s", PRODUCT_ID_MTAC_MFSER);
+ info->setup = &mfser_setup;
+ info->teardown = &mfser_teardown;
+ info->gpio_pin_name_by_attr_name = &mfser_gpio_pin_name_by_attr_name;
+
+ return true;
+}
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/mtdc_gpiob.c b/io-module/mtdc_gpiob.c
deleted file mode 100644
index 7cd38a8..0000000
--- a/io-module/mtdc_gpiob.c
+++ /dev/null
@@ -1,270 +0,0 @@
-
-struct gpio_pin *dc_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";
- } 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_dc_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);
-
- 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_dc_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);
-
- 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_dc_din(struct device *dev, struct device_attribute *attr, char *buf)
-{
- int tmp;
- u8 bit;
- u8 byte;
-
- if (!spi_dc_din_dev) {
- log_error("dc din device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "din0")) {
- bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "din1")) {
- bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "din2")) {
- bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "din3")) {
- bit = BIT(3);
- } else {
- log_error("dc din attr does not exist");
- return -ENOENT;
- }
-
- tmp = spi_readn(spi_dc_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_store_dc_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- int value;
- u8 bit;
-
- if (!spi_dc_dout_dev) {
- log_error("dc dout device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "dout0")) {
- bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "dout1")) {
- bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "dout2")) {
- bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "dout3")) {
- bit = BIT(3);
- } else {
- log_error("dc dout attr does not exist");
- return -ENOENT;
- }
-
- if (sscanf(buf, "%i", &value) != 1) {
- log_error("dc dout attr invalid argument");
- return -EINVAL;
- }
-
- mutex_lock(&spi_dc_dout_mutex);
-
- if (value) {
- spi_dc_dout_value &= ~bit;
- } else {
- spi_dc_dout_value |= bit;
- }
-
- spi_writen(spi_dc_dout_dev, &spi_dc_dout_value, 1);
-
- mutex_unlock(&spi_dc_dout_mutex);
-
- return count;
-}
-
-static ssize_t mts_attr_show_dc_dout(struct device *dev, struct device_attribute *attr, char *buf)
-{
- int value;
- u8 bit;
-
- if (!spi_dc_dout_dev) {
- log_error("dc dout device not present");
- return -ENODEV;
- }
-
- if (!strcmp(attr->attr.name, "dout0")) {
- bit = BIT(0);
- } else if (!strcmp(attr->attr.name, "dout1")) {
- bit = BIT(1);
- } else if (!strcmp(attr->attr.name, "dout2")) {
- bit = BIT(2);
- } else if (!strcmp(attr->attr.name, "dout3")) {
- bit = BIT(3);
- } else {
- log_error("dc dout attr does not exist");
- return -ENOENT;
- }
-
- mutex_lock(&spi_dc_dout_mutex);
-
- value = spi_dc_dout_value & bit ? 0 : 1;
-
- mutex_unlock(&spi_dc_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)
-{
- 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];
-
- if (!spi_dc_adc_dev) {
- log_error("dc adc device not present");
- return -ENODEV;
- }
-
- memset(tx, 0, sizeof(tx));
- memset(rx, 0, sizeof(rx));
-
- if (!strcmp(attr->attr.name, "adc0")) {
- channel = 0;
- } else if (!strcmp(attr->attr.name, "adc1")) {
- channel = 1;
- } else if (! strcmp(attr->attr.name, "adc2")) {
- channel = 2;
- } else {
- log_error("dc 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_dc_adc_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_dc_adc_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);
- 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);
-}
-
-/* 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);
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
-};
diff --git a/io-module/mtr2.c b/io-module/mtr2.c
deleted file mode 100644
index 6807088..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 accessory 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_accessory_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_accessory_card_attributes(void)
-{
- size_t platform_attrs_size = sizeof(mtr2_platform_attributes) / sizeof(struct attribute *);
- size_t accessory_card_attrs_size = sizeof(mtr2_accessory_card_attributes) / sizeof(struct attribute *);
- size_t platform_attrs_index;
- size_t accessory_card_attrs_index;
- size_t copy_length = accessory_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 + accessory_card_attrs_size) {
- log_error("not enough room for MTR2 accessory card attributes!");
- return false;
- }
-
- for (accessory_card_attrs_index = 0; accessory_card_attrs_index < copy_length; accessory_card_attrs_index++, platform_attrs_index++) {
- mtr2_platform_attributes[platform_attrs_index] = mtr2_accessory_card_attributes[accessory_card_attrs_index];
- }
-
- return true;
-}
-
-static struct attribute_group mtr2_platform_attribute_group = {
- .attrs = mtr2_platform_attributes
-};
diff --git a/io-module/mtr2d2.c b/io-module/mtr2d2.c
index 58aeb03..7e44881 100644
--- a/io-module/mtr2d2.c
+++ b/io-module/mtr2d2.c
@@ -1,9 +1,8 @@
-
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 +10,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 +18,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 +38,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 +56,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 +65,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 +83,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 +101,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,32 +119,149 @@ 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",
+ .label = "led-e",
},
.active_low = 1,
},
+
+ // gpio pins for Accessory Card 1
{
- .name = "LED13",
+ .name = "AP1_RESET",
.pin = {
- .gpio = AT91_PIN_PA29,
+ .gpio = AT91_PIN_PB12,
.flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-wifi",
+ .label = "ap1-reset",
+ }
+ },
+ {
+ .name = "AP1_GPIO1",
+ .pin = {
+ .gpio = AT91_PIN_PC6,
+ .flags = GPIOF_OUT_INIT_LOW,
+ .label = "ap1-gpio1",
},
.active_low = 1,
},
{
- .name = "LED13",
+ .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",
+ }
+ },
+ {
+ .name = "AP1_GPS_PPS",
.pin = {
.gpio = AT91_PIN_PA29,
+ .flags = GPIOF_IN,
+ .label = "ap1-gps-pps",
+ }
+ },
+
+ // gpio pins for Accessory Card 2
+ {
+ .name = "AP2_RESET",
+ .pin = {
+ .gpio = AT91_PIN_PB13,
.flags = GPIOF_OUT_INIT_HIGH,
- .label = "led-b",
+ .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",
+ }
+ },
+ {
+ .name = "AP2_GPS_PPS",
+ .pin = {
+ .gpio = AT91_PIN_PA6,
+ .flags = GPIOF_IN,
+ .label = "ap2-gps-pps",
+ }
+ },
+
{ },
};
@@ -162,7 +278,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,
@@ -173,40 +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,
- &dev_attr_led_f_gpio.attr,
-
- &dev_attr_board_temperature.attr,
-
- /* extra space for the accessory card attributes */
- 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,
};
diff --git a/io-module/mts_io.c b/io-module/mts_io.c
index 229a8f7..6ce8981 100644
--- a/io-module/mts_io.c
+++ b/io-module/mts_io.c
@@ -5,6 +5,7 @@
*
* Authors: James Maki <jmaki@multitech.com>
* Jesse Gilles <jgilles@multitech.com>
+ * Mike Fiore <mfiore@multitech.com>
*
* 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
@@ -53,34 +54,35 @@
#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;
-/* 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 has_accessory_card_port_1 = false;
-bool has_accessory_card_port_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];
+/* 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 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;
-static uint8_t has_spi_temp;
+static struct ap_info* port_info[NUM_AP];
static struct platform_device *mts_io_platform_device;
static struct attribute_group *attr_group;
@@ -91,17 +93,10 @@ 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 "mtdc_gpiob.c"
-
-/* telit radio reset handling */
-#include "telit_radio.c"
+#include "mtac.c"
+#include "mtac_gpiob.c"
+#include "mtac_mfser.c"
/* reset button handling */
#define RESET_CHECK_PER_SEC 8
@@ -252,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",
@@ -323,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);
@@ -344,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,
@@ -365,14 +305,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],
@@ -399,166 +331,89 @@ 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 "mtr2.c"
-#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]));
-/* 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)
-{
- memcpy(&ap1_eeprom, mts_ap1_eeprom, sizeof(mts_ap1_eeprom));
+ 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 {
+ 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 (mts_ap1_eeprom[0] == 0xFF) {
- log_error("uninitialized eeprom on accessory card");
- return -EIO;
- } else if (mts_ap1_eeprom[0] == 0x00) {
- log_info("no accessory card inserted");
- return 0;
+ if (strstr(ap_eeprom[port_index].product_id, PRODUCT_ID_MTAC_GPIOB)) {
+ 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)) {
+ 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;
+ }
+
+ 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]);
+ }
+
+ 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;
+ }
}
- has_accessory_card_port_1 = true;
-
- log_info("accessory card vendor-id: %.32s", ap1_eeprom.vendor_id);
- log_info("accessory card product-id: %.32s", ap1_eeprom.product_id);
- log_info("accessory card device-id: %.32s", ap1_eeprom.device_id);
- log_info("accessory card hw-version: %.32s", ap1_eeprom.hw_version);
- /* TODO: only show the mac address if this is the ethernet card */
- log_info("accessory 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]);
+ return true;
+}
- return 0;
+static void init_accessory_ports(void)
+{
+ int i;
+ for (i = 1; i <= NUM_AP; i++) {
+ if (! load_port(i)) {
+ log_error("failed to load accessory card in port %d", i);
+ }
+ }
}
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 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_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;
- accessory_card_capable = true;
- 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;
- 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_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;
- accessory_card_capable = true;
- 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) {
+ } 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);
- /*
- } 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));
@@ -580,97 +435,69 @@ 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;
}
+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_index;
log_info("init: " DRIVER_VERSION);
ret = mts_id_eeprom_load();
if (ret) {
- goto error1;
- }
-
- if (accessory_card_capable) {
- mts_ap1_product_id = MTDC_NONE;
- ret = mts_ap_eeprom_load();
- if (ret) {
- /* error reading the EEPROM from the accessory card */
- log_error("error reading accessory card eeprom: %d", ret);
- log_error("unable to initialize accessory card");
- } else if (has_accessory_card_port_1) {
- /* no error and we have a accessory card */
- if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) {
- mts_ap1_product_id = MTDC_GPIOB_0_0;
- }
-
- switch(mts_ap1_product_id) {
- case MTDC_GPIOB_0_0:
- log_debug("adding GPIO accessory card attributes");
- if (! mtr2_add_accessory_card_attributes()) {
- log_error("failed to add GPIO accessory card attributes");
- goto error1;
- } else {
- log_info("successfully added GPIO accessory card attributes");
- }
-
- log_debug("registering accessory 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 accessory 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 accessory 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("accessory card '%s' currently unsupported", ap1_eeprom.product_id);
- }
- }
+ 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 */
@@ -679,62 +506,21 @@ static int __init mts_io_init(void)
"mtcdp");
if (ret) {
log_error("sysfs_create_link failed: %d", ret);
- goto error3;
- }
-
- ret = sysfs_create_group(&mts_io_platform_device->dev.kobj, attr_group);
- if (ret) {
- 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;
- }
+ cleanup();
+ return ret;
}
- if ( has_spi_temp ) {
- ret = spi_register_driver(&mts_spi_board_temp_driver);
- if (ret) {
- goto error8;
+ if (NUM_AP) {
+ for (port_index = 0; port_index < NUM_AP; port_index++) {
+ port_info[port_index] = NULL;
}
+ init_accessory_ports();
}
- /* 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);
+ ret = sysfs_create_group(&mts_io_platform_device->dev.kobj, attr_group);
+ if (ret) {
+ cleanup();
+ return ret;
}
for (pin = gpio_pins; *pin->name; pin++) {
@@ -744,92 +530,17 @@ 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_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);
-
- return ret;
}
static void __exit mts_io_exit(void)
{
- 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);
+ cancel_delayed_work_sync(&reset_work);
- if (has_spi_sout)
- spi_unregister_driver(&mts_spi_sout_driver);
-
- if (has_accessory_card_port_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);
- 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);
+ cleanup();
log_info("exiting");
}
@@ -842,10 +553,9 @@ 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-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/mts_io.h b/io-module/mts_io.h
index fc37ac5..3645e17 100644
--- a/io-module/mts_io.h
+++ b/io-module/mts_io.h
@@ -42,43 +42,35 @@ 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_MTDC_GPIOB "MTDC-GPIOB"
-
+#define PRODUCT_ID_MTAC_GPIOB "MTAC-GPIOB"
+#define PRODUCT_ID_MTAC_MFSER "MTAC-MFSER"
+#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"
#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,
};
enum {
- MTDC_NONE,
- MTDC_GPIOB_0_0,
+ 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)
@@ -100,5 +92,26 @@ 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 {
+ char product_id[32];
+ bool (*setup)(enum ap port);
+ bool (*teardown)(enum ap port);
+ char* (*gpio_pin_name_by_attr_name)(const char* name, int port);
+};
+
#endif /* ~__MTS_IO_H */
diff --git a/io-module/spi.c b/io-module/spi.c
deleted file mode 100644
index ce5c156..0000000
--- a/io-module/spi.c
+++ /dev/null
@@ -1,767 +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_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);
-MODULE_PARM_DESC(
- dc_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);
-MODULE_PARM_DESC(
- dc_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);
-MODULE_PARM_DESC(
- dc_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);
-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_dc_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");
- return -ENODEV;
- }
-
- spi->max_speed_hz = dc_dout_max_speed_hz;
- spi->mode = 0;
-
- log_debug("dc_dout_max_speed_hz: %d", dc_dout_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup dc dout failed");
- return tmp;
- }
-
- spi_dc_dout_value = 0x00;
- spi_writen(spi, &spi_dc_dout_value, 1);
-
- spi_dc_dout_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_dc_dout_remove(struct spi_device *spi)
-{
- spi_dc_dout_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_dc_dout_driver = {
- .driver = {
- .name = "mts-io-dc-dout",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_dc_dout_probe,
- .remove = mts_spi_dc_dout_remove,
-};
-
-static int mts_spi_dc_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");
- return -ENODEV;
- }
-
- spi->max_speed_hz = dc_din_max_speed_hz;
- spi->mode = SPI_CPOL;
-
- log_debug("dc_din_max_speed_hz: %d", dc_din_max_speed_hz);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup accessory card din failed");
- return tmp;
- }
-
- spi_dc_din_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_dc_din_remove(struct spi_device *spi)
-{
- spi_dc_din_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_dc_din_driver = {
- .driver = {
- .name = "mts-io-dc-din",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_dc_din_probe,
- .remove = mts_spi_dc_din_remove,
-};
-
-static int mts_spi_dc_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");
- return -ENODEV;
- }
-
- spi->max_speed_hz = dc_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);
-
- tmp = spi_setup(spi);
- if (tmp < 0) {
- log_error("spi_setup accessory card adc failed");
- return tmp;
- }
-
- spi_dc_adc_dev = spi;
-
- return 0;
-}
-
-static int mts_spi_dc_adc_remove(struct spi_device *spi)
-{
- spi_dc_adc_dev = NULL;
-
- return 0;
-}
-
-static struct spi_driver mts_spi_dc_adc_driver = {
- .driver = {
- .name = "mts-io-dc-adc",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = mts_spi_dc_adc_probe,
- .remove = mts_spi_dc_adc_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,
-};
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);