diff options
-rw-r--r-- | io-module/Makefile | 1 | ||||
-rw-r--r-- | io-module/adc.c | 87 | ||||
-rw-r--r-- | io-module/mt100eocg.c | 221 | ||||
-rw-r--r-- | io-module/mtac.c | 232 | ||||
-rw-r--r-- | io-module/mtac_gpiob.c | 596 | ||||
-rw-r--r-- | io-module/mtac_mfser.c | 285 | ||||
-rw-r--r-- | io-module/mtcdp.c | 310 | ||||
-rw-r--r-- | io-module/mtdc_gpiob.c | 270 | ||||
-rw-r--r-- | io-module/mtr.c | 468 | ||||
-rw-r--r-- | io-module/mtr2.c | 515 | ||||
-rw-r--r-- | io-module/mtr2d2.c | 197 | ||||
-rw-r--r-- | io-module/mts_io.c | 584 | ||||
-rw-r--r-- | io-module/mts_io.h | 43 | ||||
-rw-r--r-- | io-module/spi.c | 767 | ||||
-rw-r--r-- | io-module/telit_radio.c | 219 | ||||
-rwxr-xr-x | io-tool/mts-io-sysfs | 24 |
16 files changed, 1438 insertions, 3381 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); diff --git a/io-tool/mts-io-sysfs b/io-tool/mts-io-sysfs index 3961c03..3ecb100 100755 --- a/io-tool/mts-io-sysfs +++ b/io-tool/mts-io-sysfs @@ -76,15 +76,15 @@ usage() { #items for SHOW printf " SHOW-NAME := {\n" >&${out} - for f in $MTS_IO_DIR/*; + for f in `find $MTS_IO_DIR/* -follow -maxdepth 1 -type f`; do - FILENAME=${f##*/} + FILENAME=${f##*/mts-io/} case $FILENAME in modalias ) ;; power ) ;; - subsystem ) + subsystem* ) ;; uevent ) ;; @@ -97,9 +97,9 @@ usage() { #items for STORE printf " STORE-NAME := {\n" >&${out} - for f in $MTS_IO_DIR/*; + for f in `find $MTS_IO_DIR/* -follow -maxdepth 1 -type f`; do - FILENAME=${f##*/} + FILENAME=${f##*/mts-io/} case $FILENAME in #mac addresses are read-only mac-* ) @@ -108,7 +108,7 @@ usage() { *-id ) ;; #hw-version is read-only - hw-version ) + *hw-version ) ;; #imei is read-only imei ) @@ -117,17 +117,15 @@ usage() { ;; power ) ;; - subsystem ) + subsystem* ) ;; uevent ) ;; board-temperature ) ;; - extserial-dtr ) + *adc[0-9] ) ;; - adc[0-9] ) - ;; - din[0-9] ) + *din[0-9] ) ;; gpi[0-9] ) ;; @@ -145,8 +143,8 @@ usage() { printf " $FILENAME { 0 }\n" >&${out} ;; reset-monitor ) printf " $FILENAME { pid short-signal long-signal [extra-long-signal] }\n" >&${out} ;; - serial-mode ) - printf " $FILENAME { loopback | rs232 | rs422 | rs485 }\n" >&${out} ;; + *serial-mode ) + printf " $FILENAME { loopback | rs232 | rs485-half | rs422-485-full }\n" >&${out} ;; * ) printf " $FILENAME BOOLEAN\n" >&${out} ;; esac |