brintos

brintos / linux-shallow public Read only

0
0
Text · 31.3 KiB · 6d1ce03 Raw
1150 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) STMicroelectronics SA 20154 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>5 *          for STMicroelectronics.6 */7 8#include <linux/clk.h>9#include <linux/mfd/syscon.h>10 11#include <sound/asoundef.h>12#include <sound/soc.h>13 14#include "uniperif.h"15 16/*17 * Some hardware-related definitions18 */19 20/* sys config registers definitions */21#define SYS_CFG_AUDIO_GLUE 0xA422 23/*24 * Driver specific types.25 */26 27#define UNIPERIF_PLAYER_CLK_ADJ_MIN  -99999928#define UNIPERIF_PLAYER_CLK_ADJ_MAX  100000029#define UNIPERIF_PLAYER_I2S_OUT 1 /* player id connected to I2S/TDM TX bus */30 31/*32 * Note: snd_pcm_hardware is linked to DMA controller but is declared here to33 * integrate  DAI_CPU capability in term of rate and supported channels34 */35static const struct snd_pcm_hardware uni_player_pcm_hw = {36	.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |37		SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |38		SNDRV_PCM_INFO_MMAP_VALID,39	.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,40 41	.rates = SNDRV_PCM_RATE_CONTINUOUS,42	.rate_min = 8000,43	.rate_max = 192000,44 45	.channels_min = 2,46	.channels_max = 8,47 48	.periods_min = 2,49	.periods_max = 48,50 51	.period_bytes_min = 128,52	.period_bytes_max = 64 * PAGE_SIZE,53	.buffer_bytes_max = 256 * PAGE_SIZE54};55 56/*57 * uni_player_irq_handler58 * In case of error audio stream is stopped; stop action is protected via PCM59 * stream lock to avoid race condition with trigger callback.60 */61static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)62{63	irqreturn_t ret = IRQ_NONE;64	struct uniperif *player = dev_id;65	unsigned int status;66	unsigned int tmp;67 68	spin_lock(&player->irq_lock);69	if (!player->substream)70		goto irq_spin_unlock;71 72	snd_pcm_stream_lock(player->substream);73	if (player->state == UNIPERIF_STATE_STOPPED)74		goto stream_unlock;75 76	/* Get interrupt status & clear them immediately */77	status = GET_UNIPERIF_ITS(player);78	SET_UNIPERIF_ITS_BCLR(player, status);79 80	/* Check for fifo error (underrun) */81	if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(player))) {82		dev_err(player->dev, "FIFO underflow error detected\n");83 84		/* Interrupt is just for information when underflow recovery */85		if (player->underflow_enabled) {86			/* Update state to underflow */87			player->state = UNIPERIF_STATE_UNDERFLOW;88 89		} else {90			/* Disable interrupt so doesn't continually fire */91			SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);92 93			/* Stop the player */94			snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);95		}96 97		ret = IRQ_HANDLED;98	}99 100	/* Check for dma error (overrun) */101	if (unlikely(status & UNIPERIF_ITS_DMA_ERROR_MASK(player))) {102		dev_err(player->dev, "DMA error detected\n");103 104		/* Disable interrupt so doesn't continually fire */105		SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);106 107		/* Stop the player */108		snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);109 110		ret = IRQ_HANDLED;111	}112 113	/* Check for underflow recovery done */114	if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) {115		if (!player->underflow_enabled) {116			dev_err(player->dev,117				"unexpected Underflow recovering\n");118			ret = -EPERM;119			goto stream_unlock;120		}121		/* Read the underflow recovery duration */122		tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);123		dev_dbg(player->dev, "Underflow recovered (%d LR clocks max)\n",124			tmp);125 126		/* Clear the underflow recovery duration */127		SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(player);128 129		/* Update state to started */130		player->state = UNIPERIF_STATE_STARTED;131 132		ret = IRQ_HANDLED;133	}134 135	/* Check if underflow recovery failed */136	if (unlikely(status &137		     UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(player))) {138		dev_err(player->dev, "Underflow recovery failed\n");139 140		/* Stop the player */141		snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);142 143		ret = IRQ_HANDLED;144	}145 146stream_unlock:147	snd_pcm_stream_unlock(player->substream);148irq_spin_unlock:149	spin_unlock(&player->irq_lock);150 151	return ret;152}153 154static int uni_player_clk_set_rate(struct uniperif *player, unsigned long rate)155{156	int rate_adjusted, rate_achieved, delta, ret;157	int adjustment = player->clk_adj;158 159	/*160	 *             a161	 * F = f + --------- * f = f + d162	 *          1000000163	 *164	 *         a165	 * d = --------- * f166	 *      1000000167	 *168	 * where:169	 *   f - nominal rate170	 *   a - adjustment in ppm (parts per milion)171	 *   F - rate to be set in synthesizer172	 *   d - delta (difference) between f and F173	 */174	if (adjustment < 0) {175		/* div64_64 operates on unsigned values... */176		delta = -1;177		adjustment = -adjustment;178	} else {179		delta = 1;180	}181	/* 500000 ppm is 0.5, which is used to round up values */182	delta *= (int)div64_u64((uint64_t)rate *183				(uint64_t)adjustment + 500000, 1000000);184	rate_adjusted = rate + delta;185 186	/* Adjusted rate should never be == 0 */187	if (!rate_adjusted)188		return -EINVAL;189 190	ret = clk_set_rate(player->clk, rate_adjusted);191	if (ret < 0)192		return ret;193 194	rate_achieved = clk_get_rate(player->clk);195	if (!rate_achieved)196		/* If value is 0 means that clock or parent not valid */197		return -EINVAL;198 199	/*200	 * Using ALSA's adjustment control, we can modify the rate to be up201	 * to twice as much as requested, but no more202	 */203	delta = rate_achieved - rate;204	if (delta < 0) {205		/* div64_64 operates on unsigned values... */206		delta = -delta;207		adjustment = -1;208	} else {209		adjustment = 1;210	}211	/* Frequency/2 is added to round up result */212	adjustment *= (int)div64_u64((uint64_t)delta * 1000000 + rate / 2,213				     rate);214	player->clk_adj = adjustment;215	return 0;216}217 218static void uni_player_set_channel_status(struct uniperif *player,219					  struct snd_pcm_runtime *runtime)220{221	int n;222	unsigned int status;223 224	/*225	 * Some AVRs and TVs require the channel status to contain a correct226	 * sampling frequency. If no sample rate is already specified, then227	 * set one.228	 */229	if (runtime) {230		switch (runtime->rate) {231		case 22050:232			player->stream_settings.iec958.status[3] =233						IEC958_AES3_CON_FS_22050;234			break;235		case 44100:236			player->stream_settings.iec958.status[3] =237						IEC958_AES3_CON_FS_44100;238			break;239		case 88200:240			player->stream_settings.iec958.status[3] =241						IEC958_AES3_CON_FS_88200;242			break;243		case 176400:244			player->stream_settings.iec958.status[3] =245						IEC958_AES3_CON_FS_176400;246			break;247		case 24000:248			player->stream_settings.iec958.status[3] =249						IEC958_AES3_CON_FS_24000;250			break;251		case 48000:252			player->stream_settings.iec958.status[3] =253						IEC958_AES3_CON_FS_48000;254			break;255		case 96000:256			player->stream_settings.iec958.status[3] =257						IEC958_AES3_CON_FS_96000;258			break;259		case 192000:260			player->stream_settings.iec958.status[3] =261						IEC958_AES3_CON_FS_192000;262			break;263		case 32000:264			player->stream_settings.iec958.status[3] =265						IEC958_AES3_CON_FS_32000;266			break;267		default:268			/* Mark as sampling frequency not indicated */269			player->stream_settings.iec958.status[3] =270						IEC958_AES3_CON_FS_NOTID;271			break;272		}273	}274 275	/* Audio mode:276	 * Use audio mode status to select PCM or encoded mode277	 */278	if (player->stream_settings.iec958.status[0] & IEC958_AES0_NONAUDIO)279		player->stream_settings.encoding_mode =280			UNIPERIF_IEC958_ENCODING_MODE_ENCODED;281	else282		player->stream_settings.encoding_mode =283			UNIPERIF_IEC958_ENCODING_MODE_PCM;284 285	if (player->stream_settings.encoding_mode ==286		UNIPERIF_IEC958_ENCODING_MODE_PCM)287		/* Clear user validity bits */288		SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);289	else290		/* Set user validity bits */291		SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 1);292 293	/* Program the new channel status */294	for (n = 0; n < 6; ++n) {295		status  =296		player->stream_settings.iec958.status[0 + (n * 4)] & 0xf;297		status |=298		player->stream_settings.iec958.status[1 + (n * 4)] << 8;299		status |=300		player->stream_settings.iec958.status[2 + (n * 4)] << 16;301		status |=302		player->stream_settings.iec958.status[3 + (n * 4)] << 24;303		SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);304	}305 306	/* Update the channel status */307	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)308		SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);309	else310		SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);311}312 313static int uni_player_prepare_iec958(struct uniperif *player,314				     struct snd_pcm_runtime *runtime)315{316	int clk_div;317 318	clk_div = player->mclk / runtime->rate;319 320	/* Oversampling must be multiple of 128 as iec958 frame is 32-bits */321	if ((clk_div % 128) || (clk_div <= 0)) {322		dev_err(player->dev, "%s: invalid clk_div %d\n",323			__func__, clk_div);324		return -EINVAL;325	}326 327	switch (runtime->format) {328	case SNDRV_PCM_FORMAT_S16_LE:329		/* 16/16 memory format */330		SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);331		/* 16-bits per sub-frame */332		SET_UNIPERIF_I2S_FMT_NBIT_32(player);333		/* Set 16-bit sample precision */334		SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);335		break;336	case SNDRV_PCM_FORMAT_S32_LE:337		/* 16/0 memory format */338		SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);339		/* 32-bits per sub-frame */340		SET_UNIPERIF_I2S_FMT_NBIT_32(player);341		/* Set 24-bit sample precision */342		SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(player);343		break;344	default:345		dev_err(player->dev, "format not supported\n");346		return -EINVAL;347	}348 349	/* Set parity to be calculated by the hardware */350	SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(player);351 352	/* Set channel status bits to be inserted by the hardware */353	SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(player);354 355	/* Set user data bits to be inserted by the hardware */356	SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(player);357 358	/* Set validity bits to be inserted by the hardware */359	SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(player);360 361	/* Set full software control to disabled */362	SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(player);363 364	SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);365 366	mutex_lock(&player->ctrl_lock);367	/* Update the channel status */368	uni_player_set_channel_status(player, runtime);369	mutex_unlock(&player->ctrl_lock);370 371	/* Clear the user validity user bits */372	SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);373 374	/* Disable one-bit audio mode */375	SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);376 377	/* Enable consecutive frames repetition of Z preamble (not for HBRA) */378	SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(player);379 380	/* Change to SUF0_SUBF1 and left/right channels swap! */381	SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(player);382 383	/* Set data output as MSB first */384	SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);385 386	if (player->stream_settings.encoding_mode ==387				UNIPERIF_IEC958_ENCODING_MODE_ENCODED)388		SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(player);389	else390		SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(player);391 392	SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);393 394	/* Set rounding to off */395	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);396 397	/* Set clock divisor */398	SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / 128);399 400	/* Set the spdif latency to not wait before starting player */401	SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);402 403	/*404	 * Ensure iec958 formatting is off. It will be enabled in function405	 * uni_player_start() at the same time as the operation406	 * mode is set to work around a silicon issue.407	 */408	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)409		SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);410	else411		SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);412 413	return 0;414}415 416static int uni_player_prepare_pcm(struct uniperif *player,417				  struct snd_pcm_runtime *runtime)418{419	int output_frame_size, slot_width, clk_div;420 421	/* Force slot width to 32 in I2S mode (HW constraint) */422	if ((player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) ==423		SND_SOC_DAIFMT_I2S)424		slot_width = 32;425	else426		slot_width = snd_pcm_format_width(runtime->format);427 428	output_frame_size = slot_width * runtime->channels;429 430	clk_div = player->mclk / runtime->rate;431	/*432	 * For 32 bits subframe clk_div must be a multiple of 128,433	 * for 16 bits must be a multiple of 64434	 */435	if ((slot_width == 32) && (clk_div % 128)) {436		dev_err(player->dev, "%s: invalid clk_div\n", __func__);437		return -EINVAL;438	}439 440	if ((slot_width == 16) && (clk_div % 64)) {441		dev_err(player->dev, "%s: invalid clk_div\n", __func__);442		return -EINVAL;443	}444 445	/*446	 * Number of bits per subframe (which is one channel sample)447	 * on output - Transfer 16 or 32 bits from FIFO448	 */449	switch (slot_width) {450	case 32:451		SET_UNIPERIF_I2S_FMT_NBIT_32(player);452		SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);453		break;454	case 16:455		SET_UNIPERIF_I2S_FMT_NBIT_16(player);456		SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);457		break;458	default:459		dev_err(player->dev, "subframe format not supported\n");460		return -EINVAL;461	}462 463	/* Configure data memory format */464	switch (runtime->format) {465	case SNDRV_PCM_FORMAT_S16_LE:466		/* One data word contains two samples */467		SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);468		break;469 470	case SNDRV_PCM_FORMAT_S32_LE:471		/*472		 * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits473		 * on the left than zeros (if less than 32 bytes)"... ;-)474		 */475		SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);476		break;477 478	default:479		dev_err(player->dev, "format not supported\n");480		return -EINVAL;481	}482 483	/* Set rounding to off */484	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);485 486	/* Set clock divisor */487	SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / (2 * output_frame_size));488 489	/* Number of channelsmust be even*/490	if ((runtime->channels % 2) || (runtime->channels < 2) ||491	    (runtime->channels > 10)) {492		dev_err(player->dev, "%s: invalid nb of channels\n", __func__);493		return -EINVAL;494	}495 496	SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);497 498	/* Set 1-bit audio format to disabled */499	SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);500 501	SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);502 503	/* No iec958 formatting as outputting to DAC  */504	SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);505 506	return 0;507}508 509static int uni_player_prepare_tdm(struct uniperif *player,510				  struct snd_pcm_runtime *runtime)511{512	int tdm_frame_size; /* unip tdm frame size in bytes */513	int user_frame_size; /* user tdm frame size in bytes */514	/* default unip TDM_WORD_POS_X_Y */515	unsigned int word_pos[4] = {516		0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};517	int freq, ret;518 519	tdm_frame_size =520		sti_uniperiph_get_unip_tdm_frame_size(player);521	user_frame_size =522		sti_uniperiph_get_user_frame_size(runtime);523 524	/* fix 16/0 format */525	SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);526	SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);527 528	/* number of words inserted on the TDM line */529	SET_UNIPERIF_I2S_FMT_NUM_CH(player, user_frame_size / 4 / 2);530 531	SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);532	SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);533 534	/* Enable the tdm functionality */535	SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(player);536 537	/* number of 8 bits timeslots avail in unip tdm frame */538	SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(player, tdm_frame_size);539 540	/* set the timeslot allocation for words in FIFO */541	sti_uniperiph_get_tdm_word_pos(player, word_pos);542	SET_UNIPERIF_TDM_WORD_POS(player, 1_2, word_pos[WORD_1_2]);543	SET_UNIPERIF_TDM_WORD_POS(player, 3_4, word_pos[WORD_3_4]);544	SET_UNIPERIF_TDM_WORD_POS(player, 5_6, word_pos[WORD_5_6]);545	SET_UNIPERIF_TDM_WORD_POS(player, 7_8, word_pos[WORD_7_8]);546 547	/* set unip clk rate (not done vai set_sysclk ops) */548	freq = runtime->rate * tdm_frame_size * 8;549	mutex_lock(&player->ctrl_lock);550	ret = uni_player_clk_set_rate(player, freq);551	if (!ret)552		player->mclk = freq;553	mutex_unlock(&player->ctrl_lock);554 555	return 0;556}557 558/*559 * ALSA uniperipheral iec958 controls560 */561static int  uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol,562				       struct snd_ctl_elem_info *uinfo)563{564	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;565	uinfo->count = 1;566 567	return 0;568}569 570static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol,571				     struct snd_ctl_elem_value *ucontrol)572{573	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);574	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);575	struct uniperif *player = priv->dai_data.uni;576	struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;577 578	mutex_lock(&player->ctrl_lock);579	ucontrol->value.iec958.status[0] = iec958->status[0];580	ucontrol->value.iec958.status[1] = iec958->status[1];581	ucontrol->value.iec958.status[2] = iec958->status[2];582	ucontrol->value.iec958.status[3] = iec958->status[3];583	mutex_unlock(&player->ctrl_lock);584	return 0;585}586 587static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,588				     struct snd_ctl_elem_value *ucontrol)589{590	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);591	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);592	struct uniperif *player = priv->dai_data.uni;593	struct snd_aes_iec958 *iec958 =  &player->stream_settings.iec958;594	unsigned long flags;595 596	mutex_lock(&player->ctrl_lock);597	iec958->status[0] = ucontrol->value.iec958.status[0];598	iec958->status[1] = ucontrol->value.iec958.status[1];599	iec958->status[2] = ucontrol->value.iec958.status[2];600	iec958->status[3] = ucontrol->value.iec958.status[3];601 602	spin_lock_irqsave(&player->irq_lock, flags);603	if (player->substream && player->substream->runtime)604		uni_player_set_channel_status(player,605					      player->substream->runtime);606	else607		uni_player_set_channel_status(player, NULL);608 609	spin_unlock_irqrestore(&player->irq_lock, flags);610	mutex_unlock(&player->ctrl_lock);611 612	return 0;613}614 615static struct snd_kcontrol_new uni_player_iec958_ctl = {616	.iface = SNDRV_CTL_ELEM_IFACE_PCM,617	.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),618	.info = uni_player_ctl_iec958_info,619	.get = uni_player_ctl_iec958_get,620	.put = uni_player_ctl_iec958_put,621};622 623/*624 * uniperif rate adjustement control625 */626static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol,627				       struct snd_ctl_elem_info *uinfo)628{629	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;630	uinfo->count = 1;631	uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN;632	uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX;633	uinfo->value.integer.step = 1;634 635	return 0;636}637 638static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol,639				      struct snd_ctl_elem_value *ucontrol)640{641	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);642	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);643	struct uniperif *player = priv->dai_data.uni;644 645	mutex_lock(&player->ctrl_lock);646	ucontrol->value.integer.value[0] = player->clk_adj;647	mutex_unlock(&player->ctrl_lock);648 649	return 0;650}651 652static int snd_sti_clk_adjustment_put(struct snd_kcontrol *kcontrol,653				      struct snd_ctl_elem_value *ucontrol)654{655	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);656	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);657	struct uniperif *player = priv->dai_data.uni;658	int ret = 0;659 660	if ((ucontrol->value.integer.value[0] < UNIPERIF_PLAYER_CLK_ADJ_MIN) ||661	    (ucontrol->value.integer.value[0] > UNIPERIF_PLAYER_CLK_ADJ_MAX))662		return -EINVAL;663 664	mutex_lock(&player->ctrl_lock);665	player->clk_adj = ucontrol->value.integer.value[0];666 667	if (player->mclk)668		ret = uni_player_clk_set_rate(player, player->mclk);669	mutex_unlock(&player->ctrl_lock);670 671	return ret;672}673 674static struct snd_kcontrol_new uni_player_clk_adj_ctl = {675	.iface = SNDRV_CTL_ELEM_IFACE_PCM,676	.name = "PCM Playback Oversampling Freq. Adjustment",677	.info = snd_sti_clk_adjustment_info,678	.get = snd_sti_clk_adjustment_get,679	.put = snd_sti_clk_adjustment_put,680};681 682static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = {683	&uni_player_clk_adj_ctl,684};685 686static struct snd_kcontrol_new *snd_sti_iec_ctl[] = {687	&uni_player_iec958_ctl,688	&uni_player_clk_adj_ctl,689};690 691static int uni_player_startup(struct snd_pcm_substream *substream,692			      struct snd_soc_dai *dai)693{694	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);695	struct uniperif *player = priv->dai_data.uni;696	unsigned long flags;697	int ret;698 699	spin_lock_irqsave(&player->irq_lock, flags);700	player->substream = substream;701	spin_unlock_irqrestore(&player->irq_lock, flags);702 703	player->clk_adj = 0;704 705	if (!UNIPERIF_TYPE_IS_TDM(player))706		return 0;707 708	/* refine hw constraint in tdm mode */709	ret = snd_pcm_hw_rule_add(substream->runtime, 0,710				  SNDRV_PCM_HW_PARAM_CHANNELS,711				  sti_uniperiph_fix_tdm_chan,712				  player, SNDRV_PCM_HW_PARAM_CHANNELS,713				  -1);714	if (ret < 0)715		return ret;716 717	return snd_pcm_hw_rule_add(substream->runtime, 0,718				   SNDRV_PCM_HW_PARAM_FORMAT,719				   sti_uniperiph_fix_tdm_format,720				   player, SNDRV_PCM_HW_PARAM_FORMAT,721				   -1);722}723 724static int uni_player_set_sysclk(struct snd_soc_dai *dai, int clk_id,725				 unsigned int freq, int dir)726{727	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);728	struct uniperif *player = priv->dai_data.uni;729	int ret;730 731	if (UNIPERIF_TYPE_IS_TDM(player) || (dir == SND_SOC_CLOCK_IN))732		return 0;733 734	if (clk_id != 0)735		return -EINVAL;736 737	mutex_lock(&player->ctrl_lock);738	ret = uni_player_clk_set_rate(player, freq);739	if (!ret)740		player->mclk = freq;741	mutex_unlock(&player->ctrl_lock);742 743	return ret;744}745 746static int uni_player_prepare(struct snd_pcm_substream *substream,747			      struct snd_soc_dai *dai)748{749	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);750	struct uniperif *player = priv->dai_data.uni;751	struct snd_pcm_runtime *runtime = substream->runtime;752	int transfer_size, trigger_limit;753	int ret;754 755	/* The player should be stopped */756	if (player->state != UNIPERIF_STATE_STOPPED) {757		dev_err(player->dev, "%s: invalid player state %d\n", __func__,758			player->state);759		return -EINVAL;760	}761 762	/* Calculate transfer size (in fifo cells and bytes) for frame count */763	if (player->type == SND_ST_UNIPERIF_TYPE_TDM) {764		/* transfer size = user frame size (in 32 bits FIFO cell) */765		transfer_size =766			sti_uniperiph_get_user_frame_size(runtime) / 4;767	} else {768		transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;769	}770 771	/* Calculate number of empty cells available before asserting DREQ */772	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {773		trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;774	} else {775		/*776		 * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0777		 * FDMA_TRIGGER_LIMIT also controls when the state switches778		 * from OFF or STANDBY to AUDIO DATA.779		 */780		trigger_limit = transfer_size;781	}782 783	/* Trigger limit must be an even number */784	if ((!trigger_limit % 2) || (trigger_limit != 1 && transfer_size % 2) ||785	    (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(player))) {786		dev_err(player->dev, "invalid trigger limit %d\n",787			trigger_limit);788		return -EINVAL;789	}790 791	SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit);792 793	/* Uniperipheral setup depends on player type */794	switch (player->type) {795	case SND_ST_UNIPERIF_TYPE_HDMI:796		ret = uni_player_prepare_iec958(player, runtime);797		break;798	case SND_ST_UNIPERIF_TYPE_PCM:799		ret = uni_player_prepare_pcm(player, runtime);800		break;801	case SND_ST_UNIPERIF_TYPE_SPDIF:802		ret = uni_player_prepare_iec958(player, runtime);803		break;804	case SND_ST_UNIPERIF_TYPE_TDM:805		ret = uni_player_prepare_tdm(player, runtime);806		break;807	default:808		dev_err(player->dev, "invalid player type\n");809		return -EINVAL;810	}811 812	if (ret)813		return ret;814 815	switch (player->daifmt & SND_SOC_DAIFMT_INV_MASK) {816	case SND_SOC_DAIFMT_NB_NF:817		SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);818		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);819		break;820	case SND_SOC_DAIFMT_NB_IF:821		SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);822		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);823		break;824	case SND_SOC_DAIFMT_IB_NF:825		SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);826		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);827		break;828	case SND_SOC_DAIFMT_IB_IF:829		SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);830		SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);831		break;832	}833 834	switch (player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {835	case SND_SOC_DAIFMT_I2S:836		SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);837		SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(player);838		break;839	case SND_SOC_DAIFMT_LEFT_J:840		SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);841		SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);842		break;843	case SND_SOC_DAIFMT_RIGHT_J:844		SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(player);845		SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);846		break;847	default:848		dev_err(player->dev, "format not supported\n");849		return -EINVAL;850	}851 852	SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(player, 0);853 854 855	return sti_uniperiph_reset(player);856}857 858static int uni_player_start(struct uniperif *player)859{860	int ret;861 862	/* The player should be stopped */863	if (player->state != UNIPERIF_STATE_STOPPED) {864		dev_err(player->dev, "%s: invalid player state\n", __func__);865		return -EINVAL;866	}867 868	ret = clk_prepare_enable(player->clk);869	if (ret) {870		dev_err(player->dev, "%s: Failed to enable clock\n", __func__);871		return ret;872	}873 874	/* Clear any pending interrupts */875	SET_UNIPERIF_ITS_BCLR(player, GET_UNIPERIF_ITS(player));876 877	/* Set the interrupt mask */878	SET_UNIPERIF_ITM_BSET_DMA_ERROR(player);879	SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player);880 881	/* Enable underflow recovery interrupts */882	if (player->underflow_enabled) {883		SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player);884		SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player);885	}886 887	ret = sti_uniperiph_reset(player);888	if (ret < 0) {889		clk_disable_unprepare(player->clk);890		return ret;891	}892 893	/*894	 * Does not use IEC61937 features of the uniperipheral hardware.895	 * Instead it performs IEC61937 in software and inserts it directly896	 * into the audio data stream. As such, when encoded mode is selected,897	 * linear pcm mode is still used, but with the differences of the898	 * channel status bits set for encoded mode and the validity bits set.899	 */900	SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(player);901 902	/*903	 * If iec958 formatting is required for hdmi or spdif, then it must be904	 * enabled after the operation mode is set. If set prior to this, it905	 * will not take affect and hang the player.906	 */907	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)908		if (UNIPERIF_TYPE_IS_IEC958(player))909			SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);910 911	/* Force channel status update (no update if clk disable) */912	if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)913		SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);914	else915		SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);916 917	/* Update state to started */918	player->state = UNIPERIF_STATE_STARTED;919 920	return 0;921}922 923static int uni_player_stop(struct uniperif *player)924{925	int ret;926 927	/* The player should not be in stopped state */928	if (player->state == UNIPERIF_STATE_STOPPED) {929		dev_err(player->dev, "%s: invalid player state\n", __func__);930		return -EINVAL;931	}932 933	/* Turn the player off */934	SET_UNIPERIF_CTRL_OPERATION_OFF(player);935 936	ret = sti_uniperiph_reset(player);937	if (ret < 0)938		return ret;939 940	/* Disable interrupts */941	SET_UNIPERIF_ITM_BCLR(player, GET_UNIPERIF_ITM(player));942 943	/* Disable clock */944	clk_disable_unprepare(player->clk);945 946	/* Update state to stopped and return */947	player->state = UNIPERIF_STATE_STOPPED;948 949	return 0;950}951 952int uni_player_resume(struct uniperif *player)953{954	int ret;955 956	/* Select the frequency synthesizer clock */957	if (player->clk_sel) {958		ret = regmap_field_write(player->clk_sel, 1);959		if (ret) {960			dev_err(player->dev,961				"%s: Failed to select freq synth clock\n",962				__func__);963			return ret;964		}965	}966 967	SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);968	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);969	SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);970	SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);971 972	return 0;973}974EXPORT_SYMBOL_GPL(uni_player_resume);975 976static int uni_player_trigger(struct snd_pcm_substream *substream,977			      int cmd, struct snd_soc_dai *dai)978{979	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);980	struct uniperif *player = priv->dai_data.uni;981 982	switch (cmd) {983	case SNDRV_PCM_TRIGGER_START:984		return uni_player_start(player);985	case SNDRV_PCM_TRIGGER_STOP:986		return uni_player_stop(player);987	case SNDRV_PCM_TRIGGER_RESUME:988		return uni_player_resume(player);989	default:990		return -EINVAL;991	}992}993 994static void uni_player_shutdown(struct snd_pcm_substream *substream,995				struct snd_soc_dai *dai)996{997	struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);998	struct uniperif *player = priv->dai_data.uni;999	unsigned long flags;1000 1001	spin_lock_irqsave(&player->irq_lock, flags);1002	if (player->state != UNIPERIF_STATE_STOPPED)1003		/* Stop the player */1004		uni_player_stop(player);1005 1006	player->substream = NULL;1007	spin_unlock_irqrestore(&player->irq_lock, flags);1008}1009 1010static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,1011					  struct uniperif *player)1012{1013	struct device_node *node = pdev->dev.of_node;1014	struct regmap *regmap;1015	struct reg_field regfield[2] = {1016		/* PCM_CLK_SEL */1017		REG_FIELD(SYS_CFG_AUDIO_GLUE,1018			  8 + player->id,1019			  8 + player->id),1020		/* PCMP_VALID_SEL */1021		REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1)1022	};1023 1024	regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");1025 1026	if (IS_ERR(regmap)) {1027		dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n");1028		return PTR_ERR(regmap);1029	}1030 1031	player->clk_sel = regmap_field_alloc(regmap, regfield[0]);1032	player->valid_sel = regmap_field_alloc(regmap, regfield[1]);1033 1034	return 0;1035}1036 1037static const struct snd_soc_dai_ops uni_player_dai_ops = {1038		.startup = uni_player_startup,1039		.shutdown = uni_player_shutdown,1040		.prepare = uni_player_prepare,1041		.probe = sti_uniperiph_dai_probe,1042		.trigger = uni_player_trigger,1043		.hw_params = sti_uniperiph_dai_hw_params,1044		.set_fmt = sti_uniperiph_dai_set_fmt,1045		.set_sysclk = uni_player_set_sysclk,1046		.set_tdm_slot = sti_uniperiph_set_tdm_slot1047};1048 1049int uni_player_init(struct platform_device *pdev,1050		    struct uniperif *player)1051{1052	int ret = 0;1053 1054	player->dev = &pdev->dev;1055	player->state = UNIPERIF_STATE_STOPPED;1056	player->dai_ops = &uni_player_dai_ops;1057 1058	/* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */1059	ret = uni_player_parse_dt_audio_glue(pdev, player);1060 1061	if (ret < 0) {1062		dev_err(player->dev, "Failed to parse DeviceTree\n");1063		return ret;1064	}1065 1066	/* Underflow recovery is only supported on later ip revisions */1067	if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)1068		player->underflow_enabled = 1;1069 1070	if (UNIPERIF_TYPE_IS_TDM(player))1071		player->hw = &uni_tdm_hw;1072	else1073		player->hw = &uni_player_pcm_hw;1074 1075	/* Get uniperif resource */1076	player->clk = of_clk_get(pdev->dev.of_node, 0);1077	if (IS_ERR(player->clk)) {1078		dev_err(player->dev, "Failed to get clock\n");1079		return PTR_ERR(player->clk);1080	}1081 1082	/* Select the frequency synthesizer clock */1083	if (player->clk_sel) {1084		ret = regmap_field_write(player->clk_sel, 1);1085		if (ret) {1086			dev_err(player->dev,1087				"%s: Failed to select freq synth clock\n",1088				__func__);1089			return ret;1090		}1091	}1092 1093	/* connect to I2S/TDM TX bus */1094	if (player->valid_sel &&1095	    (player->id == UNIPERIF_PLAYER_I2S_OUT)) {1096		ret = regmap_field_write(player->valid_sel, player->id);1097		if (ret) {1098			dev_err(player->dev,1099				"%s: unable to connect to tdm bus\n", __func__);1100			return ret;1101		}1102	}1103 1104	ret = devm_request_irq(&pdev->dev, player->irq,1105			       uni_player_irq_handler, IRQF_SHARED,1106			       dev_name(&pdev->dev), player);1107	if (ret < 0) {1108		dev_err(player->dev, "unable to request IRQ %d\n", player->irq);1109		return ret;1110	}1111 1112	mutex_init(&player->ctrl_lock);1113	spin_lock_init(&player->irq_lock);1114 1115	/* Ensure that disabled by default */1116	SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);1117	SET_UNIPERIF_CTRL_ROUNDING_OFF(player);1118	SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);1119	SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);1120 1121	if (UNIPERIF_TYPE_IS_IEC958(player)) {1122		/* Set default iec958 status bits  */1123 1124		/* Consumer, PCM, copyright, 2ch, mode 0 */1125		player->stream_settings.iec958.status[0] = 0x00;1126		/* Broadcast reception category */1127		player->stream_settings.iec958.status[1] =1128					IEC958_AES1_CON_GENERAL;1129		/* Do not take into account source or channel number */1130		player->stream_settings.iec958.status[2] =1131					IEC958_AES2_CON_SOURCE_UNSPEC;1132		/* Sampling frequency not indicated */1133		player->stream_settings.iec958.status[3] =1134					IEC958_AES3_CON_FS_NOTID;1135		/* Max sample word 24-bit, sample word length not indicated */1136		player->stream_settings.iec958.status[4] =1137					IEC958_AES4_CON_MAX_WORDLEN_24 |1138					IEC958_AES4_CON_WORDLEN_24_20;1139 1140		player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl);1141		player->snd_ctrls = snd_sti_iec_ctl[0];1142	} else {1143		player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl);1144		player->snd_ctrls = snd_sti_pcm_ctl[0];1145	}1146 1147	return 0;1148}1149EXPORT_SYMBOL_GPL(uni_player_init);1150