diff options
Diffstat (limited to 'sound/soc/ux500/ux500_msp_i2s.c')
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.c | 88 |
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 */ | ||
30 | static DEFINE_SPINLOCK(msp_rxtx_lock); | ||
31 | |||
32 | /* Protocol desciptors */ | 28 | /* Protocol desciptors */ |
33 | static const struct msp_protdesc prot_descs[] = { | 29 | static const struct msp_protdesc prot_descs[] = { |
34 | { /* I2S */ | 30 | { /* I2S */ |
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp, | |||
356 | 352 | ||
357 | static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) | 353 | static 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 | ||
631 | int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) | 613 | int 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 | ||
776 | MODULE_LICENSE("GPL v2"); | 710 | MODULE_LICENSE("GPL v2"); |