diff options
author | Lee Jones <lee.jones@linaro.org> | 2012-09-14 11:16:08 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2012-09-20 03:10:56 -0400 |
commit | 5ca032ee21cdabd08fb368ce3f02fa8906b0ef5f (patch) | |
tree | e77e91004f3e7608c0d6d0e2932fbb5e7881d808 /sound | |
parent | 5698bd757d55b1bb87edd1a9744ab09c142abfc2 (diff) |
ASoC: Ux500: Move MSP pinctrl setup into the MSP driver
In the initial submission of the MSP driver msp1 and msp3's associated
pinctrl mechanism was passed back to platform code using a plat_init()
call-back routine, but it has no place in platform code. The MSP driver
should set this up for the appropriate ports. Instead we use a use_pinctrl
identifier which is passed from platform_data/Device Tree which indicates
which ports should use pinctrl.
Acked-by: Ola Lilja <ola.o.lilja@stericsson.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.c | 67 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.h | 8 |
2 files changed, 57 insertions, 18 deletions
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index eb85113d472a..12d7f567420d 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c | |||
@@ -15,6 +15,7 @@ | |||
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> | ||
18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
20 | 21 | ||
@@ -25,6 +26,9 @@ | |||
25 | 26 | ||
26 | #include "ux500_msp_i2s.h" | 27 | #include "ux500_msp_i2s.h" |
27 | 28 | ||
29 | /* MSP1/3 Tx/Rx usage protection */ | ||
30 | static DEFINE_SPINLOCK(msp_rxtx_lock); | ||
31 | |||
28 | /* Protocol desciptors */ | 32 | /* Protocol desciptors */ |
29 | static const struct msp_protdesc prot_descs[] = { | 33 | static const struct msp_protdesc prot_descs[] = { |
30 | { /* I2S */ | 34 | { /* I2S */ |
@@ -352,17 +356,23 @@ static int configure_multichannel(struct ux500_msp *msp, | |||
352 | 356 | ||
353 | static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) | 357 | static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) |
354 | { | 358 | { |
355 | int status = 0; | 359 | int status = 0, retval = 0; |
356 | u32 reg_val_DMACR, reg_val_GCR; | 360 | u32 reg_val_DMACR, reg_val_GCR; |
361 | unsigned long flags; | ||
357 | 362 | ||
358 | /* Check msp state whether in RUN or CONFIGURED Mode */ | 363 | /* Check msp state whether in RUN or CONFIGURED Mode */ |
359 | if ((msp->msp_state == MSP_STATE_IDLE) && (msp->plat_init)) { | 364 | if (msp->msp_state == MSP_STATE_IDLE) { |
360 | status = msp->plat_init(); | 365 | spin_lock_irqsave(&msp_rxtx_lock, flags); |
361 | if (status) { | 366 | if (msp->pinctrl_rxtx_ref == 0 && |
362 | dev_err(msp->dev, "%s: ERROR: Failed to init MSP (%d)!\n", | 367 | !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) { |
363 | __func__, status); | 368 | retval = pinctrl_select_state(msp->pinctrl_p, |
364 | return status; | 369 | msp->pinctrl_def); |
370 | if (retval) | ||
371 | pr_err("could not set MSP defstate\n"); | ||
365 | } | 372 | } |
373 | if (!retval) | ||
374 | msp->pinctrl_rxtx_ref++; | ||
375 | spin_unlock_irqrestore(&msp_rxtx_lock, flags); | ||
366 | } | 376 | } |
367 | 377 | ||
368 | /* Configure msp with protocol dependent settings */ | 378 | /* Configure msp with protocol dependent settings */ |
@@ -620,7 +630,8 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction) | |||
620 | 630 | ||
621 | int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) | 631 | int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) |
622 | { | 632 | { |
623 | int status = 0; | 633 | int status = 0, retval = 0; |
634 | unsigned long flags; | ||
624 | 635 | ||
625 | dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); | 636 | dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); |
626 | 637 | ||
@@ -631,12 +642,19 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) | |||
631 | writel((readl(msp->registers + MSP_GCR) & | 642 | writel((readl(msp->registers + MSP_GCR) & |
632 | (~(FRAME_GEN_ENABLE | SRG_ENABLE))), | 643 | (~(FRAME_GEN_ENABLE | SRG_ENABLE))), |
633 | msp->registers + MSP_GCR); | 644 | msp->registers + MSP_GCR); |
634 | if (msp->plat_exit) | 645 | |
635 | status = msp->plat_exit(); | 646 | spin_lock_irqsave(&msp_rxtx_lock, flags); |
636 | if (status) | 647 | WARN_ON(!msp->pinctrl_rxtx_ref); |
637 | dev_warn(msp->dev, | 648 | msp->pinctrl_rxtx_ref--; |
638 | "%s: WARN: ux500_msp_i2s_exit failed (%d)!\n", | 649 | if (msp->pinctrl_rxtx_ref == 0 && |
639 | __func__, status); | 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 | |||
640 | writel(0, msp->registers + MSP_GCR); | 658 | writel(0, msp->registers + MSP_GCR); |
641 | writel(0, msp->registers + MSP_TCF); | 659 | writel(0, msp->registers + MSP_TCF); |
642 | writel(0, msp->registers + MSP_RCF); | 660 | writel(0, msp->registers + MSP_RCF); |
@@ -675,8 +693,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
675 | 693 | ||
676 | msp->id = platform_data->id; | 694 | msp->id = platform_data->id; |
677 | msp->dev = &pdev->dev; | 695 | msp->dev = &pdev->dev; |
678 | msp->plat_init = platform_data->msp_i2s_init; | ||
679 | msp->plat_exit = platform_data->msp_i2s_exit; | ||
680 | msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; | 696 | msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; |
681 | msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; | 697 | msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; |
682 | 698 | ||
@@ -713,6 +729,25 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
713 | dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); | 729 | dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); |
714 | msp->i2s_cont = i2s_cont; | 730 | msp->i2s_cont = i2s_cont; |
715 | 731 | ||
732 | msp->pinctrl_p = pinctrl_get(msp->dev); | ||
733 | if (IS_ERR(msp->pinctrl_p)) | ||
734 | dev_err(&pdev->dev, "could not get MSP pinctrl\n"); | ||
735 | else { | ||
736 | msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p, | ||
737 | PINCTRL_STATE_DEFAULT); | ||
738 | if (IS_ERR(msp->pinctrl_def)) { | ||
739 | dev_err(&pdev->dev, | ||
740 | "could not get MSP defstate (%li)\n", | ||
741 | PTR_ERR(msp->pinctrl_def)); | ||
742 | } | ||
743 | msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p, | ||
744 | PINCTRL_STATE_SLEEP); | ||
745 | if (IS_ERR(msp->pinctrl_sleep)) | ||
746 | dev_err(&pdev->dev, | ||
747 | "could not get MSP idlestate (%li)\n", | ||
748 | PTR_ERR(msp->pinctrl_def)); | ||
749 | } | ||
750 | |||
716 | return 0; | 751 | return 0; |
717 | } | 752 | } |
718 | 753 | ||
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 2d9136da9865..1311c0df7628 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -524,14 +524,18 @@ struct ux500_msp { | |||
524 | struct dma_chan *rx_pipeid; | 524 | struct dma_chan *rx_pipeid; |
525 | enum msp_state msp_state; | 525 | enum msp_state msp_state; |
526 | int (*transfer) (struct ux500_msp *msp, struct i2s_message *message); | 526 | int (*transfer) (struct ux500_msp *msp, struct i2s_message *message); |
527 | int (*plat_init) (void); | ||
528 | int (*plat_exit) (void); | ||
529 | struct timer_list notify_timer; | 527 | struct timer_list notify_timer; |
530 | int def_elem_len; | 528 | int def_elem_len; |
531 | unsigned int dir_busy; | 529 | unsigned int dir_busy; |
532 | int loopback_enable; | 530 | int loopback_enable; |
533 | u32 backup_regs[MAX_MSP_BACKUP_REGS]; | 531 | u32 backup_regs[MAX_MSP_BACKUP_REGS]; |
534 | unsigned int f_bitclk; | 532 | unsigned int f_bitclk; |
533 | /* Pin modes */ | ||
534 | struct pinctrl *pinctrl_p; | ||
535 | struct pinctrl_state *pinctrl_def; | ||
536 | struct pinctrl_state *pinctrl_sleep; | ||
537 | /* Reference Count */ | ||
538 | int pinctrl_rxtx_ref; | ||
535 | }; | 539 | }; |
536 | 540 | ||
537 | struct ux500_msp_dma_params { | 541 | struct ux500_msp_dma_params { |