e SSC system clock rate.
 */
static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
		int clk_id, unsigned int freq, int dir)
{
	/*
	 * The only clock supplied to the SSC is the AT91 master clock,
	 * which is only used if the SSC is generating BCLK and/or
	 * LRC clocks.
	 */
	switch (clk_id) {
	case AT91_SYSCLK_MCK:
		at91_ssc_sysclk = freq;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

/*
 * Record the DAI format for use in hw_params().
 */
static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
		unsigned int fmt)
{
	struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];

	ssc_p->daifmt = fmt;
	return 0;
}

/*
 * Record SSC clock dividers for use in hw_params().
 */
static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
	int div_id, int div)
{
	struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];

	switch (div_id) {
	case AT91SSC_CMR_DIV:
		/*
		 * The same master clock divider is used for both
		 * transmit and receive, so if a value has already
		 * been set, it must match this value.
		 */
		if (ssc_p->cmr_div == 0)
			ssc_p->cmr_div = div;
		else
			if (div != ssc_p->cmr_div)
				return -EBUSY;
		break;

	case AT91SSC_TCMR_PERIOD:
		ssc_p->tcmr_period = div;
		break;

	case AT91SSC_RCMR_PERIOD:
		ssc_p->rcmr_period = div;
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

/*
 * Configure the SSC.
 */
static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	int id = rtd->dai->cpu_dai->id;
	struct at91_ssc_info *ssc_p = &ssc_info[id];
	struct at91_pcm_dma_params *dma_params;
	int dir, channels, bits;
	u32 tfmr, rfmr, tcmr, rcmr;
	int start_event;
	int ret;

	/*
	 * Currently, there is only one set of dma params for
	 * each direction.  If more are added, this code will
	 * have to be changed to select the proper set.
	 */
	dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;

	dma_params = &ssc_dma_params[id][dir];
	dma_params->ssc_base = ssc_p