diff options
| author | James Maki <jmaki@multitech.com> | 2010-09-09 10:39:07 -0500 |
|---|---|---|
| committer | James Maki <jmaki@multitech.com> | 2010-09-09 10:39:07 -0500 |
| commit | 427222a6fdf12e8220cffbb96646f0d166286da3 (patch) | |
| tree | a8d93b1434ede404228facc10ee4ef475e123432 | |
| parent | b3556e09b09136ac6b4435b2ccd1f57a13365535 (diff) | |
| download | mts-io-427222a6fdf12e8220cffbb96646f0d166286da3.tar.gz mts-io-427222a6fdf12e8220cffbb96646f0d166286da3.tar.bz2 mts-io-427222a6fdf12e8220cffbb96646f0d166286da3.zip | |
update for MTCDP-1.0
| -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( |
