aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/ux500/ux500_msp_i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/ux500/ux500_msp_i2s.c')
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c88
1 files changed, 11 insertions, 77 deletions
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index f2db6c90a9e2..1ca8b08ae993 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -15,7 +15,6 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/pinctrl/consumer.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/io.h> 20#include <linux/io.h>
@@ -26,9 +25,6 @@
26 25
27#include "ux500_msp_i2s.h" 26#include "ux500_msp_i2s.h"
28 27
29/* MSP1/3 Tx/Rx usage protection */
30static DEFINE_SPINLOCK(msp_rxtx_lock);
31
32 /* Protocol desciptors */ 28 /* Protocol desciptors */
33static const struct msp_protdesc prot_descs[] = { 29static const struct msp_protdesc prot_descs[] = {
34 { /* I2S */ 30 { /* I2S */
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp,
356 352
357static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) 353static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
358{ 354{
359 int status = 0, retval = 0; 355 int status = 0;
360 u32 reg_val_DMACR, reg_val_GCR; 356 u32 reg_val_DMACR, reg_val_GCR;
361 unsigned long flags;
362
363 /* Check msp state whether in RUN or CONFIGURED Mode */
364 if (msp->msp_state == MSP_STATE_IDLE) {
365 spin_lock_irqsave(&msp_rxtx_lock, flags);
366 if (msp->pinctrl_rxtx_ref == 0 &&
367 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) {
368 retval = pinctrl_select_state(msp->pinctrl_p,
369 msp->pinctrl_def);
370 if (retval)
371 pr_err("could not set MSP defstate\n");
372 }
373 if (!retval)
374 msp->pinctrl_rxtx_ref++;
375 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
376 }
377 357
378 /* Configure msp with protocol dependent settings */ 358 /* Configure msp with protocol dependent settings */
379 configure_protocol(msp, config); 359 configure_protocol(msp, config);
@@ -387,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
387 } 367 }
388 368
389 /* Make sure the correct DMA-directions are configured */ 369 /* Make sure the correct DMA-directions are configured */
390 if ((config->direction & MSP_DIR_RX) && (!msp->dma_cfg_rx)) { 370 if ((config->direction & MSP_DIR_RX) &&
371 !msp->capture_dma_data.dma_cfg) {
391 dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!", 372 dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
392 __func__); 373 __func__);
393 return -EINVAL; 374 return -EINVAL;
394 } 375 }
395 if ((config->direction == MSP_DIR_TX) && (!msp->dma_cfg_tx)) { 376 if ((config->direction == MSP_DIR_TX) &&
377 !msp->playback_dma_data.dma_cfg) {
396 dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!", 378 dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
397 __func__); 379 __func__);
398 return -EINVAL; 380 return -EINVAL;
@@ -630,8 +612,7 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
630 612
631int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) 613int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
632{ 614{
633 int status = 0, retval = 0; 615 int status = 0;
634 unsigned long flags;
635 616
636 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); 617 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
637 618
@@ -643,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
643 (~(FRAME_GEN_ENABLE | SRG_ENABLE))), 624 (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
644 msp->registers + MSP_GCR); 625 msp->registers + MSP_GCR);
645 626
646 spin_lock_irqsave(&msp_rxtx_lock, flags);
647 WARN_ON(!msp->pinctrl_rxtx_ref);
648 msp->pinctrl_rxtx_ref--;
649 if (msp->pinctrl_rxtx_ref == 0 &&
650 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) {
651 retval = pinctrl_select_state(msp->pinctrl_p,
652 msp->pinctrl_sleep);
653 if (retval)
654 pr_err("could not set MSP sleepstate\n");
655 }
656 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
657
658 writel(0, msp->registers + MSP_GCR); 627 writel(0, msp->registers + MSP_GCR);
659 writel(0, msp->registers + MSP_TCF); 628 writel(0, msp->registers + MSP_TCF);
660 writel(0, msp->registers + MSP_RCF); 629 writel(0, msp->registers + MSP_RCF);
@@ -682,7 +651,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
682 struct msp_i2s_platform_data *platform_data) 651 struct msp_i2s_platform_data *platform_data)
683{ 652{
684 struct resource *res = NULL; 653 struct resource *res = NULL;
685 struct i2s_controller *i2s_cont;
686 struct device_node *np = pdev->dev.of_node; 654 struct device_node *np = pdev->dev.of_node;
687 struct ux500_msp *msp; 655 struct ux500_msp *msp;
688 656
@@ -707,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
707 675
708 msp->id = platform_data->id; 676 msp->id = platform_data->id;
709 msp->dev = &pdev->dev; 677 msp->dev = &pdev->dev;
710 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; 678 msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
711 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; 679 msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
712 680
713 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 681 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
714 if (res == NULL) { 682 if (res == NULL) {
@@ -717,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
717 return -ENOMEM; 685 return -ENOMEM;
718 } 686 }
719 687
688 msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
689 msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
690
720 msp->registers = devm_ioremap(&pdev->dev, res->start, 691 msp->registers = devm_ioremap(&pdev->dev, res->start,
721 resource_size(res)); 692 resource_size(res));
722 if (msp->registers == NULL) { 693 if (msp->registers == NULL) {
@@ -727,41 +698,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
727 msp->msp_state = MSP_STATE_IDLE; 698 msp->msp_state = MSP_STATE_IDLE;
728 msp->loopback_enable = 0; 699 msp->loopback_enable = 0;
729 700
730 /* I2S-controller is allocated and added in I2S controller class. */
731 i2s_cont = devm_kzalloc(&pdev->dev, sizeof(*i2s_cont), GFP_KERNEL);
732 if (!i2s_cont) {
733 dev_err(&pdev->dev,
734 "%s: ERROR: Failed to allocate I2S-controller!\n",
735 __func__);
736 return -ENOMEM;
737 }
738 i2s_cont->dev.parent = &pdev->dev;
739 i2s_cont->data = (void *)msp;
740 i2s_cont->id = (s16)msp->id;
741 snprintf(i2s_cont->name, sizeof(i2s_cont->name), "ux500-msp-i2s.%04x",
742 msp->id);
743 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
744 msp->i2s_cont = i2s_cont;
745
746 msp->pinctrl_p = pinctrl_get(msp->dev);
747 if (IS_ERR(msp->pinctrl_p))
748 dev_err(&pdev->dev, "could not get MSP pinctrl\n");
749 else {
750 msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p,
751 PINCTRL_STATE_DEFAULT);
752 if (IS_ERR(msp->pinctrl_def)) {
753 dev_err(&pdev->dev,
754 "could not get MSP defstate (%li)\n",
755 PTR_ERR(msp->pinctrl_def));
756 }
757 msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p,
758 PINCTRL_STATE_SLEEP);
759 if (IS_ERR(msp->pinctrl_sleep))
760 dev_err(&pdev->dev,
761 "could not get MSP idlestate (%li)\n",
762 PTR_ERR(msp->pinctrl_def));
763 }
764
765 return 0; 701 return 0;
766} 702}
767 703
@@ -769,8 +705,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
769 struct ux500_msp *msp) 705 struct ux500_msp *msp)
770{ 706{
771 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); 707 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
772
773 device_unregister(&msp->i2s_cont->dev);
774} 708}
775 709
776MODULE_LICENSE("GPL v2"); 710MODULE_LICENSE("GPL v2");