diff options
Diffstat (limited to 'io-module/spi.c')
-rw-r--r-- | io-module/spi.c | 767 |
1 files changed, 767 insertions, 0 deletions
diff --git a/io-module/spi.c b/io-module/spi.c new file mode 100644 index 0000000..2da3f05 --- /dev/null +++ b/io-module/spi.c @@ -0,0 +1,767 @@ +/* SPI devices, functions, and attributes */ + +static int ADT7302_to_celsius(int value) +{ + if (value & 0x2000) { + value = value - 16384; + } + + value = value / 32 + 1 * ((value % 32) >= 16); + + return value; +} + +/* SPI Devices */ +static struct spi_device *spi_sout_dev; +static u8 spi_sout_value; +static DEFINE_MUTEX(spi_sout_mutex); +static unsigned int sout_max_speed_hz = 1 * 1000 * 1000; +module_param(sout_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + sout_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +static struct spi_device *spi_dout_dev; +static u8 spi_dout_value; +static DEFINE_MUTEX(spi_dout_mutex); +static unsigned int dout_max_speed_hz = 1 * 1000 * 1000; +module_param(dout_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + dout_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +static struct spi_device *spi_din_dev; +static unsigned int din_max_speed_hz = 1 * 1000 * 1000; +module_param(din_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + din_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +static struct spi_device *spi_dc_dout_dev; +static u8 spi_dc_dout_value; +static DEFINE_MUTEX(spi_dc_dout_mutex); +static unsigned int dc_dout_max_speed_hz = 1 * 1000 * 1000; +module_param(dc_dout_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + dc_dout_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +static struct spi_device *spi_dc_din_dev; +static unsigned int dc_din_max_speed_hz = 1 * 1000 * 1000; +module_param(dc_din_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + dc_din_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +static struct spi_device *spi_dc_adc_dev; +static unsigned int dc_adc_max_speed_hz = 20 * 1000 * 1000; +module_param(dc_adc_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + dc_adc_max_speed_hz, + "Maximum clock rate to be used with this device (default: 20 MHz)" +); + +static struct spi_device *spi_board_temp_dev; +static unsigned int board_temp_max_speed_hz = 1 * 1000 * 1000; +module_param(board_temp_max_speed_hz, uint, S_IRUGO); +MODULE_PARM_DESC( + board_temp_max_speed_hz, + "Maximum clock rate to be used with this device (default: 1 MHz)" +); + +/* Generic SPI functions */ +static inline int spi_writen(struct spi_device *spi, const u8 *buf, size_t len) +{ + int tmp; + u8 *tx; + + tx = kmalloc(len, GFP_KERNEL); + if (!tx) { + return -ENOMEM; + } + + memcpy(tx, buf, len); + tmp = spi_write(spi, tx, len); + + kfree(tx); + + return tmp; +} + +static inline int spi_readn(struct spi_device *spi, u8 *buf, size_t len) +{ + int tmp; + u8 *rx; + + rx = kmalloc(len, GFP_KERNEL); + if (!rx) { + return -ENOMEM; + } + + tmp = spi_read(spi, rx, len); + memcpy(buf, rx, len); + + kfree(rx); + + return tmp; +} + +/* ---------------------------------------------------------------------------- + * + * SPI-based attribute show/store functions + * + * ---------------------------------------------------------------------------- +*/ + +#define SOUT_LED_CD_BIT BIT(0) +#define SOUT_EXTSERIAL_RI_BIT BIT(1) +#define SOUT_EXTSERIAL_DSR_BIT BIT(2) +#define SOUT_LED_DTR BIT(3) +#define SOUT_LED_SIG1_BIT BIT(4) +#define SOUT_LED_SIG2_BIT BIT(5) +#define SOUT_LED_SIG3_BIT BIT(6) +#define SOUT_EXTSERIAL_DCD_BIT BIT(7) + +static ssize_t mts_attr_store_sout(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + u8 bit; + + if (!spi_sout_dev) { + log_notice("sout device not present"); + return -ENODEV; + } + + if (!strcmp(attr->attr.name, "extserial-ri")) { + bit = SOUT_EXTSERIAL_RI_BIT; + } else if (!strcmp(attr->attr.name, "extserial-dsr")) { + bit = SOUT_EXTSERIAL_DSR_BIT; + } else if (!strcmp(attr->attr.name, "extserial-dcd")) { + bit = SOUT_EXTSERIAL_DCD_BIT; + } else if (!strcmp(attr->attr.name, "led-cd") || + !strcmp(attr->attr.name, "led-sdk-b")) { + bit = SOUT_LED_CD_BIT; + } else if (!strcmp(attr->attr.name, "led-dtr") || + !strcmp(attr->attr.name, "led-sdk-f")) { + bit = SOUT_LED_DTR; + } else if (!strcmp(attr->attr.name, "led-sig1") || + !strcmp(attr->attr.name, "led-sdk-c")) { + bit = SOUT_LED_SIG1_BIT; + } else if (!strcmp(attr->attr.name, "led-sig2") || + !strcmp(attr->attr.name, "led-sdk-d")) { + bit = SOUT_LED_SIG2_BIT; + } else if (!strcmp(attr->attr.name, "led-sig3") || + !strcmp(attr->attr.name, "led-sdk-e")) { + bit = SOUT_LED_SIG3_BIT; + } else { + log_notice("sout attr does not exist"); + return -ENOENT; + } + + if (sscanf(buf, "%i", &value) != 1) { + log_notice("sout attr invalid argument"); + return -EINVAL; + } + + mutex_lock(&spi_sout_mutex); + + if (value) { + spi_sout_value &= ~bit; + } else { + spi_sout_value |= bit; + } + spi_writen(spi_sout_dev, &spi_sout_value, 1); + + mutex_unlock(&spi_sout_mutex); + + return count; +} + +static ssize_t mts_attr_show_sout(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int value; + u8 bit; + + if (!spi_sout_dev) { + log_error("sout device not present"); + return -ENODEV; + } + + if (!strcmp(attr->attr.name, "extserial-ri")) { + bit = SOUT_EXTSERIAL_RI_BIT; + } else if (!strcmp(attr->attr.name, "extserial-dsr")) { + bit = SOUT_EXTSERIAL_DSR_BIT; + } else if (!strcmp(attr->attr.name, "extserial-dcd")) { + bit = SOUT_EXTSERIAL_DCD_BIT; + } else if (!strcmp(attr->attr.name, "led-cd") || + !strcmp(attr->attr.name, "led-sdk-b")) { + bit = SOUT_LED_CD_BIT; + } else if (!strcmp(attr->attr.name, "led-dtr") || + !strcmp(attr->attr.name, "led-sdk-f")) { + bit = SOUT_LED_DTR; + } else if (!strcmp(attr->attr.name, "led-sig1") || + !strcmp(attr->attr.name, "led-sdk-c")) { + bit = SOUT_LED_SIG1_BIT; + } else if (!strcmp(attr->attr.name, "led-sig2") || + !strcmp(attr->attr.name, "led-sdk-d")) { + bit = SOUT_LED_SIG2_BIT; + } else if (!strcmp(attr->attr.name, "led-sig3") || + !strcmp(attr->attr.name, "led-sdk-e")) { + bit = SOUT_LED_SIG3_BIT; + } else { + log_notice("sout attr does not exist"); + return -ENOENT; + } + + mutex_lock(&spi_sout_mutex); + + value = spi_sout_value & bit ? 0 : 1; + + mutex_unlock(&spi_sout_mutex); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t mts_attr_store_dout(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + u8 bit; + + if (!spi_dout_dev) { + log_notice("dout device not present"); + return -ENODEV; + } + + if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) { + bit = BIT(0); + } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) { + bit = BIT(1); + } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) { + bit = BIT(2); + } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) { + bit = BIT(3); + } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) { + bit = BIT(4); + } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) { + bit = BIT(5); + } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) { + bit = BIT(6); + } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) { + bit = BIT(7); + } else { + log_notice("dout attr does not exist"); + return -ENOENT; + } + + if (sscanf(buf, "%i", &value) != 1) { + log_notice("dout attr invalid argument"); + return -EINVAL; + } + + mutex_lock(&spi_dout_mutex); + + if (value) { + spi_dout_value &= ~bit; + } else { + spi_dout_value |= bit; + } + + spi_writen(spi_dout_dev, &spi_dout_value, 1); + + mutex_unlock(&spi_dout_mutex); + + return count; +} + +static ssize_t mts_attr_show_dout(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int value; + u8 bit; + + if (!spi_dout_dev) { + log_error("dout device not present"); + return -ENODEV; + } + + if ((!strcmp(attr->attr.name, "dout0")) || (!strcmp(attr->attr.name, "gpo1"))) { + bit = BIT(0); + } else if ((!strcmp(attr->attr.name, "dout1")) || (!strcmp(attr->attr.name, "gpo2"))) { + bit = BIT(1); + } else if ((!strcmp(attr->attr.name, "dout2")) || (!strcmp(attr->attr.name, "gpo3"))) { + bit = BIT(2); + } else if ((!strcmp(attr->attr.name, "dout3")) || (!strcmp(attr->attr.name, "gpo4"))) { + bit = BIT(3); + } else if ((!strcmp(attr->attr.name, "dout4")) || (!strcmp(attr->attr.name, "led1"))) { + bit = BIT(4); + } else if ((!strcmp(attr->attr.name, "dout5")) || (!strcmp(attr->attr.name, "led4"))) { + bit = BIT(5); + } else if ((!strcmp(attr->attr.name, "dout6")) || (!strcmp(attr->attr.name, "led5"))) { + bit = BIT(6); + } else if ((!strcmp(attr->attr.name, "dout7")) || (!strcmp(attr->attr.name, "led6"))) { + bit = BIT(7); + } else { + log_notice("dout attr does not exist"); + return -ENOENT; + } + + mutex_lock(&spi_dout_mutex); + + value = spi_dout_value & bit ? 0 : 1; + + mutex_unlock(&spi_dout_mutex); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t mts_attr_show_din(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int tmp; + u8 bit; + u8 byte; + + if (!spi_din_dev) { + log_error("din device not present"); + return -ENODEV; + } + + if ((!strcmp(attr->attr.name, "din0")) || (!strcmp(attr->attr.name, "gpi5"))) { + bit = BIT(0); + } else if ((!strcmp(attr->attr.name, "din1")) || (!strcmp(attr->attr.name, "gpi6"))) { + bit = BIT(1); + } else if ((!strcmp(attr->attr.name, "din2")) || (!strcmp(attr->attr.name, "gpi7"))) { + bit = BIT(2); + } else if ((!strcmp(attr->attr.name, "din3")) || (!strcmp(attr->attr.name, "gpi8"))) { + bit = BIT(3); + } else if ((!strcmp(attr->attr.name, "din4")) || (!strcmp(attr->attr.name, "gpi9"))) { + bit = BIT(4); + } else if ((!strcmp(attr->attr.name, "din5")) || (!strcmp(attr->attr.name, "gpi10"))) { + bit = BIT(5); + } else if (!strcmp(attr->attr.name, "din6")) { + bit = BIT(6); + } else if (!strcmp(attr->attr.name, "din7")) { + bit = BIT(7); + } else { + log_notice("din attr does not exist"); + return -ENOENT; + } + + tmp = spi_readn(spi_din_dev, &byte, 1); + if (tmp) { + log_error("spi_read failed %d", tmp); + return tmp; + } + + tmp = byte & bit ? 1 : 0; + + return sprintf(buf, "%d\n", tmp); +} + +static ssize_t mts_attr_show_board_temperature(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int tmp; + u16 temp_raw; + + if (!spi_board_temp_dev) { + log_notice("spi_board_temp device not present"); + return -ENODEV; + } + + tmp = spi_readn(spi_board_temp_dev, (u8 *) buf, 2); + if (tmp) { + log_error("spi_readn failed %d", tmp); + return tmp; + } + temp_raw = ((u8 *) buf)[0] << 8 | ((u8 *) buf)[1]; + + log_debug("temp: 0x%04X", temp_raw); + + return sprintf(buf, "%d\n", ADT7302_to_celsius(temp_raw)); +} + +/* ---------------------------------------------------------------------------- + * + * SPI-based attributes + * + * ---------------------------------------------------------------------------- +*/ + +static DEVICE_ATTR_RO_MTS(dev_attr_board_temperature, "board-temperature", + mts_attr_show_board_temperature); + +static DEVICE_ATTR_MTS(dev_attr_extserial_dcd, "extserial-dcd", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_extserial_ri, "extserial-ri", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_extserial_dsr, "extserial-dsr", + mts_attr_show_sout, mts_attr_store_sout); + +static DEVICE_ATTR_MTS(dev_attr_led_cd, "led-cd", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sdk_b, "led-sdk-b", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sig1, "led-sig1", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sdk_c, "led-sdk-c", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sig2, "led-sig2", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sdk_d, "led-sdk-d", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sig3, "led-sig3", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sdk_e, "led-sdk-e", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_dtr, "led-dtr", + mts_attr_show_sout, mts_attr_store_sout); +static DEVICE_ATTR_MTS(dev_attr_led_sdk_f, "led-sdk-f", + mts_attr_show_sout, mts_attr_store_sout); + +static DEVICE_ATTR_MTS(dev_attr_dout0, "dout0", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_dout1, "dout1", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_dout2, "dout2", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_dout3, "dout3", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_dout4, "dout4", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_dout5, "dout5", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_dout6, "dout6", + mts_attr_show_dout, mts_attr_store_dout); +static DEVICE_ATTR_MTS(dev_attr_dout7, "dout7", + mts_attr_show_dout, mts_attr_store_dout); + +static DEVICE_ATTR_RO_MTS(dev_attr_din0, "din0", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_din1, "din1", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_din2, "din2", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_din3, "din3", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_din4, "din4", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_din5, "din5", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_din6, "din6", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_din7, "din7", mts_attr_show_din); + +static DEVICE_ATTR_RO_MTS(dev_attr_gpi5, "gpi5", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_gpi6, "gpi6", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_gpi7, "gpi7", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_gpi8, "gpi8", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_gpi9, "gpi9", mts_attr_show_din); +static DEVICE_ATTR_RO_MTS(dev_attr_gpi10, "gpi10", mts_attr_show_din); + +/* SPI driver setup */ +static int mts_spi_sout_probe(struct spi_device *spi) +{ + int tmp; + + spi->max_speed_hz = sout_max_speed_hz; + spi->mode = 0; + + log_debug("sout_max_speed_hz: %d", sout_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup sout failed"); + return tmp; + } + + spi_sout_value = 0xFF; + spi_writen(spi, &spi_sout_value, 1); + + spi_sout_dev = spi; + + return 0; +} + +static int mts_spi_sout_remove(struct spi_device *spi) +{ + spi_sout_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_sout_driver = { + .driver = { + .name = "mts-io-sout", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_sout_probe, + .remove = mts_spi_sout_remove, +}; + +static int mts_spi_dout_probe(struct spi_device *spi) +{ + int tmp; + + if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DOUT)) { + log_debug("digital outputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = dout_max_speed_hz; + spi->mode = 0; + + log_debug("dout_max_speed_hz: %d", dout_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup dout failed"); + return tmp; + } + + spi_dout_value = 0x00; + spi_writen(spi, &spi_dout_value, 1); + + spi_dout_dev = spi; + + return 0; +} + +static int mts_spi_dout_remove(struct spi_device *spi) +{ + spi_dout_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_dout_driver = { + .driver = { + .name = "mts-io-dout", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_dout_probe, + .remove = mts_spi_dout_remove, +}; + +static int mts_spi_din_probe(struct spi_device *spi) +{ + int tmp; + + if (!DEVICE_CAPA(id_eeprom.capa, CAPA_DIN)) { + log_debug("digital inputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = din_max_speed_hz; + spi->mode = SPI_CPOL; + + log_debug("din_max_speed_hz: %d", din_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup din failed"); + return tmp; + } + + spi_din_dev = spi; + + return 0; +} + +static int mts_spi_din_remove(struct spi_device *spi) +{ + spi_din_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_din_driver = { + .driver = { + .name = "mts-io-din", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_din_probe, + .remove = mts_spi_din_remove, +}; + +static int mts_spi_dc_dout_probe(struct spi_device *spi) +{ + int tmp; + + if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) { + log_error("daughter card digital outputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = dc_dout_max_speed_hz; + spi->mode = 0; + + log_debug("dc_dout_max_speed_hz: %d", dc_dout_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup dc dout failed"); + return tmp; + } + + spi_dc_dout_value = 0x00; + spi_writen(spi, &spi_dc_dout_value, 1); + + spi_dc_dout_dev = spi; + + return 0; +} + +static int mts_spi_dc_dout_remove(struct spi_device *spi) +{ + spi_dc_dout_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_dc_dout_driver = { + .driver = { + .name = "mts-io-dc-dout", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_dc_dout_probe, + .remove = mts_spi_dc_dout_remove, +}; + +static int mts_spi_dc_din_probe(struct spi_device *spi) +{ + int tmp; + + if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) { + log_error("daughter card digital inputs not available"); + return -ENODEV; + } + + spi->max_speed_hz = dc_din_max_speed_hz; + spi->mode = SPI_CPOL; + + log_debug("dc_din_max_speed_hz: %d", dc_din_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup daughter card din failed"); + return tmp; + } + + spi_dc_din_dev = spi; + + return 0; +} + +static int mts_spi_dc_din_remove(struct spi_device *spi) +{ + spi_dc_din_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_dc_din_driver = { + .driver = { + .name = "mts-io-dc-din", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_dc_din_probe, + .remove = mts_spi_dc_din_remove, +}; + +static int mts_spi_dc_adc_probe(struct spi_device *spi) +{ + int tmp; + + if (! has_daughter_card || mts_dc_product_id != MTDC_GPIOB_0_0) { + log_error("daughter card analog to digital not available"); + return -ENODEV; + } + + spi->max_speed_hz = dc_adc_max_speed_hz; + spi->mode = 0; + + log_debug("dc_adc_max_speed_hz: %d", dc_adc_max_speed_hz); + log_debug("dc_adc_mode: %d", spi->mode); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup daughter card adc failed"); + return tmp; + } + + spi_dc_adc_dev = spi; + + return 0; +} + +static int mts_spi_dc_adc_remove(struct spi_device *spi) +{ + spi_dc_adc_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_dc_adc_driver = { + .driver = { + .name = "mts-io-dc-adc", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_dc_adc_probe, + .remove = mts_spi_dc_adc_remove, +}; + +static int mts_spi_board_temp_probe(struct spi_device *spi) +{ + int tmp; + + spi->max_speed_hz = board_temp_max_speed_hz; + spi->mode = SPI_CPOL | SPI_CPHA; + + log_debug("board_temp_max_speed_hz: %d", board_temp_max_speed_hz); + + tmp = spi_setup(spi); + if (tmp < 0) { + log_error("spi_setup board-temp failed"); + return tmp; + } + + spi_board_temp_dev = spi; + + return 0; +} + +static int mts_spi_board_temp_remove(struct spi_device *spi) +{ + spi_board_temp_dev = NULL; + + return 0; +} + +static struct spi_driver mts_spi_board_temp_driver = { + .driver = { + .name = "mts-io-board-temp", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = mts_spi_board_temp_probe, + .remove = mts_spi_board_temp_remove, +}; |