diff options
Diffstat (limited to 'io-module')
-rw-r--r-- | io-module/mtdc_gpiob.c | 289 | ||||
-rw-r--r-- | io-module/mtr2d2.c | 134 | ||||
-rw-r--r-- | io-module/mts_io.c | 274 | ||||
-rw-r--r-- | io-module/spi.c | 248 |
4 files changed, 750 insertions, 195 deletions
diff --git a/io-module/mtdc_gpiob.c b/io-module/mtdc_gpiob.c index c207483..5a592b7 100644 --- a/io-module/mtdc_gpiob.c +++ b/io-module/mtdc_gpiob.c @@ -1,16 +1,25 @@ - -struct gpio_pin *dc_gpio_pin_by_attr_name(const char *name) { +struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { struct gpio_pin *pin; char *pin_attr_name; - if (!strcmp(name, "led1")) { - pin_attr_name = "dc-gpio1"; - } else if (!strcmp(name, "led2")) { - pin_attr_name = "dc-gpio2"; - } else if (!strcmp(name, "dout-enable")) { - pin_attr_name = "dc-gpio3"; + if (!strcmp(name, "ap1-led1")) { + pin_attr_name = "ap1-gpio3"; + } else if (!strcmp(name, "ap1-led2")) { + pin_attr_name = "ap1-gpio4"; + } else if (!strcmp(name, "ap1-dout-enable")) { + pin_attr_name = "ap1-gpio1"; + } else if (!strcmp(name, "ap1-reset")) { + pin_attr_name = "ap1-reset"; + } else if (!strcmp(name, "ap2-led1")) { + pin_attr_name = "ap2-gpio3"; + } else if (!strcmp(name, "ap2-led2")) { + pin_attr_name = "ap2-gpio4"; + } else if (!strcmp(name, "ap2-dout-enable")) { + pin_attr_name = "ap2-gpio1"; + } else if (!strcmp(name, "ap2-reset")) { + pin_attr_name = "ap2-reset"; } else { - log_error("daughter card attribute %s not available", name); + log_error("accessory card attribute %s not available", name); return NULL; } @@ -26,12 +35,12 @@ struct gpio_pin *dc_gpio_pin_by_attr_name(const char *name) { } -static ssize_t mts_attr_show_dc_gpio_pin(struct device *dev, +static ssize_t mts_attr_show_ap_gpio_pin(struct device *dev, struct device_attribute *attr, char *buf) { int value; - struct gpio_pin *pin = dc_gpio_pin_by_attr_name(attr->attr.name); + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); if (!pin) { return -ENODEV; @@ -54,11 +63,11 @@ static ssize_t mts_attr_show_dc_gpio_pin(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t mts_attr_store_dc_gpio_pin(struct device *dev, +static ssize_t mts_attr_store_ap_gpio_pin(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; - struct gpio_pin *pin = dc_gpio_pin_by_attr_name(attr->attr.name); + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); if (!pin) { return -ENODEV; @@ -81,31 +90,46 @@ static ssize_t mts_attr_store_dc_gpio_pin(struct device *dev, return count; } -static ssize_t mts_attr_show_dc_din(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_din(struct device *dev, struct device_attribute *attr, char *buf) { int tmp; u8 bit; u8 byte; + struct spi_device* spi_dev; + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_din_dev) { + log_error("accessory card 1 din device not present"); + return -ENODEV; + } - if (!spi_dc_din_dev) { - log_error("dc din device not present"); + spi_dev = spi_ap1_din_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_din_dev) { + log_error("accessory card 2 din device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_din_dev; + } else { + log_error("unknown din device %s", attr->attr.name); return -ENODEV; } - if (!strcmp(attr->attr.name, "din0")) { + if (strstr(attr->attr.name, "din0")) { bit = BIT(0); - } else if (!strcmp(attr->attr.name, "din1")) { + } else if (strstr(attr->attr.name, "din1")) { bit = BIT(1); - } else if (!strcmp(attr->attr.name, "din2")) { + } else if (strstr(attr->attr.name, "din2")) { bit = BIT(2); - } else if (!strcmp(attr->attr.name, "din3")) { + } else if (strstr(attr->attr.name, "din3")) { bit = BIT(3); } else { - log_error("dc din attr does not exist"); + log_error("accessory card din attr does not exist"); return -ENOENT; } - tmp = spi_readn(spi_dc_din_dev, &byte, 1); + tmp = spi_readn(spi_dev, &byte, 1); if (tmp) { log_error("spi_read failed %d", tmp); return tmp; @@ -116,82 +140,112 @@ static ssize_t mts_attr_show_dc_din(struct device *dev, struct device_attribute return sprintf(buf, "%d\n", tmp); } -static ssize_t mts_attr_store_dc_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t mts_attr_store_ap_dout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; u8 bit; + struct spi_device* spi_dev; + + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_dout_dev) { + log_error("accessory card 1 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_dout_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_dout_dev) { + log_error("accessory card 2 dout device not present"); + return -ENODEV; + } - if (!spi_dc_dout_dev) { - log_error("dc dout device not present"); + spi_dev = spi_ap2_dout_dev; + } else { + log_error("unknown dout device %s", attr->attr.name); return -ENODEV; } - if (!strcmp(attr->attr.name, "dout0")) { + if (strstr(attr->attr.name, "dout0")) { bit = BIT(0); - } else if (!strcmp(attr->attr.name, "dout1")) { + } else if (strstr(attr->attr.name, "dout1")) { bit = BIT(1); - } else if (!strcmp(attr->attr.name, "dout2")) { + } else if (strstr(attr->attr.name, "dout2")) { bit = BIT(2); - } else if (!strcmp(attr->attr.name, "dout3")) { + } else if (strstr(attr->attr.name, "dout3")) { bit = BIT(3); } else { - log_error("dc dout attr does not exist"); + log_error("accessory card dout attr does not exist"); return -ENOENT; } if (sscanf(buf, "%i", &value) != 1) { - log_error("dc dout attr invalid argument"); + log_error("accessory card dout attr invalid argument"); return -EINVAL; } - mutex_lock(&spi_dc_dout_mutex); + mutex_lock(&spi_ap_dout_mutex); if (value) { - spi_dc_dout_value &= ~bit; + spi_ap_dout_value &= ~bit; } else { - spi_dc_dout_value |= bit; + spi_ap_dout_value |= bit; } - spi_writen(spi_dc_dout_dev, &spi_dc_dout_value, 1); + spi_writen(spi_dev, &spi_ap_dout_value, 1); - mutex_unlock(&spi_dc_dout_mutex); + mutex_unlock(&spi_ap_dout_mutex); return count; } -static ssize_t mts_attr_show_dc_dout(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_dout(struct device *dev, struct device_attribute *attr, char *buf) { int value; u8 bit; + struct spi_device* spi_dev; - if (!spi_dc_dout_dev) { - log_error("dc dout device not present"); + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_dout_dev) { + log_error("accessory card 1 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_dout_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_dout_dev) { + log_error("accessory card 2 dout device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_dout_dev; + } else { + log_error("unknown dout device %s", attr->attr.name); return -ENODEV; } - if (!strcmp(attr->attr.name, "dout0")) { + if (strstr(attr->attr.name, "dout0")) { bit = BIT(0); - } else if (!strcmp(attr->attr.name, "dout1")) { + } else if (strstr(attr->attr.name, "dout1")) { bit = BIT(1); - } else if (!strcmp(attr->attr.name, "dout2")) { + } else if (strstr(attr->attr.name, "dout2")) { bit = BIT(2); - } else if (!strcmp(attr->attr.name, "dout3")) { + } else if (strstr(attr->attr.name, "dout3")) { bit = BIT(3); } else { - log_error("dc dout attr does not exist"); + log_error("accessory card dout attr does not exist"); return -ENOENT; } - mutex_lock(&spi_dc_dout_mutex); + mutex_lock(&spi_ap_dout_mutex); - value = spi_dc_dout_value & bit ? 0 : 1; + value = spi_ap_dout_value & bit ? 0 : 1; - mutex_unlock(&spi_dc_dout_mutex); + mutex_unlock(&spi_ap_dout_mutex); return sprintf(buf, "%d\n", value); } -static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t mts_attr_show_ap_adc(struct device *dev, struct device_attribute *attr, char *buf) { int tmp; int tx_data; @@ -201,23 +255,38 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute int manual_mode = 0x1840; /* 0b 0001 1000 0100 0000 */ uint8_t tx[2]; uint8_t rx[2]; - - if (!spi_dc_adc_dev) { - log_error("dc adc device not present"); - return -ENODEV; - } + struct spi_device* spi_dev; memset(tx, 0, sizeof(tx)); memset(rx, 0, sizeof(rx)); - if (!strcmp(attr->attr.name, "adc0")) { + if (strstr(attr->attr.name, ":0")) { + if (!spi_ap1_adc_dev) { + log_error("accessory card 1 adc device not present"); + return -ENODEV; + } + + spi_dev = spi_ap1_adc_dev; + } else if (strstr(attr->attr.name, ":1")) { + if (!spi_ap2_adc_dev) { + log_error("accessory card 2 adc device not present"); + return -ENODEV; + } + + spi_dev = spi_ap2_adc_dev; + } else { + log_error("unknown adc device %s", attr->attr.name); + return -ENODEV; + } + + if (strstr(attr->attr.name, "adc0")) { channel = 0; - } else if (!strcmp(attr->attr.name, "adc1")) { + } else if (strstr(attr->attr.name, "adc1")) { channel = 1; - } else if (! strcmp(attr->attr.name, "adc2")) { + } else if (strstr(attr->attr.name, "adc2")) { channel = 2; } else { - log_error("dc adc attr does not exist"); + log_error("accessory card adc attr does not exist"); return -ENOENT; } @@ -225,7 +294,7 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute tx_data = manual_mode | ((channel << 7) & channel_mask); tx[0] = tx_data >> 8; tx[1] = tx_data & 0xFF; - tmp = spi_writen(spi_dc_adc_dev, tx, 2); + tmp = spi_writen(spi_dev, tx, 2); if (tmp) { log_error("spi_write failed %d", tmp); return tmp; @@ -236,14 +305,14 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute * the ADC just needs the clock running so it can convert */ tx[0] = 0; tx[1] = 0; - tmp = spi_writen(spi_dc_adc_dev, tx, 2); + tmp = spi_writen(spi_dev, tx, 2); if (tmp) { log_error("2nd spi_write failed %d", tmp); return tmp; } /* 3rd transfer to read data */ - tmp = spi_readn(spi_dc_adc_dev, rx, 2); + tmp = spi_readn(spi_dev, rx, 2); if (tmp) { log_error("spi_read failed %d", tmp); return tmp; @@ -253,18 +322,88 @@ static ssize_t mts_attr_show_dc_adc(struct device *dev, struct device_attribute return sprintf(buf, "%lu\n", (unsigned long) rx_data); } -/* MTDC-GPIOB */ -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din0, "din0", mts_attr_show_dc_din); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din1, "din1", mts_attr_show_dc_din); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din2, "din2", mts_attr_show_dc_din); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_din3, "din3", mts_attr_show_dc_din); -static DEVICE_ATTR_MTS(dev_attr_dc_dout0, "dout0", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_MTS(dev_attr_dc_dout1, "dout1", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_MTS(dev_attr_dc_dout2, "dout2", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_MTS(dev_attr_dc_dout3, "dout3", mts_attr_show_dc_dout, mts_attr_store_dc_dout); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc0, "adc0", mts_attr_show_dc_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc1, "adc1", mts_attr_show_dc_adc); -static DEVICE_ATTR_RO_MTS(dev_attr_dc_adc2, "adc2", mts_attr_show_dc_adc); -static DEVICE_ATTR_MTS(dev_attr_dc_led1, "led1", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_dc_led2, "led2", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin); -static DEVICE_ATTR_MTS(dev_attr_dc_oe, "dout-enable", mts_attr_show_dc_gpio_pin, mts_attr_store_dc_gpio_pin); +/* accessory port 1 gpiob attributes */ +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din0, "din0:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din1, "din1:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din2, "din2:0", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_din3, "din3:0", mts_attr_show_ap_din); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout0, "dout0:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout1, "dout1:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout2, "dout2:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_dout3, "dout3:0", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc0, "adc0:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc1, "adc1:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap1_gpio_adc2, "adc2:0", mts_attr_show_ap_adc); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led1, "ap1-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_led2, "ap1-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_gpio_oe, "ap1-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap1_reset, "ap1-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); + +static int ap1_gpio_attributes_size = 15; // not including NULL at end + +static struct attribute *ap1_gpio_attributes[] = { + &dev_attr_ap1_reset.attr, + + &dev_attr_ap1_gpio_oe.attr, // gpio1 + &dev_attr_ap1_gpio_led1.attr, // gpio3 + &dev_attr_ap1_gpio_led2.attr, // gpio4 + + &dev_attr_ap1_gpio_din0.attr, + &dev_attr_ap1_gpio_din1.attr, + &dev_attr_ap1_gpio_din2.attr, + &dev_attr_ap1_gpio_din3.attr, + + &dev_attr_ap1_gpio_dout0.attr, + &dev_attr_ap1_gpio_dout1.attr, + &dev_attr_ap1_gpio_dout2.attr, + &dev_attr_ap1_gpio_dout3.attr, + + &dev_attr_ap1_gpio_adc0.attr, + &dev_attr_ap1_gpio_adc1.attr, + &dev_attr_ap1_gpio_adc2.attr, + + NULL, +}; + +/* accessory port 2 gpiob attributes */ +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din0, "din0:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din1, "din1:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din2, "din2:1", mts_attr_show_ap_din); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_din3, "din3:1", mts_attr_show_ap_din); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout0, "dout0:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout1, "dout1:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout2, "dout2:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_dout3, "dout3:1", mts_attr_show_ap_dout, mts_attr_store_ap_dout); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc0, "adc0:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc1, "adc1:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_RO_MTS(dev_attr_ap2_gpio_adc2, "adc2:1", mts_attr_show_ap_adc); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led1, "ap2-led1", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_led2, "ap2-led2", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_gpio_oe, "ap2-dout-enable", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); +static DEVICE_ATTR_MTS(dev_attr_ap2_reset, "ap2-reset", mts_attr_show_ap_gpio_pin, mts_attr_store_ap_gpio_pin); + +static int ap2_gpio_attributes_size = 15; // not including NULL at end + +static struct attribute *ap2_gpio_attributes[] = { + &dev_attr_ap2_reset.attr, + + &dev_attr_ap2_gpio_oe.attr, // gpio1 + &dev_attr_ap2_gpio_led1.attr, // gpio3 + &dev_attr_ap2_gpio_led2.attr, // gpio4 + + &dev_attr_ap2_gpio_din0.attr, + &dev_attr_ap2_gpio_din1.attr, + &dev_attr_ap2_gpio_din2.attr, + &dev_attr_ap2_gpio_din3.attr, + + &dev_attr_ap2_gpio_dout0.attr, + &dev_attr_ap2_gpio_dout1.attr, + &dev_attr_ap2_gpio_dout2.attr, + &dev_attr_ap2_gpio_dout3.attr, + + &dev_attr_ap2_gpio_adc0.attr, + &dev_attr_ap2_gpio_adc1.attr, + &dev_attr_ap2_gpio_adc2.attr, + + NULL, +}; diff --git a/io-module/mtr2d2.c b/io-module/mtr2d2.c index 58aeb03..b2fc03f 100644 --- a/io-module/mtr2d2.c +++ b/io-module/mtr2d2.c @@ -146,9 +146,130 @@ static struct gpio_pin gpio_pins_mtr2d2_0_0[] = { }, .active_low = 1, }, + + // gpio pins for Accessory Card 1 + { + .name = "AP1_RESET", + .pin = { + .gpio = AT91_PIN_PB12, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "ap1-reset", + } + }, + { + .name = "AP1_GPIO1", + .pin = { + .gpio = AT91_PIN_PC6, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio1", + }, + .active_low = 1, + }, + { + .name = "AP1_GPIO2", + .pin = { + .gpio = AT91_PIN_PC7, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio2", + } + }, + { + .name = "AP1_GPIO3", + .pin = { + .gpio = AT91_PIN_PC8, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio3", + } + }, + { + .name = "AP1_GPIO4", + .pin = { + .gpio = AT91_PIN_PC9, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap1-gpio4", + } + }, + { + .name = "AP1_INTERRUPT1", + .pin = { + .gpio = AT91_PIN_PB14, + .flags = GPIOF_IN, + .label = "ap1-interrupt1", + } + }, + { + .name = "AP1_INTERRUPT2", + .pin = { + .gpio = AT91_PIN_PB15, + .flags = GPIOF_IN, + .label = "ap1-interrupt2", + } + }, + + // gpio pins for Accessory Card 2 + { + .name = "AP2_RESET", + .pin = { + .gpio = AT91_PIN_PB13, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "ap2-reset", + } + }, + { + .name = "AP2_GPIO1", + .pin = { + .gpio = AT91_PIN_PC20, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio1", + }, + .active_low = 1, + }, + { + .name = "AP2_GPIO2", + .pin = { + .gpio = AT91_PIN_PC21, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio2", + } + }, + { + .name = "AP2_GPIO3", + .pin = { + .gpio = AT91_PIN_PC22, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio3", + } + }, + { + .name = "AP2_GPIO4", + .pin = { + .gpio = AT91_PIN_PC23, + .flags = GPIOF_OUT_INIT_LOW, + .label = "ap2-gpio4", + } + }, + { + .name = "AP2_INTERRUPT1", + .pin = { + .gpio = AT91_PIN_PB17, + .flags = GPIOF_IN, + .label = "ap2-interrupt1", + } + }, + { + .name = "AP2_INTERRUPT2", + .pin = { + .gpio = AT91_PIN_PB18, + .flags = GPIOF_IN, + .label = "ap2-interrupt2", + } + }, + { }, }; +static int mtr2d2_platform_attributes_size = 64; // not including NULL at end + static struct attribute *mtr2d2_platform_attributes[] = { &dev_attr_vendor_id.attr, &dev_attr_product_id.attr, @@ -207,6 +328,19 @@ static struct attribute *mtr2d2_platform_attributes[] = { NULL, // index 49 NULL, // index 50 NULL, // index 51 + NULL, // index 52 + NULL, // index 53 + NULL, // index 54 + NULL, // index 55 + NULL, // index 56 + NULL, // index 57 + NULL, // index 58 + NULL, // index 59 + NULL, // index 60 + NULL, // index 61 + NULL, // index 62 + NULL, // index 63 + NULL, // index 64 NULL, }; diff --git a/io-module/mts_io.c b/io-module/mts_io.c index e26013d..b63a756 100644 --- a/io-module/mts_io.c +++ b/io-module/mts_io.c @@ -71,8 +71,8 @@ static struct mts_ap_eeprom_layout ap1_eeprom; static struct mts_ap_eeprom_layout ap2_eeprom; bool accessory_card_capable = false; -bool has_accessory_card_port_1 = false; -bool has_accessory_card_port_2 = false; +bool have_accessory_card_slot_1 = false; +bool have_accessory_card_slot_2 = false; static uint8_t mts_product_id; static uint8_t mts_ap1_product_id; @@ -405,7 +405,7 @@ static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth", mts_attr_show_product_info); /* include per-device pins and attributes */ -#include "mtr2.c" +//#include "mtr2.c" #include "mtr.c" #include "mtr2d2.c" @@ -414,10 +414,70 @@ static DEVICE_ATTR_RO_MTS(dev_attr_eth_mac, "mac-eth", #include "mt100eocg.c" */ -/* reorg this function to load and log both accessory card EEPROMs - * should be able to handle either or both slots being empty - */ -static int mts_ap_eeprom_load(void) +static bool add_accessory_card_attributes(int slot) +{ + size_t device_attrs_size; + size_t card_attrs_size; + size_t attrs_index; + size_t i; + + struct attribute **device_attrs; + struct attribute **card_attrs; + + switch (mts_product_id) { + case MTR2D2_0_0: + device_attrs_size = mtr2d2_platform_attributes_size; + device_attrs = mtr2d2_platform_attributes; + break; + default: + log_error("accessory cards aren't supported for platform %s", id_eeprom.hw_version); + return false; + } + + if (slot == 1) { + switch (mts_ap1_product_id) { + case MTDC_GPIOB_0_0: + card_attrs_size = ap1_gpio_attributes_size; + card_attrs = ap1_gpio_attributes; + break; + default: + log_error("accessory card %s isn't supported", ap1_eeprom.hw_version); + return false; + } + } else if (slot == 2) { + switch (mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + card_attrs_size = ap2_gpio_attributes_size; + card_attrs = ap2_gpio_attributes; + break; + default: + log_error("accessory card %s isn't supported", ap2_eeprom.hw_version); + return false; + } + } else { + log_error("%d is an invalid slot value", slot); + return false; + } + + for (attrs_index = 0; attrs_index < device_attrs_size; attrs_index++) { + if (! device_attrs[attrs_index]) { + break; + } + } + + if (device_attrs_size < attrs_index + card_attrs_size) { + log_error("not enough room for accessory card attributes!"); + return false; + } + + for (i = 0; i < card_attrs_size; i++) { + device_attrs[attrs_index + i] = card_attrs[i]; + } + + return true; +} + +static bool mts_ap_eeprom_load(void) { // Accessory Card Slot 1 memcpy(&ap1_eeprom, mts_ap1_eeprom, sizeof(mts_ap1_eeprom)); @@ -427,7 +487,7 @@ static int mts_ap_eeprom_load(void) } else if (mts_ap1_eeprom[0] == 0x00) { log_info("no accessory card inserted in slot 1"); } else { - has_accessory_card_port_1 = true; + have_accessory_card_slot_1 = true; log_info("accessory card 1 vendor-id: %.32s", ap1_eeprom.vendor_id); log_info("accessory card 1 product-id: %.32s", ap1_eeprom.product_id); @@ -452,7 +512,7 @@ static int mts_ap_eeprom_load(void) } else if (mts_ap2_eeprom[0] == 0x00) { log_info("no accessory card inserted in slot 2"); } else { - has_accessory_card_port_2 = true; + have_accessory_card_slot_2 = true; log_info("accessory card 2 vendor-id: %.32s", ap2_eeprom.vendor_id); log_info("accessory card 2 product-id: %.32s", ap2_eeprom.product_id); @@ -469,7 +529,8 @@ static int mts_ap_eeprom_load(void) } } - return 0; + // if either slot has a valid card, return true + return (have_accessory_card_slot_1 || have_accessory_card_slot_2); } static int mts_id_eeprom_load(void) @@ -507,7 +568,6 @@ static int mts_id_eeprom_load(void) has_spi_dout = 1; has_spi_temp = 1; log_info("detected board %s", HW_VERSION_MT100EOCG_0_0); - */ } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTR2_0_0, strlen(HW_VERSION_MTR2_0_0)) == 0) { attr_group = &mtr2_platform_attribute_group; gpio_pins = gpio_pins_mtr2_0_0; @@ -518,6 +578,7 @@ static int mts_id_eeprom_load(void) has_spi_dout = 0; has_spi_temp = 1; log_info("detected board %s", HW_VERSION_MTR2_0_0); + */ } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTR_0_0, strlen(HW_VERSION_MTR_0_0)) == 0) { attr_group = &mtr_platform_attribute_group; gpio_pins = gpio_pins_mtr_0_0; @@ -536,6 +597,7 @@ static int mts_id_eeprom_load(void) has_spi_dout = 0; has_spi_temp = 0; log_info("detected board %s", HW_VERSION_MTR_0_1); + /* } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTOCGD2_0_0, strlen(HW_VERSION_MTOCGD2_0_0)) == 0) { attr_group = &mtr2_platform_attribute_group; gpio_pins = gpio_pins_mtr2_0_0; @@ -546,6 +608,7 @@ static int mts_id_eeprom_load(void) has_spi_dout = 0; has_spi_temp = 1; log_info("detected board %s", HW_VERSION_MTOCGD2_0_0); + */ } else if (strncmp(id_eeprom.hw_version, HW_VERSION_MTOCGD_0_0, strlen(HW_VERSION_MTOCGD_0_0)) == 0) { attr_group = &mtr_platform_attribute_group; gpio_pins = gpio_pins_mtr_0_0; @@ -568,6 +631,7 @@ static int mts_id_eeprom_load(void) attr_group = &mtr2d2_platform_attribute_group; gpio_pins = gpio_pins_mtr2d2_0_0; mts_product_id = MTR2D2_0_0; + accessory_card_capable = true; has_spi_sout = 0; has_spi_din = 0; has_spi_dout = 0; @@ -631,6 +695,8 @@ static int __init mts_io_init(void) { struct gpio_pin *pin; int ret; + size_t device_attributes_size; + size_t card_attributes_size; log_info("init: " DRIVER_VERSION); @@ -641,54 +707,92 @@ static int __init mts_io_init(void) if (accessory_card_capable) { mts_ap1_product_id = MTDC_NONE; - ret = mts_ap_eeprom_load(); - if (ret) { - /* error reading the EEPROM from the daughter card */ - log_error("error reading daughter card eeprom: %d", ret); - log_error("unable to initialize daughter card"); - goto error1; - } else if (false) { - // this needs review, stay away for now - /* no error and we have a daughter card */ - if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) { - mts_ap1_product_id = MTDC_GPIOB_0_0; + mts_ap2_product_id = MTDC_NONE; + if (mts_ap_eeprom_load()) { + // handle both slots, but do slot 1 first + // probably need special handling if both cards are the same type + if (have_accessory_card_slot_1) { + // more elegant way to handle this? + if (strstr(ap1_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) { + mts_ap1_product_id = MTDC_GPIOB_0_0; + } // else if (...) { } + + switch(mts_ap1_product_id) { + case MTDC_GPIOB_0_0: + log_info("loading GPIO accessory card in slot 1"); + if (! add_accessory_card_attributes(1)) { + log_error("failed to load GPIO accessory card in slot 1"); + } else { + log_info("successfully loaded GPIO accessory card in slot 1"); + } + log_debug("registering accessory card 1 dout driver"); + ret = spi_register_driver(&mts_spi_ap1_dout_driver); + if (ret) { + log_error("failed to register accessory card 1 dout driver"); + spi_unregister_driver(&mts_spi_ap1_dout_driver); + goto error1; + } + log_debug("registering accessory card 1 din driver"); + ret = spi_register_driver(&mts_spi_ap1_din_driver); + if (ret) { + log_error("failed to register accessory card 1 din driver"); + spi_unregister_driver(&mts_spi_ap1_din_driver); + goto error1; + } + log_debug("registering accessory card 1 adc driver"); + ret = spi_register_driver(&mts_spi_ap1_adc_driver); + if (ret) { + log_error("failed to register accessory card 1 adc driver"); + spi_unregister_driver(&mts_spi_ap1_adc_driver); + goto error1; + } + break; + + default: + log_error("accessory card %s unsupported", ap1_eeprom.product_id); + } } - switch(mts_ap1_product_id) { - case MTDC_GPIOB_0_0: - log_debug("adding GPIO daughter card attributes"); - if (! mtr2_add_daughter_card_attributes()) { - log_error("failed to add GPIO daughter card attributes"); - goto error1; - } else { - log_info("successfully added GPIO daughter card attributes"); - } - - log_debug("registering daughter card dout driver"); - ret = spi_register_driver(&mts_spi_dc_dout_driver); - if (ret) { - log_error("failed to register dc dout driver"); - spi_unregister_driver(&mts_spi_dc_dout_driver); - goto error1; - } - log_debug("registering daughter card din driver"); - ret = spi_register_driver(&mts_spi_dc_din_driver); - if (ret) { - log_error("failed to register dc din driver"); - spi_unregister_driver(&mts_spi_dc_din_driver); - goto error1; - } - log_debug("registering daughter card adc driver"); - ret = spi_register_driver(&mts_spi_dc_adc_driver); - if (ret) { - log_error("failed to register dc adc driver"); - spi_unregister_driver(&mts_spi_dc_adc_driver); - goto error1; - } - break; - - default: - log_info("daughter card '%s' currently unsupported", ap1_eeprom.product_id); + if (have_accessory_card_slot_2) { + // more elegant way to handle this? + if (strstr(ap2_eeprom.product_id, PRODUCT_ID_MTDC_GPIOB)) { + mts_ap2_product_id = MTDC_GPIOB_0_0; + } // else if (...) { } + + switch(mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + log_info("loading GPIO accessory card in slot 2"); + if (! add_accessory_card_attributes(2)) { + log_error("failed to load GPIO accessory card in slot 2"); + } else { + log_info("successfully loaded GPIO accessory card in slot 2"); + } + log_debug("registering accessory card 2 dout driver"); + ret = spi_register_driver(&mts_spi_ap2_dout_driver); + if (ret) { + log_error("failed to register accessory card 2 dout driver"); + spi_unregister_driver(&mts_spi_ap2_dout_driver); + goto error1; + } + log_debug("registering accessory card 2 din driver"); + ret = spi_register_driver(&mts_spi_ap2_din_driver); + if (ret) { + log_error("failed to register accessory card 2 din driver"); + spi_unregister_driver(&mts_spi_ap2_din_driver); + goto error1; + } + log_debug("registering accessory card 2 adc driver"); + ret = spi_register_driver(&mts_spi_ap2_adc_driver); + if (ret) { + log_error("failed to register accessory card 2 adc driver"); + spi_unregister_driver(&mts_spi_ap2_adc_driver); + goto error1; + } + break; + + default: + log_error("accessory card %s unsupported", ap1_eeprom.product_id); + } } } } @@ -815,6 +919,32 @@ error3: platform_device_del(mts_io_platform_device); error2: platform_device_put(mts_io_platform_device); + + if (have_accessory_card_slot_1) { + switch (mts_ap1_product_id) { + case MTDC_GPIOB_0_0: + spi_unregister_driver(&mts_spi_ap1_dout_driver); + spi_unregister_driver(&mts_spi_ap1_din_driver); + spi_unregister_driver(&mts_spi_ap1_adc_driver); + break; + + default: + break; + } + } + + if (have_accessory_card_slot_2) { + switch (mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + spi_unregister_driver(&mts_spi_ap2_dout_driver); + spi_unregister_driver(&mts_spi_ap2_din_driver); + spi_unregister_driver(&mts_spi_ap2_adc_driver); + break; + + default: + break; + } + } error1: log_error("init failed: %d", ret); @@ -843,12 +973,25 @@ static void __exit mts_io_exit(void) if (has_spi_sout) spi_unregister_driver(&mts_spi_sout_driver); - if (has_accessory_card_port_1) { + if (have_accessory_card_slot_1) { switch (mts_ap1_product_id) { case MTDC_GPIOB_0_0: - spi_unregister_driver(&mts_spi_dc_dout_driver); - spi_unregister_driver(&mts_spi_dc_din_driver); - spi_unregister_driver(&mts_spi_dc_adc_driver); + spi_unregister_driver(&mts_spi_ap1_dout_driver); + spi_unregister_driver(&mts_spi_ap1_din_driver); + spi_unregister_driver(&mts_spi_ap1_adc_driver); + break; + + default: + break; + } + } + + if (have_accessory_card_slot_2) { + switch (mts_ap2_product_id) { + case MTDC_GPIOB_0_0: + spi_unregister_driver(&mts_spi_ap2_dout_driver); + spi_unregister_driver(&mts_spi_ap2_din_driver); + spi_unregister_driver(&mts_spi_ap2_adc_driver); break; default: @@ -877,6 +1020,9 @@ MODULE_ALIAS("mts-io-sout"); MODULE_ALIAS("mts-io-board-temp"); MODULE_ALIAS("mts-io-dout"); MODULE_ALIAS("mts-io-din"); -MODULE_ALIAS("mts-io-dc-dout"); -MODULE_ALIAS("mts-io-dc-din"); -MODULE_ALIAS("mts-io-dc-adc"); +MODULE_ALIAS("mts-io-ap1-dout"); +MODULE_ALIAS("mts-io-ap1-din"); +MODULE_ALIAS("mts-io-ap1-adc"); +MODULE_ALIAS("mts-io-ap2-dout"); +MODULE_ALIAS("mts-io-ap2-din"); +MODULE_ALIAS("mts-io-ap2-adc"); diff --git a/io-module/spi.c b/io-module/spi.c index dfbdfe2..df663ae 100644 --- a/io-module/spi.c +++ b/io-module/spi.c @@ -40,29 +40,32 @@ MODULE_PARM_DESC( "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); +static struct spi_device *spi_ap1_dout_dev; +static struct spi_device *spi_ap2_dout_dev; +static u8 spi_ap_dout_value; +static DEFINE_MUTEX(spi_ap_dout_mutex); +static unsigned int ap_dout_max_speed_hz = 1 * 1000 * 1000; +module_param(ap_dout_max_speed_hz, uint, S_IRUGO); MODULE_PARM_DESC( - dc_dout_max_speed_hz, + ap_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); +static struct spi_device *spi_ap1_din_dev; +static struct spi_device *spi_ap2_din_dev; +static unsigned int ap_din_max_speed_hz = 1 * 1000 * 1000; +module_param(ap_din_max_speed_hz, uint, S_IRUGO); MODULE_PARM_DESC( - dc_din_max_speed_hz, + ap_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); +static struct spi_device *spi_ap1_adc_dev; +static struct spi_device *spi_ap2_adc_dev; +static unsigned int ap_adc_max_speed_hz = 20 * 1000 * 1000; +module_param(ap_adc_max_speed_hz, uint, S_IRUGO); MODULE_PARM_DESC( - dc_adc_max_speed_hz, + ap_adc_max_speed_hz, "Maximum clock rate to be used with this device (default: 20 MHz)" ); @@ -595,137 +598,270 @@ static struct spi_driver mts_spi_din_driver = { .remove = mts_spi_din_remove, }; -static int mts_spi_dc_dout_probe(struct spi_device *spi) +static int mts_spi_ap1_dout_probe(struct spi_device *spi) { int tmp; - if (! has_accessory_card_port_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { - log_error("accessory card digital outputs not available"); + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 1 digital outputs not available"); return -ENODEV; } - spi->max_speed_hz = dc_dout_max_speed_hz; + spi->max_speed_hz = ap_dout_max_speed_hz; spi->mode = 0; - log_debug("dc_dout_max_speed_hz: %d", dc_dout_max_speed_hz); + log_debug("ap1_dout_max_speed_hz: %d", ap_dout_max_speed_hz); tmp = spi_setup(spi); if (tmp < 0) { - log_error("spi_setup dc dout failed"); + log_error("spi_setup accessory card 1 dout failed"); return tmp; } - spi_dc_dout_value = 0x00; - spi_writen(spi, &spi_dc_dout_value, 1); + spi_ap_dout_value = 0x00; + spi_writen(spi, &spi_ap_dout_value, 1); - spi_dc_dout_dev = spi; + spi_ap1_dout_dev = spi; return 0; } -static int mts_spi_dc_dout_remove(struct spi_device *spi) +static int mts_spi_ap1_dout_remove(struct spi_device *spi) { - spi_dc_dout_dev = NULL; + spi_ap1_dout_dev = NULL; return 0; } -static struct spi_driver mts_spi_dc_dout_driver = { +static struct spi_driver mts_spi_ap1_dout_driver = { .driver = { - .name = "mts-io-dc-dout", + .name = "mts-io-ap1-dout", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = mts_spi_dc_dout_probe, - .remove = mts_spi_dc_dout_remove, + .probe = mts_spi_ap1_dout_probe, + .remove = mts_spi_ap1_dout_remove, }; -static int mts_spi_dc_din_probe(struct spi_device *spi) +static int mts_spi_ap1_din_probe(struct spi_device *spi) { int tmp; - if (! has_accessory_card_port_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { - log_error("accessory card digital inputs not available"); + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 1 digital inputs not available"); return -ENODEV; } - spi->max_speed_hz = dc_din_max_speed_hz; + spi->max_speed_hz = ap_din_max_speed_hz; spi->mode = SPI_CPOL; - log_debug("dc_din_max_speed_hz: %d", dc_din_max_speed_hz); + log_debug("ap1_din_max_speed_hz: %d", ap_din_max_speed_hz); tmp = spi_setup(spi); if (tmp < 0) { - log_error("spi_setup daughter card din failed"); + log_error("spi_setup accessory card 1 din failed"); return tmp; } - spi_dc_din_dev = spi; + spi_ap1_din_dev = spi; return 0; } -static int mts_spi_dc_din_remove(struct spi_device *spi) +static int mts_spi_ap1_din_remove(struct spi_device *spi) { - spi_dc_din_dev = NULL; + spi_ap1_din_dev = NULL; return 0; } -static struct spi_driver mts_spi_dc_din_driver = { +static struct spi_driver mts_spi_ap1_din_driver = { .driver = { - .name = "mts-io-dc-din", + .name = "mts-io-ap1-din", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = mts_spi_dc_din_probe, - .remove = mts_spi_dc_din_remove, + .probe = mts_spi_ap1_din_probe, + .remove = mts_spi_ap1_din_remove, }; -static int mts_spi_dc_adc_probe(struct spi_device *spi) +static int mts_spi_ap1_adc_probe(struct spi_device *spi) { int tmp; - if (! has_accessory_card_port_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { - log_error("accessory card analog to digital not available"); + if (! have_accessory_card_slot_1 || mts_ap1_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 1 analog to digital not available"); return -ENODEV; } - spi->max_speed_hz = dc_adc_max_speed_hz; + spi->max_speed_hz = ap_adc_max_speed_hz; spi->mode = 0; - log_debug("dc_adc_max_speed_hz: %d", dc_adc_max_speed_hz); - log_debug("dc_adc_mode: %d", spi->mode); + log_debug("ap1_adc_max_speed_hz: %d", ap_adc_max_speed_hz); + log_debug("ap1_adc_mode: %d", spi->mode); tmp = spi_setup(spi); if (tmp < 0) { - log_error("spi_setup daughter card adc failed"); + log_error("spi_setup accessory card 1 adc failed"); return tmp; } - spi_dc_adc_dev = spi; + spi_ap1_adc_dev = spi; return 0; } -static int mts_spi_dc_adc_remove(struct spi_device *spi) +static int mts_spi_ap1_adc_remove(struct spi_device *spi) { - spi_dc_adc_dev = NULL; + spi_ap1_adc_dev = NULL; return 0; } -static struct spi_driver mts_spi_dc_adc_driver = { +static struct spi_driver mts_spi_ap1_adc_driver = { .driver = { - .name = "mts-io-dc-adc", + .name = "mts-io-ap1-adc", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = mts_spi_dc_adc_probe, - .remove = mts_spi_dc_adc_remove, + .probe = mts_spi_ap1_adc_probe, + .remove = mts_spi_ap1_adc_remove, +}; + +static int mts_spi_ap2_dout_probe(struct spi_device *spi) +{ + int tmp; + + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 2 digital outputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = ap_dout_max_speed_hz; + spi->mode = 0; + + log_debug("ap2_dout_max_speed_hz: %d", ap_dout_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup accessory card 2 dout failed"); + return tmp; + } + + spi_ap_dout_value = 0x00; + spi_writen(spi, &spi_ap_dout_value, 2); + + spi_ap2_dout_dev = spi; + + return 0; +} + +static int mts_spi_ap2_dout_remove(struct spi_device *spi) +{ + spi_ap2_dout_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_ap2_dout_driver = { + .driver = { + .name = "mts-io-ap2-dout", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_ap2_dout_probe, + .remove = mts_spi_ap2_dout_remove, +}; + +static int mts_spi_ap2_din_probe(struct spi_device *spi) +{ + int tmp; + + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 2 digital inputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = ap_din_max_speed_hz; + spi->mode = SPI_CPOL; + + log_debug("ap2_din_max_speed_hz: %d", ap_din_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup accessory card 2 din failed"); + return tmp; + } + + spi_ap2_din_dev = spi; + + return 0; +} + +static int mts_spi_ap2_din_remove(struct spi_device *spi) +{ + spi_ap2_din_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_ap2_din_driver = { + .driver = { + .name = "mts-io-ap2-din", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_ap2_din_probe, + .remove = mts_spi_ap2_din_remove, +}; + +static int mts_spi_ap2_adc_probe(struct spi_device *spi) +{ + int tmp; + + if (! have_accessory_card_slot_2 || mts_ap2_product_id != MTDC_GPIOB_0_0) { + log_error("accessory card 2 analog to digital not available"); + return -ENODEV; + } + + spi->max_speed_hz = ap_adc_max_speed_hz; + spi->mode = 0; + + log_debug("ap2_adc_max_speed_hz: %d", ap_adc_max_speed_hz); + log_debug("ap2_adc_mode: %d", spi->mode); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup accessory card 2 adc failed"); + return tmp; + } + + spi_ap2_adc_dev = spi; + + return 0; +} + +static int mts_spi_ap2_adc_remove(struct spi_device *spi) +{ + spi_ap2_adc_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_ap2_adc_driver = { + .driver = { + .name = "mts-io-ap2-adc", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_ap2_adc_probe, + .remove = mts_spi_ap2_adc_remove, }; static int mts_spi_board_temp_probe(struct spi_device *spi) |