diff --git a/ads1278_core.c b/ads1278_core.c index e47f0c7..c09c62a 100644 --- a/ads1278_core.c +++ b/ads1278_core.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define FRAME_SIZE (24) @@ -19,6 +20,7 @@ struct ads1278 { + struct workqueue_struct *wq; unsigned char *rx; unsigned char *tx; dma_addr_t rx_dma_handle; @@ -29,26 +31,43 @@ struct ads1278 int running[2]; }; -static void ads1278_transfer_callback1(void *context) +static struct spi_device *spip = NULL; +static void ads1278_work_handler(struct work_struct *w) { - struct spi_device *spi = (struct spi_device *)context; - struct ads1278 *ads = spi_get_drvdata(spi); + struct ads1278 *ads; + + if (!spip) + return; + + ads = spi_get_drvdata(spip); - if (!ads->stop_requested) - spi_async(spi, &ads->msg[0]); - else - ads->running[0] = 0; + while (!ads->stop_requested) { + spi_sync_locked(spip, &ads->msg[0]); + } } +static DECLARE_WORK(ads1278_work, ads1278_work_handler); -static void ads1278_transfer_callback2(void *context) +static void ads1278_transfer_callback1(void *context) { - struct spi_device *spi = (struct spi_device *)context; - struct ads1278 *ads = spi_get_drvdata(spi); +// struct spi_device *spi = (struct spi_device *)context; +// struct ads1278 *ads = spi_get_drvdata(spi); +// +// if (!ads->stop_requested) +// queue_work(ads->wq, &ads1278_work); +// //spi_async(spi, &ads->msg[0]); +// else +// ads->running[0] = 0; +} - if (!ads->stop_requested) - spi_async(spi, &ads->msg[1]); - else - ads->running[1] = 0; +static void ads1278_transfer_callback2(void *context) +{ +// struct spi_device *spi = (struct spi_device *)context; +// struct ads1278 *ads = spi_get_drvdata(spi); +// +// if (!ads->stop_requested) +// spi_async(spi, &ads->msg[1]); +// else +// ads->running[1] = 0; } @@ -119,8 +138,16 @@ static int ads1278_begin_transfer(struct spi_device *spi) ads->running[0] = 1; ads->running[1] = 1; - /* TODO ret = */ spi_async(spi, &ads->msg[0]); - return spi_async(spi, &ads->msg[1]); +// /* TODO ret = */ spi_async(spi, &ads->msg[0]); +// return spi_async(spi, &ads->msg[1]); + + ads->wq = create_singlethread_workqueue("ads1278"); + if (ads->wq) { + spip = spi; + queue_work(ads->wq, &ads1278_work); + } + + return 0; } static int ads1278_probe(struct spi_device *spi) @@ -149,6 +176,7 @@ static int ads1278_probe(struct spi_device *spi) dev_info(&spi->dev, "ready to go!"); + spi_bus_lock(spi->controller); if (ads1278_begin_transfer(spi)) { dev_err(&spi->dev, "error with initial transfer!"); goto end_free_ads; @@ -184,9 +212,14 @@ static void ads1278_remove(struct spi_device *spi) dma_free_coherent(&spi->dev, TRANSFER_SIZE * 2, ads->tx, ads->tx_dma_handle); dma_free_coherent(&spi->dev, TRANSFER_SIZE * 2, ads->rx, ads->rx_dma_handle); + flush_scheduled_work(); + if (ads->wq) + destroy_workqueue(ads->wq); + kfree(ads); } + spi_bus_unlock(spi->controller); dev_info(&spi->dev, "done."); }