diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-08-13 12:12:31 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-08-13 12:12:31 +0200 |
commit | f5b6c1fcb42fe7d6f2f6eb2220512e2a5f875133 (patch) | |
tree | 325f29d9788e80a0dd66d907ce38650834060e4b /sound/soc/uniphier/aio-core.c | |
parent | 73b383141d296c55bfbc0ce336a4a946627e7780 (diff) | |
parent | 4aa5db22d35588e1a5d2ee88472348ea73d9fb23 (diff) |
Merge tag 'asoc-v4.19' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.19
A fairly big update, including quite a bit of core activity this time
around (which is good to see) along with a fairly large set of new
drivers.
- A new snd_pcm_stop_xrun() helper which is now used in several
drivers.
- Support for providing name prefixes to generic component nodes.
- Quite a few fixes for DPCM as it gains a bit wider use and more
robust testing.
- Generalization of the DIO2125 support to a simple amplifier driver.
- Accessory detection support for the audio graph card.
- DT support for PXA AC'97 devices.
- Quirks for a number of new x86 systems.
- Support for AM Logic Meson, Everest ES7154, Intel systems with
RT5682, Qualcomm QDSP6 and WCD9335, Realtek RT5682 and TI TAS5707.
Diffstat (limited to 'sound/soc/uniphier/aio-core.c')
-rw-r--r-- | sound/soc/uniphier/aio-core.c | 84 |
1 files changed, 76 insertions, 8 deletions
diff --git a/sound/soc/uniphier/aio-core.c b/sound/soc/uniphier/aio-core.c index 638cb3fc5f7b..9bcba06ba52e 100644 --- a/sound/soc/uniphier/aio-core.c +++ b/sound/soc/uniphier/aio-core.c @@ -265,6 +265,57 @@ void aio_port_reset(struct uniphier_aio_sub *sub) } /** + * aio_port_set_ch - set channels of LPCM + * @sub: the AIO substream pointer, PCM substream only + * @ch : count of channels + * + * Set suitable slot selecting to input/output port block of AIO. + * + * This function may return error if non-PCM substream. + * + * Return: Zero if successful, otherwise a negative value on error. + */ +static int aio_port_set_ch(struct uniphier_aio_sub *sub) +{ + struct regmap *r = sub->aio->chip->regmap; + u32 slotsel_2ch[] = { + 0, 0, 0, 0, 0, + }; + u32 slotsel_multi[] = { + OPORTMXTYSLOTCTR_SLOTSEL_SLOT0, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT1, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT2, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT3, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT4, + }; + u32 mode, *slotsel; + int i; + + switch (params_channels(&sub->params)) { + case 8: + case 6: + mode = OPORTMXTYSLOTCTR_MODE; + slotsel = slotsel_multi; + break; + case 2: + mode = 0; + slotsel = slotsel_2ch; + break; + default: + return -EINVAL; + } + + for (i = 0; i < AUD_MAX_SLOTSEL; i++) { + regmap_update_bits(r, OPORTMXTYSLOTCTR(sub->swm->oport.map, i), + OPORTMXTYSLOTCTR_MODE, mode); + regmap_update_bits(r, OPORTMXTYSLOTCTR(sub->swm->oport.map, i), + OPORTMXTYSLOTCTR_SLOTSEL_MASK, slotsel[i]); + } + + return 0; +} + +/** * aio_port_set_rate - set sampling rate of LPCM * @sub: the AIO substream pointer, PCM substream only * @rate: Sampling rate in Hz. @@ -276,7 +327,7 @@ void aio_port_reset(struct uniphier_aio_sub *sub) * * Return: Zero if successful, otherwise a negative value on error. */ -int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate) +static int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate) { struct regmap *r = sub->aio->chip->regmap; struct device *dev = &sub->aio->chip->pdev->dev; @@ -395,7 +446,7 @@ int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate) * * Return: Zero if successful, otherwise a negative value on error. */ -int aio_port_set_fmt(struct uniphier_aio_sub *sub) +static int aio_port_set_fmt(struct uniphier_aio_sub *sub) { struct regmap *r = sub->aio->chip->regmap; struct device *dev = &sub->aio->chip->pdev->dev; @@ -460,7 +511,7 @@ int aio_port_set_fmt(struct uniphier_aio_sub *sub) * * Return: Zero if successful, otherwise a negative value on error. */ -int aio_port_set_clk(struct uniphier_aio_sub *sub) +static int aio_port_set_clk(struct uniphier_aio_sub *sub) { struct uniphier_aio_chip *chip = sub->aio->chip; struct device *dev = &sub->aio->chip->pdev->dev; @@ -575,6 +626,10 @@ int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through, rate = params_rate(params); } + ret = aio_port_set_ch(sub); + if (ret) + return ret; + ret = aio_port_set_rate(sub, rate); if (ret) return ret; @@ -731,15 +786,28 @@ void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol) int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through) { struct regmap *r = sub->aio->chip->regmap; - u32 v; + u32 memfmt, v; if (sub->swm->dir == PORT_DIR_OUTPUT) { - if (pass_through) + if (pass_through) { v = PBOUTMXCTR0_ENDIAN_0123 | PBOUTMXCTR0_MEMFMT_STREAM; - else - v = PBOUTMXCTR0_ENDIAN_3210 | - PBOUTMXCTR0_MEMFMT_2CH; + } else { + switch (params_channels(&sub->params)) { + case 2: + memfmt = PBOUTMXCTR0_MEMFMT_2CH; + break; + case 6: + memfmt = PBOUTMXCTR0_MEMFMT_6CH; + break; + case 8: + memfmt = PBOUTMXCTR0_MEMFMT_8CH; + break; + default: + return -EINVAL; + } + v = PBOUTMXCTR0_ENDIAN_3210 | memfmt; + } regmap_write(r, PBOUTMXCTR0(sub->swm->oif.map), v); regmap_write(r, PBOUTMXCTR1(sub->swm->oif.map), 0); |