diff options
-rw-r--r-- | io-module/eeprom/eeprom.bin | bin | 0 -> 512 bytes | |||
-rw-r--r-- | io-module/mts_io.c | 1726 |
2 files changed, 1066 insertions, 660 deletions
diff --git a/io-module/eeprom/eeprom.bin b/io-module/eeprom/eeprom.bin Binary files differnew file mode 100644 index 0000000..985f368 --- /dev/null +++ b/io-module/eeprom/eeprom.bin diff --git a/io-module/mts_io.c b/io-module/mts_io.c index bc5db24..d95eed5 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -36,25 +36,36 @@ #include <linux/device.h> #include <linux/bitops.h> #include <linux/spi/spi.h> +#include <linux/i2c/at24.h> +#include <linux/kmod.h> #include "mts_io.h" -#define DRIVER_VERSION "v0.2.0" +#define DRIVER_VERSION "v0.4.0" #define DRIVER_AUTHOR "James Maki <jmaki@multitech.com>" #define DRIVER_DESC "MTCDP IO Controller" #define DRIVER_NAME "mts-io" #define PLATFORM_NAME "mtcdp" -#define DEBUG 0 +#define DEBUG 1 +#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 dbg(fmt, args...) printk(KERN_DEBUG DRIVER_NAME ": " fmt "\n" , ##args) +# define log_debug(format, args...) __log(KERN_DEBUG, "DEBUG", format , ## args) #else -# define dbg(fmt, args...) do {} while (0) +# define log_debug(format, args...) do {} while (0) #endif -#define error(fmt, args...) printk(KERN_ERR DRIVER_NAME ": " fmt "\n" , ##args) -#define info(fmt, args...) printk(KERN_INFO DRIVER_NAME ": " fmt "\n" , ##args) enum { LED_OFF, @@ -62,41 +73,6 @@ enum { LED_FLASHING, }; -#define BOARD_REVA 0 -#define BOARD_REVB 1 -#define BOARD_REVC 2 - -static u8 board_rev = BOARD_REVA; - -#define LED_CD_BIT BIT(0) -#define EXTSERIAL_RI_BIT BIT(1) -#define EXTSERIAL_DSR_BIT BIT(2) -#define CS0_BIT3 BIT(3) -#define LED_SIG1_BIT BIT(4) -#define LED_SIG2_BIT BIT(5) -#define LED_SIG3_BIT BIT(6) -#define EXTSERIAL_DCD_BIT BIT(7) - -#define GPIO_VER0 AT91_PIN_PA23 -#define GPIO_VER1 AT91_PIN_PA24 -#define GPIO_STATUS_LED AT91_PIN_PA30 -#define GPIO_LS_LED AT91_PIN_PC9 -#define GPIO_ENIO AT91_PIN_PC15 -#define GPIO_ETH0_ENABLED AT91_PIN_PB31 -#define GPIO_RADIO_RESET AT91_PIN_PB30 -#define GPIO_OPTRST AT91_PIN_PA22 -#define GPIO_RSERSRC AT91_PIN_PC7 -#define GPIO_DBSERON AT91_PIN_PC6 -#define GPIO_DTR1 AT91_PIN_PC10 -#define GPIO_RXD1MON AT91_PIN_PC8 -#define GPIO_EXTIN0 AT91_PIN_PB13 -#define GPIO_EXTIN1 AT91_PIN_PB12 -#define GPIO_EXTIN2 AT91_PIN_PB11 -#define GPIO_EXTIN3 AT91_PIN_PB10 -#define GPIO_EXTIN4 AT91_PIN_PB9 -#define GPIO_EXTIN5 AT91_PIN_PB8 -#define GPIO_GPS_NINT2 AT91_PIN_PC2 - #define LED_STATUS_CONTROLLABLE 0 #define LED_LS_CONTROLLABLE 0 @@ -104,28 +80,332 @@ static u8 board_rev = BOARD_REVA; static int led_mode_status = LED_OFF; #endif -static struct spi_device *spi_sregout; -static u8 spi_sregout_byte; -static DEFINE_MUTEX(spi_sregout_mutex); +#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) + +enum { + GPIO_DIR_INPUT, + GPIO_DIR_OUTPUT, +}; + +struct gpio_pin { + char name[32]; + unsigned pin; + int direction; + int output_value; + int use_pullup; +}; -static struct spi_device *spi_temp; +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", + .pin = AT91_PIN_PB31, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "RADIO_RESET", + .pin = AT91_PIN_PB30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "DEVICE_RESET", + .pin = AT91_PIN_PA22, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, +#if LED_LS_CONTROLLABLE + { + .name = "LS_LED", + .pin = AT91_PIN_PC9, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, +#endif +#if LED_STATUS_CONTROLLABLE + { + .name = "STATUS_LED", + .pin = AT91_PIN_PA30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, +#endif + { + .name = "RSERSRC", + .pin = AT91_PIN_PC7, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "DTR1", + .pin = AT91_PIN_PC10, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { }, +}; -static int spi_sregout_write(struct spi_device *spi, const u8 value) +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", + .pin = AT91_PIN_PB31, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "RADIO_RESET", + .pin = AT91_PIN_PB30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "DEVICE_RESET", + .pin = AT91_PIN_PA22, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, +#if LED_LS_CONTROLLABLE + { + .name = "LS_LED", + .pin = AT91_PIN_PC9, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, +#endif +#if LED_STATUS_CONTROLLABLE + { + .name = "STATUS_LED", + .pin = AT91_PIN_PA30, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, +#endif + { + .name = "RSERSRC", + .pin = AT91_PIN_PC7, + .direction = GPIO_DIR_OUTPUT, + .output_value = 1, + .use_pullup = 0, + }, + { + .name = "TXD1", + .pin = AT91_PIN_PB17, + .direction = GPIO_DIR_OUTPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "DTR1", + .pin = AT91_PIN_PB18, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "DC_NINT1", + .pin = AT91_PIN_PB8, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { + .name = "DC_NINT2", + .pin = AT91_PIN_PB9, + .direction = GPIO_DIR_INPUT, + .output_value = 0, + .use_pullup = 0, + }, + { }, +}; + +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; +} + +static uint8_t __capa_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 +}; + +#define DEVICE_CAPA_INDEX(c) ((c) >> 3) +#define DEVICE_CAPA_MASK(c) __capa_mask[(c) & 0x07] + +#define DEVICE_CAPA(capa_buf, c) ((capa_buf)[DEVICE_CAPA_INDEX(c)] & DEVICE_CAPA_MASK(c)) +#define DEVICE_CAPA_SET(capa_buf, c) \ +do { \ + (capa_buf)[DEVICE_CAPA_INDEX(c)] |= DEVICE_CAPA_MASK(c); \ +}while (0) +#define DEVICE_CAPA_CLEAR(capa_buf, c) \ +do { \ + (capa_buf)[DEVICE_CAPA_INDEX(c)] &= ~DEVICE_CAPA_MASK(c); \ +} while (0) + +struct mts_id_eeprom_overlay { + char vendor_id[32]; + char product_id[32]; + char device_id[32]; + char hw_version[32]; + uint8_t capa[32]; + uint8_t reserved[352]; +}; + +extern uint8_t mts_id_eeprom[512]; +struct mts_id_eeprom_overlay *id_eeprom = + (struct mts_id_eeprom_overlay *) mts_id_eeprom; + +#define HWV_MTCDP_0_0 "MTCDP-0.0" +#define HWV_MTCDP_1_0 "MTCDP-1.0" + +static int mts_id_eeprom_load(void) { - return spi_write(spi, &value, 1); + if (id_eeprom->vendor_id[0] == 0xFF) { + log_error("uninitialized eeprom"); + return -EIO; + } else if (id_eeprom->vendor_id[0] == 0x00) { + log_debug("MTCDP-0.0 hardware found"); + strcpy(id_eeprom->hw_version, HWV_MTCDP_0_0); + gpio_pins = gpio_pins_mtcdp_0_0; + } else { + gpio_pins = gpio_pins_mtcdp_1_0; + } + + log_info("vendor_id: %.32s", id_eeprom->vendor_id); + log_info("product_id: %.32s", id_eeprom->product_id); + log_info("device_id: %.32s", id_eeprom->device_id); + log_info("hw_version: %.32s", id_eeprom->hw_version); + log_info("capa: %02X", id_eeprom->capa[0]); + + return 0; } -static int spi_temp_read(struct spi_device *spi, u16 *value) +static struct spi_device *spi_sout_dev; +static u8 spi_sout_value; +static DEFINE_MUTEX(spi_sout_mutex); + +static struct spi_device *spi_dout_dev; +static u8 spi_dout_value; +static DEFINE_MUTEX(spi_dout_mutex); + +static struct spi_device *spi_din_dev; + +static struct spi_device *spi_board_temp_dev; + +static inline int spi_writen(struct spi_device *spi, const u8 *buf, size_t len) { int tmp; - u8 buf[2] = {0, 0}; + u8 *tx; + + tx = kmalloc(len, GFP_KERNEL); + if (!tx) { + return -ENOMEM; + } + + memcpy(tx, buf, len); + tmp = spi_write(spi, tx, len); - tmp = spi_read(spi, buf, 2); - *value = buf[0] << 8 | buf[1]; + 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; +} + +#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) @@ -142,11 +422,15 @@ static DECLARE_DELAYED_WORK(blink_work, blink_callback); static void blink_callback(struct work_struct *ignored) { - unsigned long reset_pressed = !at91_get_gpio_value(GPIO_OPTRST); + struct gpio_pin *pin; + int reset_pressed; struct pid *vpid = NULL; mutex_lock(&mts_io_mutex); + pin = gpio_pin_by_name("DEVICE_RESET"); + reset_pressed = !at91_get_gpio_value(pin->pin); + if (reset_pid > 0) { vpid = find_vpid(reset_pid); } @@ -169,7 +453,8 @@ static void blink_callback(struct work_struct *ignored) #if LED_STATUS_CONTROLLABLE if (led_mode_status == LED_FLASHING) { - at91_set_gpio_value(GPIO_STATUS_LED, !at91_get_gpio_value(GPIO_STATUS_LED)); + pin = gpio_pin_by_name("STATUS_LED"); + at91_set_gpio_value(pin->pin, !at91_get_gpio_value(pin->pin)); } #endif @@ -181,15 +466,16 @@ static void blink_callback(struct work_struct *ignored) static int radio_reset(void) { int ret; + struct gpio_pin *pin = gpio_pin_by_name("RADIO_RESET"); - ret = at91_set_gpio_value(GPIO_RADIO_RESET, 0); + ret = at91_set_gpio_value(pin->pin, 0); if (ret) { return ret; } mdelay(250); - ret = at91_set_gpio_value(GPIO_RADIO_RESET, 1); + ret = at91_set_gpio_value(pin->pin, 1); return ret; } @@ -205,15 +491,34 @@ static int ADT7302_to_celsius(int value) return value; } -static ssize_t show_radio_reset(struct device *dev, + +#define MTS_ATTR_MODE_RW S_IWUSR | S_IRUGO +#define MTS_ATTR_MODE_RO S_IRUGO + +#define MTS_ATTR_NAME(name) mts_attr_##name +#define MTS_ATTR_SHOW(name) mts_attr_show_##name +#define MTS_ATTR_STORE(name) mts_attr_store_##name + +#define MTS_ATTR(name, attr_name, attr_mode, show, store) \ +static struct device_attribute MTS_ATTR_NAME(name) = \ + .attr = { \ + .name = attr_name, \ + .mode = attr_mode, \ + }, \ + .show = show, \ + .store = store, \ +} + +static ssize_t mts_attr_show_radio_reset(struct device *dev, struct device_attribute *attr, char *buf) { int value; + struct gpio_pin *pin = gpio_pin_by_name("RADIO_RESET"); mutex_lock(&mts_io_mutex); - value = at91_get_gpio_value(GPIO_RADIO_RESET); + value = at91_get_gpio_value(pin->pin); mutex_unlock(&mts_io_mutex); @@ -224,8 +529,8 @@ static ssize_t show_radio_reset(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t store_radio_reset(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t mts_attr_store_radio_reset(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { int value; int err; @@ -253,21 +558,22 @@ static ssize_t store_radio_reset(struct device *dev, struct device_attribute *at static struct device_attribute dev_attr_radio_reset = { .attr = { .name = "radio-reset", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_radio_reset, - .store = store_radio_reset, + .show = mts_attr_show_radio_reset, + .store = mts_attr_store_radio_reset, }; -static ssize_t show_eth0_enabled(struct device *dev, +static ssize_t mts_attr_show_eth0_enabled(struct device *dev, struct device_attribute *attr, char *buf) { int value; + struct gpio_pin *pin = gpio_pin_by_name("ETH0_ENABLED"); mutex_lock(&mts_io_mutex); - value = at91_get_gpio_value(GPIO_ETH0_ENABLED); + value = at91_get_gpio_value(pin->pin); mutex_unlock(&mts_io_mutex); @@ -278,11 +584,12 @@ static ssize_t show_eth0_enabled(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t store_eth0_enabled(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t mts_attr_store_eth0_enabled(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { int value; int err; + struct gpio_pin *pin = gpio_pin_by_name("ETH0_ENABLED"); if (sscanf(buf, "%i", &value) != 1) { return -EINVAL; @@ -290,7 +597,7 @@ static ssize_t store_eth0_enabled(struct device *dev, struct device_attribute *a mutex_lock(&mts_io_mutex); - err = at91_set_gpio_value(GPIO_ETH0_ENABLED, value); + err = at91_set_gpio_value(pin->pin, value); mutex_unlock(&mts_io_mutex); @@ -304,487 +611,540 @@ static ssize_t store_eth0_enabled(struct device *dev, struct device_attribute *a static struct device_attribute dev_attr_eth0_enabled = { .attr = { .name = "eth0-enabled", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_eth0_enabled, - .store = store_eth0_enabled, + .show = mts_attr_show_eth0_enabled, + .store = mts_attr_store_eth0_enabled, }; -static ssize_t show_extserial_dcd(struct device *dev, - struct device_attribute *attr, - char *buf) + +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_sregout) { - error("device not present"); + if (!spi_sout_dev) { + log_notice("sout device not present"); return -ENODEV; } - mutex_lock(&spi_sregout_mutex); - - value = spi_sregout_byte & EXTSERIAL_DCD_BIT ? 0 : 1; - - mutex_unlock(&spi_sregout_mutex); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t store_extserial_dcd(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int value; - - if (!spi_sregout) { - error("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 exists"); + return -ENOENT; } if (sscanf(buf, "%i", &value) != 1) { + log_notice("sout attr invalid argument"); return -EINVAL; } - mutex_lock(&spi_sregout_mutex); + mutex_lock(&spi_sout_mutex); if (value) { - spi_sregout_byte &= ~EXTSERIAL_DCD_BIT; + spi_sout_value &= ~bit; } else { - spi_sregout_byte |= EXTSERIAL_DCD_BIT; + spi_sout_value |= bit; } - spi_sregout_write(spi_sregout, spi_sregout_byte); + spi_writen(spi_sout_dev, &spi_sout_value, 1); - mutex_unlock(&spi_sregout_mutex); + mutex_unlock(&spi_sout_mutex); return count; } -static struct device_attribute dev_attr_extserial_dcd = { - .attr = { - .name = "extserial-dcd", - .mode = 0644, - }, - .show = show_extserial_dcd, - .store = store_extserial_dcd, -}; - -static ssize_t show_extserial_ri(struct device *dev, +static ssize_t mts_attr_show_sout(struct device *dev, struct device_attribute *attr, char *buf) { int value; + u8 bit; - if (!spi_sregout) { - error("device not present"); + if (!spi_sout_dev) { + log_error("sout device not present"); return -ENODEV; } - mutex_lock(&spi_sregout_mutex); - - value = spi_sregout_byte & EXTSERIAL_RI_BIT ? 0 : 1; - - mutex_unlock(&spi_sregout_mutex); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t store_extserial_ri(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int value; - - if (!spi_sregout) { - error("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 exists"); + return -ENOENT; } - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } + mutex_lock(&spi_sout_mutex); - mutex_lock(&spi_sregout_mutex); + value = spi_sout_value & bit ? 0 : 1; - if (value) { - spi_sregout_byte &= ~EXTSERIAL_RI_BIT; - } else { - spi_sregout_byte |= EXTSERIAL_RI_BIT; - } - spi_sregout_write(spi_sregout, spi_sregout_byte); - - mutex_unlock(&spi_sregout_mutex); + mutex_unlock(&spi_sout_mutex); - return count; + return sprintf(buf, "%d\n", value); } +static struct device_attribute dev_attr_extserial_dcd = { + .attr = { + .name = "extserial-dcd", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; + static struct device_attribute dev_attr_extserial_ri = { .attr = { .name = "extserial-ri", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_extserial_ri, - .store = store_extserial_ri, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, }; -static ssize_t show_extserial_dsr(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int value; - - if (!spi_sregout) { - error("device not present"); - return -ENODEV; - } - - mutex_lock(&spi_sregout_mutex); - - value = spi_sregout_byte & EXTSERIAL_DSR_BIT ? 0 : 1; - - mutex_unlock(&spi_sregout_mutex); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t store_extserial_dsr(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int value; - - if (!spi_sregout) { - error("device not present"); - return -ENODEV; - } - - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } - - mutex_lock(&spi_sregout_mutex); - - if (value) { - spi_sregout_byte &= ~EXTSERIAL_DSR_BIT; - } else { - spi_sregout_byte |= EXTSERIAL_DSR_BIT; - } - spi_sregout_write(spi_sregout, spi_sregout_byte); - - mutex_unlock(&spi_sregout_mutex); - - return count; -} - static struct device_attribute dev_attr_extserial_dsr = { .attr = { .name = "extserial-dsr", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_extserial_dsr, - .store = store_extserial_dsr, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, }; -static ssize_t show_extserial_dtr(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int value; - - mutex_lock(&mts_io_mutex); - - value = !at91_get_gpio_value(GPIO_DTR1); - - mutex_unlock(&mts_io_mutex); +static struct device_attribute dev_attr_led_cd = { + .attr = { + .name = "led-cd", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; - if (value < 0) { - return value; - } +static struct device_attribute dev_attr_led_sdk_b = { + .attr = { + .name = "led-sdk-b", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; - return sprintf(buf, "%d\n", value); -} +static struct device_attribute dev_attr_led_sig1 = { + .attr = { + .name = "led-sig1", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; -static struct device_attribute dev_attr_extserial_dtr = { +static struct device_attribute dev_attr_led_sdk_c = { .attr = { - .name = "extserial-dtr", - .mode = 0444, + .name = "led-sdk-c", + .mode = MTS_ATTR_MODE_RW, }, - .show = show_extserial_dtr, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, }; -static ssize_t show_led_sig1(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int value; +static struct device_attribute dev_attr_led_sig2 = { + .attr = { + .name = "led-sig2", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; - if (!spi_sregout) { - error("device not present"); - return -ENODEV; - } +static struct device_attribute dev_attr_led_sdk_d = { + .attr = { + .name = "led-sdk-d", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; - mutex_lock(&spi_sregout_mutex); +static struct device_attribute dev_attr_led_sig3 = { + .attr = { + .name = "led-sig3", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; - value = spi_sregout_byte & LED_SIG1_BIT ? 0 : 1; +static struct device_attribute dev_attr_led_sdk_e = { + .attr = { + .name = "led-sdk-e", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; - mutex_unlock(&spi_sregout_mutex); +static struct device_attribute dev_attr_led_dtr = { + .attr = { + .name = "led-dtr", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; - return sprintf(buf, "%d\n", value); -} +static struct device_attribute dev_attr_led_sdk_f = { + .attr = { + .name = "led-sdk-f", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_sout, + .store = mts_attr_store_sout, +}; -static ssize_t store_led_sig1(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +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_sregout) { - error("device not present"); + if (!spi_dout_dev) { + log_notice("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 if (!strcmp(attr->attr.name, "dout4")) { + bit = BIT(4); + } else if (!strcmp(attr->attr.name, "dout5")) { + bit = BIT(5); + } else if (!strcmp(attr->attr.name, "dout6")) { + bit = BIT(6); + } else if (!strcmp(attr->attr.name, "dout7")) { + bit = BIT(7); + } else { + log_notice("dout attr does not exists"); + return -ENOENT; + } + if (sscanf(buf, "%i", &value) != 1) { + log_notice("dout attr invalid argument"); return -EINVAL; } - mutex_lock(&spi_sregout_mutex); + mutex_lock(&spi_dout_mutex); if (value) { - spi_sregout_byte &= ~LED_SIG1_BIT; + spi_dout_value |= bit; } else { - spi_sregout_byte |= LED_SIG1_BIT; + spi_dout_value &= ~bit; } - spi_sregout_write(spi_sregout, spi_sregout_byte); + spi_writen(spi_dout_dev, &spi_dout_value, 1); - mutex_unlock(&spi_sregout_mutex); + mutex_unlock(&spi_dout_mutex); return count; } -static struct device_attribute dev_attr_led_sig1 = { - .attr = { - .name = "led-sig1", - .mode = 0644, - }, - .show = show_led_sig1, - .store = store_led_sig1, -}; - -static struct device_attribute dev_attr_led_sdk_c = { - .attr = { - .name = "led-sdk-c", - .mode = 0644, - }, - .show = show_led_sig1, - .store = store_led_sig1, -}; - -static ssize_t show_led_sig2(struct device *dev, +static ssize_t mts_attr_show_dout(struct device *dev, struct device_attribute *attr, char *buf) { int value; + u8 bit; - if (!spi_sregout) { - error("device not present"); + if (!spi_dout_dev) { + log_error("dout device not present"); return -ENODEV; } - mutex_lock(&spi_sregout_mutex); + 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 if (!strcmp(attr->attr.name, "dout4")) { + bit = BIT(4); + } else if (!strcmp(attr->attr.name, "dout5")) { + bit = BIT(5); + } else if (!strcmp(attr->attr.name, "dout6")) { + bit = BIT(6); + } else if (!strcmp(attr->attr.name, "dout7")) { + bit = BIT(7); + } else { + log_notice("dout attr does not exists"); + return -ENOENT; + } - value = spi_sregout_byte & LED_SIG2_BIT ? 0 : 1; + mutex_lock(&spi_dout_mutex); - mutex_unlock(&spi_sregout_mutex); + value = spi_dout_value & bit ? 1 : 0; + + mutex_unlock(&spi_dout_mutex); return sprintf(buf, "%d\n", value); } -static ssize_t store_led_sig2(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int value; - - if (!spi_sregout) { - error("device not present"); - return -ENODEV; - } +static struct device_attribute dev_attr_dout0 = { + .attr = { + .name = "dout0", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, +}; - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } +static struct device_attribute dev_attr_dout1 = { + .attr = { + .name = "dout1", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, +}; - mutex_lock(&spi_sregout_mutex); +static struct device_attribute dev_attr_dout2 = { + .attr = { + .name = "dout2", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, +}; - if (value) { - spi_sregout_byte &= ~LED_SIG2_BIT; - } else { - spi_sregout_byte |= LED_SIG2_BIT; - } - spi_sregout_write(spi_sregout, spi_sregout_byte); +static struct device_attribute dev_attr_dout3 = { + .attr = { + .name = "dout3", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, +}; - mutex_unlock(&spi_sregout_mutex); +static struct device_attribute dev_attr_dout4 = { + .attr = { + .name = "dout4", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, +}; - return count; -} +static struct device_attribute dev_attr_dout5 = { + .attr = { + .name = "dout5", + .mode = MTS_ATTR_MODE_RW, + }, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, +}; -static struct device_attribute dev_attr_led_sig2 = { +static struct device_attribute dev_attr_dout6 = { .attr = { - .name = "led-sig2", - .mode = 0644, + .name = "dout6", + .mode = MTS_ATTR_MODE_RW, }, - .show = show_led_sig2, - .store = store_led_sig2, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, }; -static struct device_attribute dev_attr_led_sdk_d = { +static struct device_attribute dev_attr_dout7 = { .attr = { - .name = "led-sdk-d", - .mode = 0644, + .name = "dout7", + .mode = MTS_ATTR_MODE_RW, }, - .show = show_led_sig2, - .store = store_led_sig2, + .show = mts_attr_show_dout, + .store = mts_attr_store_dout, }; -static ssize_t show_led_sig3(struct device *dev, +static ssize_t mts_attr_show_din(struct device *dev, struct device_attribute *attr, char *buf) { - int value; - - if (!spi_sregout) { - error("device not present"); - return -ENODEV; - } - - mutex_lock(&spi_sregout_mutex); - - value = spi_sregout_byte & LED_SIG3_BIT ? 0 : 1; - - mutex_unlock(&spi_sregout_mutex); - - return sprintf(buf, "%d\n", value); -} - -static ssize_t store_led_sig3(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int value; + int tmp; + u8 bit; + u8 byte; - if (!spi_sregout) { - error("device not present"); + if (!spi_din_dev) { + log_error("din device not present"); return -ENODEV; } - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; + 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 if (!strcmp(attr->attr.name, "din4")) { + bit = BIT(4); + } else if (!strcmp(attr->attr.name, "din5")) { + 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 exists"); + return -ENOENT; } - mutex_lock(&spi_sregout_mutex); - - if (value) { - spi_sregout_byte &= ~LED_SIG3_BIT; - } else { - spi_sregout_byte |= LED_SIG3_BIT; + tmp = spi_readn(spi_din_dev, &byte, 1); + if (tmp) { + log_error("spi_read failed %d", tmp); + return tmp; } - spi_sregout_write(spi_sregout, spi_sregout_byte); - mutex_unlock(&spi_sregout_mutex); + tmp = byte & bit ? 1 : 0; - return count; + return sprintf(buf, "%d\n", tmp); } -static struct device_attribute dev_attr_led_sig3 = { +static struct device_attribute dev_attr_din0 = { .attr = { - .name = "led-sig3", - .mode = 0644, + .name = "din0", + .mode = MTS_ATTR_MODE_RO, }, - .show = show_led_sig3, - .store = store_led_sig3, + .show = mts_attr_show_din, }; -static struct device_attribute dev_attr_led_sdk_e = { +static struct device_attribute dev_attr_din1 = { .attr = { - .name = "led-sdk-e", - .mode = 0644, + .name = "din1", + .mode = MTS_ATTR_MODE_RO, }, - .show = show_led_sig3, - .store = store_led_sig3, + .show = mts_attr_show_din, }; -static ssize_t show_led_cd(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int value; +static struct device_attribute dev_attr_din2 = { + .attr = { + .name = "din2", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_din, +}; - if (!spi_sregout) { - error("device not present"); - return -ENODEV; - } +static struct device_attribute dev_attr_din3 = { + .attr = { + .name = "din3", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_din, +}; - mutex_lock(&spi_sregout_mutex); +static struct device_attribute dev_attr_din4 = { + .attr = { + .name = "din4", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_din, +}; - value = spi_sregout_byte & LED_CD_BIT ? 0 : 1; +static struct device_attribute dev_attr_din5 = { + .attr = { + .name = "din5", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_din, +}; - mutex_unlock(&spi_sregout_mutex); +static struct device_attribute dev_attr_din6 = { + .attr = { + .name = "din6", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_din, +}; + +static struct device_attribute dev_attr_din7 = { + .attr = { + .name = "din7", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_din, +}; - return sprintf(buf, "%d\n", value); -} -static ssize_t store_led_cd(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t mts_attr_show_extserial_dtr(struct device *dev, + struct device_attribute *attr, + char *buf) { int value; + struct gpio_pin *pin = gpio_pin_by_name("DTR1"); - if (!spi_sregout) { - error("device not present"); - return -ENODEV; - } + mutex_lock(&mts_io_mutex); - if (sscanf(buf, "%i", &value) != 1) { - return -EINVAL; - } + value = !at91_get_gpio_value(pin->pin); - mutex_lock(&spi_sregout_mutex); + mutex_unlock(&mts_io_mutex); - if (value) { - spi_sregout_byte &= ~LED_CD_BIT; - } else { - spi_sregout_byte |= LED_CD_BIT; + if (value < 0) { + return value; } - spi_sregout_write(spi_sregout, spi_sregout_byte); - - mutex_unlock(&spi_sregout_mutex); - return count; + return sprintf(buf, "%d\n", value); } -static struct device_attribute dev_attr_led_cd = { - .attr = { - .name = "led-cd", - .mode = 0644, - }, - .show = show_led_cd, - .store = store_led_cd, -}; - -static struct device_attribute dev_attr_led_sdk_b = { +static struct device_attribute dev_attr_extserial_dtr = { .attr = { - .name = "led-sdk-b", - .mode = 0644, + .name = "extserial-dtr", + .mode = MTS_ATTR_MODE_RO, }, - .show = show_led_cd, - .store = store_led_cd, + .show = mts_attr_show_extserial_dtr, }; #if LED_STATUS_CONTROLLABLE -static ssize_t show_led_status(struct device *dev, +static ssize_t mts_attr_show_led_status(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%d\n", led_mode_status); } -static ssize_t store_led_status(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t mts_attr_store_led_status(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { int value; int ret; + struct gpio_pin *pin = gpio_pin_by_name("STATUS_LED"); if (sscanf(buf, "%i", &value) != 1) { return -EINVAL; @@ -795,19 +1155,19 @@ static ssize_t store_led_status(struct device *dev, struct device_attribute *att switch (value) { case LED_OFF: led_mode_status = LED_OFF; - ret = at91_set_gpio_value(GPIO_STATUS_LED, 1); + ret = at91_set_gpio_value(pin->pin, 1); break; case LED_ON: led_mode_status = LED_ON; - ret = at91_set_gpio_value(GPIO_STATUS_LED, 0); + ret = at91_set_gpio_value(pin->pin, 0); break; case LED_FLASHING: led_mode_status = LED_FLASHING; - ret = at91_set_gpio_value(GPIO_STATUS_LED, 0); + ret = at91_set_gpio_value(pin->pin, 0); break; @@ -823,32 +1183,33 @@ static ssize_t store_led_status(struct device *dev, struct device_attribute *att static struct device_attribute dev_attr_led_status = { .attr = { .name = "led-status", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_led_status, - .store = store_led_status, + .show = mts_attr_show_led_status, + .store = mts_attr_store_led_status, }; static struct device_attribute dev_attr_led_sdk_a = { .attr = { .name = "led-sdk-a", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_led_status, - .store = store_led_status, + .show = mts_attr_show_led_status, + .store = mts_attr_store_led_status, }; #endif #if LED_LS_CONTROLLABLE -static ssize_t show_led_ls(struct device *dev, +static ssize_t mts_attr_show_led_ls(struct device *dev, struct device_attribute *attr, char *buf) { int value; + struct gpio_pin *pin = gpio_pin_by_name("LS_LED"); mutex_lock(&mts_io_mutex); - value = at91_get_gpio_value(GPIO_LS_LED); + value = at91_get_gpio_value(pin->pin); mutex_unlock(&mts_io_mutex); @@ -859,11 +1220,12 @@ static ssize_t show_led_ls(struct device *dev, return sprintf(buf, "%d\n", !value); } -static ssize_t store_led_ls(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t mts_attr_store_led_ls(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { int value; int err; + struct gpio_pin *pin = gpio_pin_by_name("LS_LED"); if (sscanf(buf, "%i", &value) != 1) { return -EINVAL; @@ -871,7 +1233,7 @@ static ssize_t store_led_ls(struct device *dev, struct device_attribute *attr, mutex_lock(&mts_io_mutex); - err = at91_set_gpio_value(GPIO_LS_LED, !value); + err = at91_set_gpio_value(pin->pin, !value); mutex_unlock(&mts_io_mutex); @@ -885,22 +1247,23 @@ static ssize_t store_led_ls(struct device *dev, struct device_attribute *attr, static struct device_attribute dev_attr_led_ls = { .attr = { .name = "led-ls", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_led_ls, - .store = store_led_ls, + .show = mts_attr_show_led_ls, + .store = mts_attr_store_led_ls, }; #endif -static ssize_t show_reset(struct device *dev, +static ssize_t mts_attr_show_reset(struct device *dev, struct device_attribute *attr, char *buf) { int value; + struct gpio_pin *pin = gpio_pin_by_name("DEVICE_RESET"); mutex_lock(&mts_io_mutex); - value = !at91_get_gpio_value(GPIO_OPTRST); + value = !at91_get_gpio_value(pin->pin); mutex_unlock(&mts_io_mutex); @@ -914,12 +1277,12 @@ static ssize_t show_reset(struct device *dev, static struct device_attribute dev_attr_reset = { .attr = { .name = "reset", - .mode = 0444, + .mode = MTS_ATTR_MODE_RO, }, - .show = show_reset, + .show = mts_attr_show_reset, }; -static ssize_t show_reset_monitor(struct device *dev, +static ssize_t mts_attr_show_reset_monitor(struct device *dev, struct device_attribute *attr, char *buf) { @@ -934,8 +1297,8 @@ static ssize_t show_reset_monitor(struct device *dev, return ret; } -static ssize_t store_reset_monitor(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t mts_attr_store_reset_monitor(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { pid_t pid; int short_signal; @@ -959,26 +1322,32 @@ static ssize_t store_reset_monitor(struct device *dev, struct device_attribute * static struct device_attribute dev_attr_reset_monitor = { .attr = { .name = "reset-monitor", - .mode = 0644, + .mode = MTS_ATTR_MODE_RW, }, - .show = show_reset_monitor, - .store = store_reset_monitor, + .show = mts_attr_show_reset_monitor, + .store = mts_attr_store_reset_monitor, }; -static ssize_t show_board_temperature(struct device *dev, +static ssize_t mts_attr_show_board_temperature(struct device *dev, struct device_attribute *attr, char *buf) { int tmp; u16 temp_raw; - tmp = spi_temp_read(spi_temp, &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) { - error("spi_read temp failed %d", tmp); + log_error("spi_readn failed %d", tmp); return tmp; } + temp_raw = ((u8 *) buf)[0] << 8 | ((u8 *) buf)[1]; - dbg("temp: 0x%04X", temp_raw); + log_debug("temp: 0x%04X", temp_raw); return sprintf(buf, "%d\n", ADT7302_to_celsius(temp_raw)); } @@ -986,36 +1355,131 @@ static ssize_t show_board_temperature(struct device *dev, static struct device_attribute dev_attr_board_temperature = { .attr = { .name = "board-temperature", - .mode = 0444, + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_board_temperature, +}; + +static ssize_t mts_attr_show_adc(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int offset; + u32 value; + + if (!strcmp(id_eeprom->hw_version, HWV_MTCDP_0_0)) { + log_debug("ADC not available on 0.0 hw"); + return -ENODEV; + } + + if (!strcmp(attr->attr.name, "adc0")) { + offset = ADC_CDR0_OFFSET; + } else if (!strcmp(attr->attr.name, "adc1")) { + offset = ADC_CDR1_OFFSET; + } else if (!strcmp(attr->attr.name, "adc2")) { + offset = ADC_CDR2_OFFSET; + } else if (!strcmp(attr->attr.name, "adc3")) { + offset = ADC_CDR3_OFFSET; + } else { + log_notice("adc attr does not exists"); + return -ENOENT; + } + + ADC_CONVERT_START(adc_base); + + value = 0; + while (value != 0x0F) { + value = readl(adc_base + ADC_SR_OFFSET) & 0x0F; + } + + return sprintf(buf, "%lu\n", (unsigned long) readl(adc_base + offset)); +} + +static struct device_attribute dev_attr_adc0 = { + .attr = { + .name = "adc0", + .mode = MTS_ATTR_MODE_RO, }, - .show = show_board_temperature, + .show = mts_attr_show_adc, +}; + +static struct device_attribute dev_attr_adc1 = { + .attr = { + .name = "adc1", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_adc, +}; + +static struct device_attribute dev_attr_adc2 = { + .attr = { + .name = "adc2", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_adc, +}; + +static struct device_attribute dev_attr_adc3 = { + .attr = { + .name = "adc3", + .mode = MTS_ATTR_MODE_RO, + }, + .show = mts_attr_show_adc, }; static struct attribute *platform_attributes[] = { + &dev_attr_reset.attr, + &dev_attr_reset_monitor.attr, &dev_attr_radio_reset.attr, &dev_attr_eth0_enabled.attr, + &dev_attr_extserial_dtr.attr, +#if LED_LS_CONTROLLABLE + &dev_attr_led_ls.attr, +#endif +#if LED_STATUS_CONTROLLABLE + &dev_attr_led_status.attr, + &dev_attr_led_sdk_a.attr, +#endif + &dev_attr_extserial_dcd.attr, &dev_attr_extserial_ri.attr, &dev_attr_extserial_dsr.attr, - &dev_attr_extserial_dtr.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_cd.attr, - &dev_attr_led_sdk_b.attr, -#if LED_STATUS_CONTROLLABLE - &dev_attr_led_status.attr, - &dev_attr_led_sdk_a.attr, -#endif -#if LED_LS_CONTROLLABLE - &dev_attr_led_ls.attr, -#endif - &dev_attr_reset.attr, - &dev_attr_reset_monitor.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, }; @@ -1025,218 +1489,128 @@ static struct attribute_group platform_attribute_group = { static struct platform_device *mts_io_platform_device; -enum { - DIR_INPUT, - DIR_OUTPUT, -}; +static int __devinit mts_spi_sout_probe(struct spi_device *spi) +{ + int tmp; -struct gpio_pin_info { - char name[32]; - unsigned long pin; - int direction; - int output_value; - int use_pullup; - int board_rev_added; -}; + spi->max_speed_hz = 1 * 1000 * 1000; + spi->mode = 0; -static struct gpio_pin_info gpio_pins[] = { - /* - * GPIO_{VER0,VER1} need to be first in the list. - */ - { - .name = "GPIO_VER0", - .pin = GPIO_VER0, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, - { - .name = "GPIO_VER1", - .pin = GPIO_VER1, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, - { - .name = "GPIO_ENIO", - .pin = GPIO_ENIO, - .direction = DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, - { - .name = "GPIO_ETH0_ENABLED", - .pin = AT91_PIN_PB31, - .direction = DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, - { - .name = "GPIO_RADIO_RESET", - .pin = GPIO_RADIO_RESET, - .direction = DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, - { - .name = "GPIO_OPTRST", - .pin = GPIO_OPTRST, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, -#if LED_LS_CONTROLLABLE - { - .name = "GPIO_LS_LED", - .pin = GPIO_LS_LED, - .direction = DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, -#endif -#if LED_STATUS_CONTROLLABLE - { - .name = "GPIO_STATUS_LED", - .pin = GPIO_STATUS_LED, - .direction = DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .board_rev_added = BOARD_REVA, - }, -#endif - { - .name = "GPIO_RSERSRC", - .pin = GPIO_RSERSRC, - .direction = DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .board_rev_added = BOARD_REVB, - }, - { - .name = "GPIO_DBSERON", - .pin = GPIO_DBSERON, - .direction = DIR_OUTPUT, - .output_value = 1, - .use_pullup = 0, - .board_rev_added = BOARD_REVB, - }, - { - .name = "GPIO_DTR1", - .pin = GPIO_DTR1, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVB, - }, - { - .name = "GPIO_RXD1MON", - .pin = GPIO_RXD1MON, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVB, - }, - { - .name = "GPIO_EXTIN0", - .pin = GPIO_EXTIN0, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVB, - }, - { - .name = "GPIO_EXTIN1", - .pin = GPIO_EXTIN1, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVB, - }, - { - .name = "GPIO_EXTIN2", - .pin = GPIO_EXTIN2, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVB, - }, -#if 0 - { - .name = "GPIO_EXTIN3", - .pin = GPIO_EXTIN3, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVC, - }, - { - .name = "GPIO_EXTIN4", - .pin = GPIO_EXTIN4, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVC, - }, - { - .name = "GPIO_EXTIN5", - .pin = GPIO_EXTIN5, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVC, - }, - { - .name = "GPIO_GPS_NINT2", - .pin = GPIO_GPS_NINT2, - .direction = DIR_INPUT, - .output_value = 0, - .use_pullup = 0, - .board_rev_added = BOARD_REVC, + 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, }, -#endif + + .probe = mts_spi_sout_probe, + .remove = __devexit_p(mts_spi_sout_remove), }; -static int __devinit mts_spi_sregout_probe(struct spi_device *spi) +static int __devinit mts_spi_dout_probe(struct spi_device *spi) { int tmp; + if (!strcmp(id_eeprom->hw_version, HWV_MTCDP_0_0)) { + log_debug("digital outputs not available on 0.0 hw"); + return -ENODEV; + } + spi->max_speed_hz = 1 * 1000 * 1000; spi->mode = 0; tmp = spi_setup(spi); if (tmp < 0) { + log_error("spi_setup dout failed"); return tmp; } - spi_sregout_byte = 0xFF; - spi_sregout_write(spi, spi_sregout_byte); + spi_dout_value = 0x00; + spi_writen(spi, &spi_dout_value, 1); - spi_sregout = spi; + spi_dout_dev = spi; return 0; } -static int mts_spi_sregout_remove(struct spi_device *spi) +static int mts_spi_dout_remove(struct spi_device *spi) { + spi_dout_dev = NULL; + return 0; } -static struct spi_driver mts_spi_sregout_driver = { +static struct spi_driver mts_spi_dout_driver = { .driver = { - .name = "mts-io-sregout", + .name = "mts-io-dout", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = mts_spi_sregout_probe, - .remove = __devexit_p(mts_spi_sregout_remove), + .probe = mts_spi_dout_probe, + .remove = __devexit_p(mts_spi_dout_remove), +}; + +static int __devinit mts_spi_din_probe(struct spi_device *spi) +{ + int tmp; + + if (!strcmp(id_eeprom->hw_version, HWV_MTCDP_0_0)) { + log_debug("digital inputs not available on 0.0 hw"); + return -ENODEV; + } + + spi->max_speed_hz = 1 * 1000 * 1000; + spi->mode = SPI_CPHA; + + 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 = __devexit_p(mts_spi_din_remove), }; static int __devinit mts_spi_board_temp_probe(struct spi_device *spi) @@ -1248,17 +1622,19 @@ static int __devinit mts_spi_board_temp_probe(struct spi_device *spi) tmp = spi_setup(spi); if (tmp < 0) { - error("spi_setup board-tmp"); + log_error("spi_setup board-temp failed"); return tmp; } - spi_temp = spi; + 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; } @@ -1275,10 +1651,15 @@ static struct spi_driver mts_spi_board_temp_driver = { static int __init mts_io_init(void) { - int i; + struct gpio_pin *pin; int ret; - info("init"); + log_info("init: " DRIVER_VERSION); + + ret = mts_id_eeprom_load(); + if (ret) { + goto error1; + } mts_io_platform_device = platform_device_alloc(PLATFORM_NAME, -1); if (!mts_io_platform_device) { @@ -1297,81 +1678,104 @@ static int __init mts_io_init(void) goto error3; } - for (i = 0; i < ARRAY_SIZE(gpio_pins); i++) { - gpio_request(gpio_pins[i].pin, gpio_pins[i].name); - - if (board_rev >= gpio_pins[i].board_rev_added) { - if (gpio_pins[i].direction == DIR_OUTPUT) { - at91_set_gpio_output(gpio_pins[i].pin, - gpio_pins[i].output_value); - } else { - at91_set_gpio_input(gpio_pins[i].pin, - gpio_pins[i].use_pullup); - } - } - - if (i == 1) { - board_rev = (at91_get_gpio_value(GPIO_VER1) << 1) | - at91_get_gpio_value(GPIO_VER0); - board_rev ^= 0x03; - info("board rev: %d", board_rev); - - if (board_rev == BOARD_REVA) { - error("rev A boards are not supported"); - ret = -EIO; - goto error3; - } - } + ret = spi_register_driver(&mts_spi_sout_driver); + if (ret) { + goto error4; } - at91_set_gpio_value(GPIO_ENIO, 0); + ret = spi_register_driver(&mts_spi_board_temp_driver); + if (ret) { + goto error7; + } - ret = spi_register_driver(&mts_spi_sregout_driver); + ret = spi_register_driver(&mts_spi_dout_driver); if (ret) { - goto error3; + goto error5; } - ret = spi_register_driver(&mts_spi_board_temp_driver); + ret = spi_register_driver(&mts_spi_din_driver); if (ret) { - goto error4; + goto error6; + } + + adc_base = ioremap(AT91SAM9260_BASE_ADC, SZ_16K); + if (!adc_base) { + goto error8; } + adc_clk = clk_get(NULL, "adc_clk"); + if (!adc_clk) { + goto error9; + } + 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 (!strcmp(id_eeprom->hw_version, HWV_MTCDP_0_0)) { + writel(0x0F, adc_base + ADC_CHDR_OFFSET); + } else { + writel(0x0F, adc_base + ADC_CHER_OFFSET); + } + + for (pin = gpio_pins; *pin->name; pin++) { + gpio_request(pin->pin, pin->name); + + if (pin->direction == GPIO_DIR_OUTPUT) { + at91_set_gpio_output(pin->pin, pin->output_value); + } else { + at91_set_gpio_input(pin->pin, pin->use_pullup); + } + } + + pin = gpio_pin_by_name("ENIO"); + at91_set_gpio_value(pin->pin, 0); + blink_callback(NULL); return 0; +error9: + iounmap(adc_base); +error8: + spi_unregister_driver(&mts_spi_board_temp_driver); +error7: + spi_unregister_driver(&mts_spi_din_driver); +error6: + spi_unregister_driver(&mts_spi_dout_driver); +error5: + spi_unregister_driver(&mts_spi_sout_driver); error4: - spi_unregister_driver(&mts_spi_sregout_driver); + sysfs_remove_group(&mts_io_platform_device->dev.kobj, + &platform_attribute_group); error3: platform_device_del(mts_io_platform_device); error2: platform_device_put(mts_io_platform_device); error1: - error("init failed: %d", ret); + log_error("init failed: %d", ret); return ret; } static void __exit mts_io_exit(void) { - int i; - cancel_delayed_work_sync(&blink_work); - spi_unregister_driver(&mts_spi_board_temp_driver); - spi_unregister_driver(&mts_spi_sregout_driver); + iounmap(adc_base); + clk_disable(adc_clk); + clk_put(adc_clk); - for (i = 0; i < ARRAY_SIZE(gpio_pins); i++) { - if (board_rev >= gpio_pins[i].board_rev_added) { - at91_set_gpio_input(gpio_pins[i].pin, gpio_pins[i].use_pullup); - } - } + spi_unregister_driver(&mts_spi_din_driver); + spi_unregister_driver(&mts_spi_dout_driver); + spi_unregister_driver(&mts_spi_board_temp_driver); + spi_unregister_driver(&mts_spi_sout_driver); sysfs_remove_group(&mts_io_platform_device->dev.kobj, &platform_attribute_group); platform_device_unregister(mts_io_platform_device); - info("exiting"); + log_info("exiting"); } module_init(mts_io_init); @@ -1382,5 +1786,7 @@ 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"); |