From 9cf9a09c665ecfb6425a08e424b01c8cacbdb660 Mon Sep 17 00:00:00 2001 From: Jesse Gilles Date: Fri, 16 May 2014 16:43:44 -0500 Subject: Major changes to split sources up * moved common peripheral i/o functions to separate source files * moved device-specific setup to separate source files * removed LED blink functionality (unused) * mtcdp, mt100eocg are not supported, but code is included for possible future use --- io-module/adc.c | 87 ++ io-module/gpio.c | 83 ++ io-module/mt100eocg.c | 221 ++++ io-module/mtcdp.c | 310 +++++ io-module/mtr.c | 468 +++++++ io-module/mtr2.c | 515 ++++++++ io-module/mts_io.c | 3256 +++-------------------------------------------- io-module/mts_io.h | 19 + io-module/spi.c | 767 +++++++++++ io-module/telit_radio.c | 219 ++++ 10 files changed, 2831 insertions(+), 3114 deletions(-) create mode 100644 io-module/adc.c create mode 100644 io-module/gpio.c create mode 100644 io-module/mt100eocg.c create mode 100644 io-module/mtcdp.c create mode 100644 io-module/mtr.c create mode 100644 io-module/mtr2.c create mode 100644 io-module/spi.c create mode 100644 io-module/telit_radio.c diff --git a/io-module/adc.c b/io-module/adc.c new file mode 100644 index 0000000..bcb3598 --- /dev/null +++ b/io-module/adc.c @@ -0,0 +1,87 @@ + +#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/gpio.c b/io-module/gpio.c new file mode 100644 index 0000000..72c55f6 --- /dev/null +++ b/io-module/gpio.c @@ -0,0 +1,83 @@ + +struct gpio_pin *gpio_pin_by_name(const char *name) { + struct gpio_pin *pin; + + for (pin = gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->name, name)) { + return pin; + } + } + + log_error("pin named %s not found", name); + + return NULL; +} + +struct gpio_pin *gpio_pin_by_attr_name(const char *name) { + struct gpio_pin *pin; + + for (pin = gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->pin.label, name)) { + return pin; + } + } + + log_error("pin with attr name %s not found", name); + + return NULL; +} + +static ssize_t mts_attr_show_gpio_pin(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int value; + struct gpio_pin *pin = 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_gpio_pin(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + struct gpio_pin *pin = gpio_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + if (sscanf(buf, "%i", &value) != 1) { + return -EINVAL; + } + + if (pin->active_low) { + value = !value; + } + + mutex_lock(&mts_io_mutex); + + gpio_set_value(pin->pin.gpio, value); + + mutex_unlock(&mts_io_mutex); + + return count; +} diff --git a/io-module/mt100eocg.c b/io-module/mt100eocg.c new file mode 100644 index 0000000..8d2338d --- /dev/null +++ b/io-module/mt100eocg.c @@ -0,0 +1,221 @@ + +static struct gpio_pin gpio_pins_mt100eocg_0_0[] = { + { + .name = "ENIO", + .pin = AT91_PIN_PC15, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "ETH0_ENABLED", + .attr_name = "eth0-enabled", + .pin = AT91_PIN_PB31, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "RADIO_RESET", + .attr_name = "radio-reset", + .pin = AT91_PIN_PB30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "DEVICE_RESET", + .attr_name = "reset", + .pin = AT91_PIN_PA22, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "LED3", + .attr_name = "led3", + .pin = AT91_PIN_PC9, +#if LED_LS_CONTROLLABLE + .direction = GPIO_DIR_OUTPUT, +#else + .direction = GPIO_DIR_INPUT, +#endif + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "LED2", + .attr_name = "led2", + .pin = AT91_PIN_PA30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "RSERSRC", + .attr_name = "rsersrc", + .pin = AT91_PIN_PC7, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "TXD1", + .pin = AT91_PIN_PB17, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "DTR1", + .attr_name = "extserial-dtr", + .pin = AT91_PIN_PB18, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "DCD1", + .attr_name = "extserial-dcd", + .pin = AT91_PIN_PB3, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "GPIO11", + .attr_name = "gpio11", + .pin = AT91_PIN_PB19, + .direction = GPIO_DIR_OD, + .output_value = 1, + .use_pullup = 1, + }, + { + .name = "GPIO12", + .attr_name = "gpio12", + .pin = AT91_PIN_PB20, + .direction = GPIO_DIR_OD, + .output_value = 1, + .use_pullup = 1, + }, + { + .name = "ADC0", + .pin = AT91_PIN_PC0, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "ADC1", + .pin = AT91_PIN_PC1, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "ADC2", + .pin = AT91_PIN_PC2, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "ADC3", + .pin = AT91_PIN_PC3, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { }, +}; + +/* mt100eocg specific attributes */ +static DEVICE_ATTR_MTS(dev_attr_gpo1, "gpo1", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_gpo2, "gpo2", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_gpo3, "gpo3", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_gpo4, "gpo4", + mts_attr_show_dout, mts_attr_store_dout); + + +static DEVICE_ATTR_MTS(dev_attr_led1, "led1", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_led2, "led2", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); + +#if LED_LS_CONTROLLABLE +static DEVICE_ATTR_MTS(dev_attr_led3, "led3", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); +#else +static DEVICE_ATTR_RO_MTS(dev_attr_led3, "led3", mts_attr_show_gpio_pin); +#endif + +static DEVICE_ATTR_MTS(dev_attr_led4, "led4", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_led5, "led5", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_led6, "led6", + mts_attr_show_dout, mts_attr_store_dout); + +static DEVICE_ATTR_MTS(dev_attr_gpio11, "gpio11", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_gpio12, "gpio12", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); + +static DEVICE_ATTR_MTS(dev_attr_rsersrc, "rsersrc", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); + +static struct attribute *mt100eocg_platform_attributes[] = { + &dev_attr_vendor_id.attr, + &dev_attr_product_id.attr, + &dev_attr_device_id.attr, + &dev_attr_hw_version.attr, + &dev_attr_imei.attr, + &dev_attr_eth_mac.attr, + &dev_attr_extserial_dtr.attr, + &dev_attr_extserial_dcd_gpio.attr, + &dev_attr_rsersrc.attr, + &dev_attr_radio_reset.attr, + &dev_attr_eth0_enabled.attr, + &dev_attr_gpio11.attr, + &dev_attr_gpio12.attr, + + &dev_attr_gpo1.attr, + &dev_attr_gpo2.attr, + &dev_attr_gpo3.attr, + &dev_attr_gpo4.attr, + &dev_attr_led1.attr, + &dev_attr_led2.attr, + &dev_attr_led3.attr, + &dev_attr_led4.attr, + &dev_attr_led5.attr, + &dev_attr_led6.attr, + + &dev_attr_gpi5.attr, + &dev_attr_gpi6.attr, + &dev_attr_gpi7.attr, + &dev_attr_gpi8.attr, + &dev_attr_gpi9.attr, + &dev_attr_gpi10.attr, + + &dev_attr_board_temperature.attr, + + &dev_attr_adc0.attr, + &dev_attr_adc1.attr, + &dev_attr_adc2.attr, + &dev_attr_adc3.attr, + + NULL, +}; + +static struct attribute_group mt100eocg_platform_attribute_group = { + .attrs = mt100eocg_platform_attributes +}; diff --git a/io-module/mtcdp.c b/io-module/mtcdp.c new file mode 100644 index 0000000..31551b0 --- /dev/null +++ b/io-module/mtcdp.c @@ -0,0 +1,310 @@ + +#define USBH2_PS_CONTROLLABLE 0 + +static struct gpio_pin gpio_pins_mtcdp_0_0[] = { + { + .name = "ENIO", + .pin = AT91_PIN_PC15, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "ETH0_ENABLED", + .attr_name = "eth0-enabled", + .pin = AT91_PIN_PB31, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "RADIO_RESET", + .attr_name = "radio-reset", + .pin = AT91_PIN_PB30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "DEVICE_RESET", + .attr_name = "reset", + .pin = AT91_PIN_PA22, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "LS_LED", + .attr_name = "led-ls", + .pin = AT91_PIN_PC9, +#if LED_LS_CONTROLLABLE + .direction = GPIO_DIR_OUTPUT, +#else + .direction = GPIO_DIR_INPUT, +#endif + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "STATUS_LED", + .attr_name = "led-status", + .pin = AT91_PIN_PA30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "STATUS_LED", + .attr_name = "led-sdk-a", + .pin = AT91_PIN_PA30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, +#endif + { + .name = "RSERSRC", + .attr_name = "rsersrc", + .pin = AT91_PIN_PC7, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "DTR1", + .attr_name = "extserial-dtr", + .pin = AT91_PIN_PC10, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, + { }, +}; + +static struct gpio_pin gpio_pins_mtcdp_1_0[] = { + { + .name = "ENIO", + .pin = AT91_PIN_PC15, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "ETH0_ENABLED", + .attr_name = "eth0-enabled", + .pin = AT91_PIN_PB31, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "RADIO_RESET", + .attr_name = "radio-reset", + .pin = AT91_PIN_PB30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "DEVICE_RESET", + .attr_name = "reset", + .pin = AT91_PIN_PA22, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "LS_LED", + .attr_name = "led-ls", + .pin = AT91_PIN_PC9, +#if LED_LS_CONTROLLABLE + .direction = GPIO_DIR_OUTPUT, +#else + .direction = GPIO_DIR_INPUT, +#endif + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "STATUS_LED", + .attr_name = "led-status", + .pin = AT91_PIN_PA30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "STATUS_LED", + .attr_name = "led-sdk-a", + .pin = AT91_PIN_PA30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "RSERSRC", + .attr_name = "rsersrc", + .pin = AT91_PIN_PC7, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "TXD1", + .pin = AT91_PIN_PB17, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "DTR1", + .attr_name = "extserial-dtr", + .pin = AT91_PIN_PB18, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, + { + .name = "USBH2_PS_OC", + .attr_name = "usbh2-ps-oc", + .pin = AT91_PIN_PB19, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, +#if USBH2_PS_CONTROLLABLE + { + .name = "USBH2_PS_ENABLED", + .attr_name = "usbh2-ps-enabled", + .pin = AT91_PIN_PB20, + .direction = GPIO_DIR_OUTPUT, + .output_value = 0, + .use_pullup = 0, + .active_low = 1, + }, +#endif + { + .name = "NDC_RESET", + .attr_name = "ndc-reset", + .pin = AT91_PIN_PB21, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "ADC0", + .pin = AT91_PIN_PC0, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "ADC1", + .pin = AT91_PIN_PC1, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "ADC2", + .pin = AT91_PIN_PC2, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "ADC3", + .pin = AT91_PIN_PC3, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { }, +}; + +/* mtcdp specific attributes */ +static DEVICE_ATTR_MTS(dev_attr_led_sdk_a, "led-sdk-a", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); +static DEVICE_ATTR_RO_MTS(dev_attr_usbh2_ps_oc, "usbh2-ps-oc", + mts_attr_show_gpio_pin); + +#if USBH2_PS_CONTROLLABLE +static DEVICE_ATTR_MTS(dev_attr_usbh2_ps_enabled, "usbh2-ps-enabled", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); +#endif + +static struct attribute *mtcdp_platform_attributes[] = { + &dev_attr_vendor_id.attr, + &dev_attr_product_id.attr, + &dev_attr_device_id.attr, + &dev_attr_hw_version.attr, + &dev_attr_imei.attr, + &dev_attr_eth_mac.attr, + &dev_attr_reset.attr, + &dev_attr_reset_monitor.attr, + &dev_attr_radio_reset.attr, + &dev_attr_ndc_reset.attr, + &dev_attr_eth0_enabled.attr, + &dev_attr_extserial_dtr.attr, + &dev_attr_led_ls.attr, + &dev_attr_led_status.attr, + &dev_attr_led_sdk_a.attr, + &dev_attr_usbh2_ps_oc.attr, +#if USBH2_PS_CONTROLLABLE + &dev_attr_usbh2_ps_enabled.attr, +#endif + + &dev_attr_extserial_dcd.attr, + &dev_attr_extserial_ri.attr, + &dev_attr_extserial_dsr.attr, + &dev_attr_led_cd.attr, + &dev_attr_led_sdk_b.attr, + &dev_attr_led_sig1.attr, + &dev_attr_led_sdk_c.attr, + &dev_attr_led_sig2.attr, + &dev_attr_led_sdk_d.attr, + &dev_attr_led_sig3.attr, + &dev_attr_led_sdk_e.attr, + &dev_attr_led_dtr.attr, + &dev_attr_led_sdk_f.attr, + + &dev_attr_dout0.attr, + &dev_attr_dout1.attr, + &dev_attr_dout2.attr, + &dev_attr_dout3.attr, + &dev_attr_dout4.attr, + &dev_attr_dout5.attr, + &dev_attr_dout6.attr, + &dev_attr_dout7.attr, + + &dev_attr_din0.attr, + &dev_attr_din1.attr, + &dev_attr_din2.attr, + &dev_attr_din3.attr, + &dev_attr_din4.attr, + &dev_attr_din5.attr, + &dev_attr_din6.attr, + &dev_attr_din7.attr, + + &dev_attr_board_temperature.attr, + + &dev_attr_adc0.attr, + &dev_attr_adc1.attr, + &dev_attr_adc2.attr, + &dev_attr_adc3.attr, + + NULL, +}; + +static struct attribute_group mtcdp_platform_attribute_group = { + .attrs = mtcdp_platform_attributes +}; diff --git a/io-module/mtr.c b/io-module/mtr.c new file mode 100644 index 0000000..cef1560 --- /dev/null +++ b/io-module/mtr.c @@ -0,0 +1,468 @@ + +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 new file mode 100644 index 0000000..2efc85d --- /dev/null +++ b/io-module/mtr2.c @@ -0,0 +1,515 @@ + +static struct gpio_pin gpio_pins_mtr2_0_0[] = { + { + .name = "NETH_RST", + .pin = { + .gpio = AT91_PIN_PC6, + .flags = GPIOF_OPEN_DRAIN | GPIOF_INIT_HIGH, + .label = "eth-switch-enabled", + }, + }, + { + .name = "RADIO_RESET", + .pin = { + .gpio = AT91_PIN_PC5, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "radio-reset", + }, + }, + { + .name = "RADIO_RESET", + .pin = { + .gpio = AT91_PIN_PC5, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "radio-power", + }, + }, + { + .name = "DEVICE_RESET", + .pin = { + .gpio = AT91_PIN_PC4, + .flags = GPIOF_IN, + .label = "reset", + }, + .active_low = 1, + }, + { + .name = "LS_LED", + .pin = { + .gpio = AT91_PIN_PA14, +#if LED_LS_CONTROLLABLE + .flags = GPIOF_OUT_INIT_HIGH, +#else + .flags = GPIOF_IN, +#endif + .label = "led-ls", + }, + .active_low = 1, + }, + { + .name = "STATUS_LED", + .pin = { + .gpio = AT91_PIN_PA24, + .flags = GPIOF_OUT_INIT_LOW, + .label = "led-status", + }, + .active_low = 1, + }, + { + .name = "STATUS_LED", + .pin = { + .gpio = AT91_PIN_PA24, + .flags = GPIOF_OUT_INIT_LOW, + .label = "led-a", + }, + .active_low = 1, + }, + { + .name = "LED7", + .pin = { + .gpio = AT91_PIN_PA25, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-cd", + }, + .active_low = 1, + }, + { + .name = "LED7", + .pin = { + .gpio = AT91_PIN_PA25, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-c", + }, + .active_low = 1, + }, + { + .name = "LED10", + .pin = { + .gpio = AT91_PIN_PA26, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-sig1", + }, + .active_low = 1, + }, + { + .name = "LED10", + .pin = { + .gpio = AT91_PIN_PA26, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-d", + }, + .active_low = 1, + }, + { + .name = "LED11", + .pin = { + .gpio = AT91_PIN_PA27, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-sig2", + }, + .active_low = 1, + }, + { + .name = "LED11", + .pin = { + .gpio = AT91_PIN_PA27, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-e", + }, + .active_low = 1, + }, + { + .name = "LED12", + .pin = { + .gpio = AT91_PIN_PA28, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-sig3", + }, + .active_low = 1, + }, + { + .name = "LED12", + .pin = { + .gpio = AT91_PIN_PA28, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-f", + }, + .active_low = 1, + }, + { + .name = "LED13", + .pin = { + .gpio = AT91_PIN_PA29, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-wifi", + }, + .active_low = 1, + }, + { + .name = "LED13", + .pin = { + .gpio = AT91_PIN_PA29, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "led-b", + }, + .active_low = 1, + }, + { + .name = "UART3_DTR", + .pin = { + .gpio = AT91_PIN_PC12, + .flags = GPIOF_IN, + .label = "extserial-dtr", + }, + .active_low = 1, + }, + { + .name = "UART3_DSR", + .pin = { + .gpio = AT91_PIN_PC11, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "extserial-dsr", + }, + .active_low = 1, + }, + { + .name = "UART3_DCD", + .pin = { + .gpio = AT91_PIN_PC10, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "extserial-dcd", + }, + .active_low = 1, + }, + { + .name = "UART3_RI", + .pin = { + .gpio = AT91_PIN_PC13, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "extserial-ri", + }, + .active_low = 1, + }, + { + .name = "NDC_RESET", + .pin = { + .gpio = AT91_PIN_PC3, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "ndc-reset", + }, + }, + { + .name = "NDC_EEPROM_WRITE_PROTECT", + .pin = { + .gpio = AT91_PIN_PC26, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ndc-eeprom-wp", + }, + }, + { + .name = "BT_EN", + .pin = { + .gpio = AT91_PIN_PD21, + .flags = GPIOF_OUT_INIT_LOW, + .label = "bt-enabled", + }, + }, + { + .name = "WLAN_EN", + .pin = { + .gpio = AT91_PIN_PC1, + .flags = GPIOF_OUT_INIT_LOW, + .label = "wlan-enabled", + }, + }, + { + .name = "SERIAL_MODE0", + .pin = { + .gpio = AT91_PIN_PC23, + .flags = GPIOF_OUT_INIT_LOW, + .label = "serial-mode", + }, + }, + { + .name = "SERIAL_MODE1", + .pin = { + .gpio = AT91_PIN_PC24, + .flags = GPIOF_OUT_INIT_LOW, + .label = "serial-mode", + }, + }, + { + .name = "SERIAL_MODE2", + .pin = { + .gpio = AT91_PIN_PC25, + .flags = GPIOF_OUT_INIT_LOW, + .label = "serial-mode", + }, + }, + { + .name = "RS4XX_TERM_RES", + .pin = { + .gpio = AT91_PIN_PC26, + .flags = GPIOF_OUT_INIT_LOW, + .label = "rs4xx-term-res", + }, + }, + { + .name = "NDC_GPIO1", + .pin = { + .gpio = AT91_PIN_PC0, + .flags = GPIOF_OUT_INIT_LOW, + .label = "dc-gpio1", + }, + }, + { + .name = "NDC_GPIO2", + .pin = { + .gpio = AT91_PIN_PC14, + .flags = GPIOF_OUT_INIT_LOW, + .label = "dc-gpio2", + }, + }, + { + .name = "NDC_GPIO3", + .pin = { + .gpio = AT91_PIN_PC29, + .flags = GPIOF_OUT_INIT_LOW, + .label = "dc-gpio3", + }, + }, + { + .name = "NDC_GPIO4", + .pin = { + .gpio = AT91_PIN_PC30, + .flags = GPIOF_OUT_INIT_LOW, + .label = "dc-gpio4", + }, + }, + { + .name = "NDC_INTERRUPT1", + .pin = { + .gpio = AT91_PIN_PC20, + .flags = GPIOF_IN, + .label = "dc-int1", + }, + }, + { + .name = "NDC_INTERRUPT2", + .pin = { + .gpio = AT91_PIN_PC21, + .flags = GPIOF_IN, + .label = "dc-int2", + }, + }, + { }, +}; + +/* MTOCGD2 specific functions */ +static ssize_t mts_attr_show_serial_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + int smode0; + int smode1; + int smode2; + + struct gpio_pin *pin_smode0 = gpio_pin_by_name("SERIAL_MODE0"); + struct gpio_pin *pin_smode1 = gpio_pin_by_name("SERIAL_MODE1"); + struct gpio_pin *pin_smode2 = gpio_pin_by_name("SERIAL_MODE2"); + + if (!pin_smode0 || !pin_smode1 || !pin_smode2) + return -ENODEV; + + mutex_lock(&mts_io_mutex); + + smode0 = gpio_get_value(pin_smode0->pin.gpio); + smode1 = gpio_get_value(pin_smode1->pin.gpio); + smode2 = gpio_get_value(pin_smode2->pin.gpio); + + if (smode2 == 0 && smode1 == 0 && smode0 == 1) + ret = sprintf(buf, "rs232\n"); + else if (smode2 == 0 && smode1 == 1 && smode0 == 0) + ret = sprintf(buf, "rs485\n"); + else if (smode2 == 1 && smode1 == 0 && smode0 == 0) + ret = sprintf(buf, "rs422\n"); + else if (smode2 == 0 && smode1 == 0 && smode0 == 0) + ret = sprintf(buf, "loopback\n"); + else + ret = sprintf(buf, "error\n"); + + mutex_unlock(&mts_io_mutex); + + return ret; +} + +static ssize_t mts_attr_store_serial_mode(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int smode0; + int smode1; + int smode2; + struct gpio_pin *pin_smode0 = gpio_pin_by_name("SERIAL_MODE0"); + struct gpio_pin *pin_smode1 = gpio_pin_by_name("SERIAL_MODE1"); + struct gpio_pin *pin_smode2 = gpio_pin_by_name("SERIAL_MODE2"); + + if (!pin_smode0 || !pin_smode1 || !pin_smode2) + return -ENODEV; + + if (!strcasecmp(buf, "rs232")) { + smode2 = 0; + smode1 = 0; + smode0 = 1; + } + else if (!strcasecmp(buf, "rs485")) { + smode2 = 0; + smode1 = 1; + smode0 = 0; + } + else if (!strcasecmp(buf, "rs422")) { + smode2 = 1; + smode1 = 0; + smode0 = 0; + } + else if (!strcasecmp(buf, "loopback")) { + smode2 = 0; + smode1 = 0; + smode0 = 0; + } + else { + return -EINVAL; + } + + mutex_lock(&mts_io_mutex); + + gpio_set_value(pin_smode2->pin.gpio, smode2); + gpio_set_value(pin_smode1->pin.gpio, smode1); + gpio_set_value(pin_smode0->pin.gpio, smode0); + + mutex_unlock(&mts_io_mutex); + + return count; +} + +/* MTOCGD2 specific attributes */ +static DEVICE_ATTR_MTS(dev_attr_serial_mode, "serial-mode", + mts_attr_show_serial_mode, mts_attr_store_serial_mode); +static DEVICE_ATTR_MTS(dev_attr_eth_switch_enabled, "eth-switch-enabled", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_rs4xx_term_res, "rs4xx-term-res", + mts_attr_show_gpio_pin, mts_attr_store_gpio_pin); + +static struct attribute *mtr2_platform_attributes[] = { + &dev_attr_vendor_id.attr, + &dev_attr_product_id.attr, + &dev_attr_device_id.attr, + &dev_attr_hw_version.attr, + &dev_attr_imei.attr, + &dev_attr_eth_mac.attr, + &dev_attr_wifi_mac.attr, + &dev_attr_reset.attr, + &dev_attr_reset_monitor.attr, + &dev_attr_radio_power.attr, + &dev_attr_radio_reset.attr, + &dev_attr_ndc_reset.attr, + &dev_attr_extserial_dtr.attr, + &dev_attr_extserial_dsr_gpio.attr, + &dev_attr_extserial_ri_gpio.attr, + &dev_attr_extserial_dcd_gpio.attr, + &dev_attr_eth_switch_enabled.attr, + &dev_attr_bt_enabled.attr, + &dev_attr_wlan_enabled.attr, + + &dev_attr_serial_mode.attr, + &dev_attr_rs4xx_term_res.attr, + + &dev_attr_led_status.attr, + &dev_attr_led_wifi_gpio.attr, + &dev_attr_led_cd_gpio.attr, + &dev_attr_led_sig1_gpio.attr, + &dev_attr_led_sig2_gpio.attr, + &dev_attr_led_sig3_gpio.attr, + + &dev_attr_led_a_gpio.attr, + &dev_attr_led_b_gpio.attr, + &dev_attr_led_c_gpio.attr, + &dev_attr_led_d_gpio.attr, + &dev_attr_led_e_gpio.attr, + &dev_attr_led_f_gpio.attr, + + &dev_attr_board_temperature.attr, + + /* extra space for the daughter card attributes */ + NULL, // index 34 + NULL, // index 35 + NULL, // index 36 + NULL, // index 37 + NULL, // index 38 + NULL, // index 39 + NULL, // index 40 + NULL, // index 41 + NULL, // index 42 + NULL, // index 43 + NULL, // index 44 + NULL, // index 45 + NULL, // index 46 + NULL, // index 47 + NULL, // index 48 + NULL, // index 49 + NULL, // index 50 + NULL, // index 51 + NULL, +}; + +static struct attribute *mtr2_daughter_card_attributes[] = { + &dev_attr_dc_din0.attr, + &dev_attr_dc_din1.attr, + &dev_attr_dc_din2.attr, + &dev_attr_dc_din3.attr, + + &dev_attr_dc_dout0.attr, + &dev_attr_dc_dout1.attr, + &dev_attr_dc_dout2.attr, + &dev_attr_dc_dout3.attr, + + &dev_attr_dc_adc0.attr, + &dev_attr_dc_adc1.attr, + &dev_attr_dc_adc2.attr, + + &dev_attr_dc_led1.attr, + &dev_attr_dc_led2.attr, + &dev_attr_dc_oe.attr, + + NULL, +}; + +static bool mtr2_add_daughter_card_attributes(void) +{ + size_t platform_attrs_size = sizeof(mtr2_platform_attributes) / sizeof(struct attribute *); + size_t daughter_card_attrs_size = sizeof(mtr2_daughter_card_attributes) / sizeof(struct attribute *); + size_t platform_attrs_index; + size_t daughter_card_attrs_index; + size_t copy_length = daughter_card_attrs_size - 1; /* don't need to copy the NULL at the end */ + + for (platform_attrs_index = 0; platform_attrs_index < platform_attrs_size; platform_attrs_index++) { + if (! mtr2_platform_attributes[platform_attrs_index]) { + break; + } + } + + if (platform_attrs_size < platform_attrs_index + daughter_card_attrs_size) { + log_error("not enough room for MTR2 daughter card attributes!"); + return false; + } + + for (daughter_card_attrs_index = 0; daughter_card_attrs_index < copy_length; daughter_card_attrs_index++, platform_attrs_index++) { + mtr2_platform_attributes[platform_attrs_index] = mtr2_daughter_card_attributes[daughter_card_attrs_index]; + } + + return true; +} + +static struct attribute_group mtr2_platform_attribute_group = { + .attrs = mtr2_platform_attributes +}; diff --git a/io-module/mts_io.c b/io-module/mts_io.c index 79351fa..1f641d9 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -1,7 +1,7 @@ /* * MTS-IO Controller * - * Copyright (C) 2013 by Multi-Tech Systems + * Copyright (C) 2014 by Multi-Tech Systems * * Authors: James Maki * Jesse Gilles @@ -44,46 +44,14 @@ #include "mts_io.h" -#define DRIVER_VERSION "v0.8.2" +#define DRIVER_VERSION "v0.9.1" #define DRIVER_AUTHOR "James Maki " #define DRIVER_DESC "MTS-IO Controller" #define DRIVER_NAME "mts-io" #define PLATFORM_NAME "mts-io" -#define DEBUG 0 - -#define __log(level, name, format, args...) \ - printk(level "[" name "] " DRIVER_NAME ":%s:%d: " format "\n" , \ - __func__ , __LINE__ , ## args) - -#define log_emerg(format, args...) __log(KERN_EMERG, "EMERG", format , ## args) -#define log_alert(format, args...) __log(KERN_ALERT, "ALERT", format , ## args) -#define log_crit(format, args...) __log(KERN_CRIT, "CRIT", format , ## args) -#define log_error(format, args...) __log(KERN_ERR, "ERROR", format , ## args) -#define log_warning(format, args...) __log(KERN_WARNING, "WARNING", format , ## args) -#define log_notice(format, args...) __log(KERN_NOTICE, "NOTICE", format , ## args) -#define log_info(format, args...) __log(KERN_INFO, "INFO", format , ## args) -#if DEBUG -# define log_debug(format, args...) __log(KERN_DEBUG, "DEBUG", format , ## args) -#else -# define log_debug(format, args...) do {} while (0) -#endif - -#define LED_STATUS_CONTROLLABLE_MTCDP 0 #define LED_LS_CONTROLLABLE 0 -#define USBH2_PS_CONTROLLABLE 0 - -static int led_mode_status = LED_OFF; - -#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) #define AT91SAM9X5_BASE_ADC 0xf804c000 @@ -109,1253 +77,44 @@ static uint8_t has_spi_din; static uint8_t has_spi_dout; static uint8_t has_spi_temp; +static struct platform_device *mts_io_platform_device; static struct attribute_group *attr_group; - static struct gpio_pin *gpio_pins; -/* -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, - }, -#if LED_STATUS_CONTROLLABLE_MTCDP - { - .name = "STATUS_LED", - .attr_name = "led-status", - .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, - }, -#if LED_STATUS_CONTROLLABLE_MTCDP - { - .name = "STATUS_LED", - .attr_name = "led-status", - .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 = "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, - }, - { }, -}; - -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, - }, - { }, -}; -*/ - -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 = "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", - }, - }, - { }, -}; - -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 = "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", - }, - }, - { }, -}; - -struct gpio_pin *gpio_pin_by_name(const char *name) { - struct gpio_pin *pin; - - for (pin = gpio_pins; *pin->name; pin++) { - if (!strcmp(pin->name, name)) { - return pin; - } - } - - log_error("pin named %s not found", name); - - return NULL; -} - -struct gpio_pin *gpio_pin_by_attr_name(const char *name) { - struct gpio_pin *pin; - - for (pin = gpio_pins; *pin->name; pin++) { - if (!strcmp(pin->pin.label, name)) { - return pin; - } - } - - log_error("pin with attr name %s not found", name); - - return NULL; -} - - -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)" -); - -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 DEFINE_MUTEX(mts_io_mutex); -static inline int spi_readn(struct spi_device *spi, u8 *buf, size_t len) -{ - int tmp; - u8 *rx; +/* generic GPIO support */ +#include "gpio.c" - rx = kmalloc(len, GFP_KERNEL); - if (!rx) { - return -ENOMEM; - } +/* AT91 built-in ADC */ +#include "adc.c" - tmp = spi_read(spi, rx, len); - memcpy(buf, rx, len); +/* SPI-based stuff */ +#include "spi.c" - kfree(rx); +/* accessory card support */ +#include "mtdc_gpiob.c" - return tmp; -} +/* telit radio reset handling */ +#include "telit_radio.c" -#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) - -#define BLINK_PER_SEC 8 -#define BLINK_INTERVAL (HZ / BLINK_PER_SEC) -#define RESET_HOLD_COUNT (BLINK_PER_SEC * 3) -#define RESET_LONG_HOLD_COUNT (BLINK_PER_SEC * 30) +/* reset button handling */ +#define RESET_CHECK_PER_SEC 8 +#define RESET_INTERVAL (HZ / RESET_CHECK_PER_SEC) +#define RESET_HOLD_COUNT (RESET_CHECK_PER_SEC * 3) +#define RESET_LONG_HOLD_COUNT (RESET_CHECK_PER_SEC * 30) static pid_t reset_pid = -1; static pid_t reset_count = 0; static int reset_short_signal = SIGUSR1; static int reset_long_signal = SIGUSR2; static int reset_extra_long_signal = SIGHUP; -static DEFINE_MUTEX(mts_io_mutex); -static void blink_callback(struct work_struct *ignored); +static void reset_callback(struct work_struct *ignored); -static DECLARE_DELAYED_WORK(blink_work, blink_callback); +static DECLARE_DELAYED_WORK(reset_work, reset_callback); -static void blink_callback(struct work_struct *ignored) +static void reset_callback(struct work_struct *ignored) { struct gpio_pin *pin; int reset_pressed = 0; @@ -1394,205 +153,66 @@ static void blink_callback(struct work_struct *ignored) reset_count = 0; } - if (led_mode_status == LED_FLASHING) { - pin = gpio_pin_by_name("STATUS_LED"); - if (pin) { - gpio_set_value(pin->pin.gpio, !gpio_get_value(pin->pin.gpio)); - } - } - mutex_unlock(&mts_io_mutex); - schedule_delayed_work(&blink_work, BLINK_INTERVAL); + schedule_delayed_work(&reset_work, RESET_INTERVAL); } -static int radio_off_telit(void) +static ssize_t mts_attr_show_reset_monitor(struct device *dev, + struct device_attribute *attr, + char *buf) { - 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); + int ret; - // check that power is low - value = gpio_get_val