Linux Audio

Check our new training course

Loading...
v6.2
  1/*
  2 * ALSA SoC Synopsys I2S Audio Layer
  3 *
  4 * sound/soc/dwc/designware_i2s.c
  5 *
  6 * Copyright (C) 2010 ST Microelectronics
  7 * Rajeev Kumar <rajeevkumar.linux@gmail.com>
  8 *
  9 * This file is licensed under the terms of the GNU General Public
 10 * License version 2. This program is licensed "as is" without any
 11 * warranty of any kind, whether express or implied.
 12 */
 13
 14#include <linux/clk.h>
 15#include <linux/device.h>
 16#include <linux/init.h>
 17#include <linux/io.h>
 18#include <linux/interrupt.h>
 19#include <linux/module.h>
 20#include <linux/slab.h>
 21#include <linux/pm_runtime.h>
 22#include <sound/designware_i2s.h>
 23#include <sound/pcm.h>
 24#include <sound/pcm_params.h>
 25#include <sound/soc.h>
 26#include <sound/dmaengine_pcm.h>
 27#include "local.h"
 28
 29static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
 30{
 31	writel(val, io_base + reg);
 32}
 33
 34static inline u32 i2s_read_reg(void __iomem *io_base, int reg)
 35{
 36	return readl(io_base + reg);
 37}
 38
 39static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream)
 40{
 41	u32 i = 0;
 42
 43	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 44		for (i = 0; i < 4; i++)
 45			i2s_write_reg(dev->i2s_base, TER(i), 0);
 46	} else {
 47		for (i = 0; i < 4; i++)
 48			i2s_write_reg(dev->i2s_base, RER(i), 0);
 49	}
 50}
 51
 52static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
 53{
 54	u32 i = 0;
 55
 56	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 57		for (i = 0; i < 4; i++)
 58			i2s_read_reg(dev->i2s_base, TOR(i));
 59	} else {
 60		for (i = 0; i < 4; i++)
 61			i2s_read_reg(dev->i2s_base, ROR(i));
 62	}
 63}
 64
 65static inline void i2s_disable_irqs(struct dw_i2s_dev *dev, u32 stream,
 66				    int chan_nr)
 67{
 68	u32 i, irq;
 69
 70	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 71		for (i = 0; i < (chan_nr / 2); i++) {
 72			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 73			i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
 74		}
 75	} else {
 76		for (i = 0; i < (chan_nr / 2); i++) {
 77			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 78			i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
 79		}
 80	}
 81}
 82
 83static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
 84				   int chan_nr)
 85{
 86	u32 i, irq;
 87
 88	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 89		for (i = 0; i < (chan_nr / 2); i++) {
 90			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 91			i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
 92		}
 93	} else {
 94		for (i = 0; i < (chan_nr / 2); i++) {
 95			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 96			i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
 97		}
 98	}
 99}
100
101static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
102{
103	struct dw_i2s_dev *dev = dev_id;
104	bool irq_valid = false;
105	u32 isr[4];
106	int i;
107
108	for (i = 0; i < 4; i++)
109		isr[i] = i2s_read_reg(dev->i2s_base, ISR(i));
110
111	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_PLAYBACK);
112	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_CAPTURE);
113
114	for (i = 0; i < 4; i++) {
115		/*
116		 * Check if TX fifo is empty. If empty fill FIFO with samples
117		 * NOTE: Only two channels supported
118		 */
119		if ((isr[i] & ISR_TXFE) && (i == 0) && dev->use_pio) {
120			dw_pcm_push_tx(dev);
121			irq_valid = true;
122		}
123
124		/*
125		 * Data available. Retrieve samples from FIFO
126		 * NOTE: Only two channels supported
127		 */
128		if ((isr[i] & ISR_RXDA) && (i == 0) && dev->use_pio) {
129			dw_pcm_pop_rx(dev);
130			irq_valid = true;
131		}
132
133		/* Error Handling: TX */
134		if (isr[i] & ISR_TXFO) {
135			dev_err(dev->dev, "TX overrun (ch_id=%d)\n", i);
136			irq_valid = true;
137		}
138
139		/* Error Handling: TX */
140		if (isr[i] & ISR_RXFO) {
141			dev_err(dev->dev, "RX overrun (ch_id=%d)\n", i);
142			irq_valid = true;
143		}
144	}
145
146	if (irq_valid)
147		return IRQ_HANDLED;
148	else
149		return IRQ_NONE;
150}
151
152static void i2s_start(struct dw_i2s_dev *dev,
153		      struct snd_pcm_substream *substream)
154{
155	struct i2s_clk_config_data *config = &dev->config;
156
157	i2s_write_reg(dev->i2s_base, IER, 1);
158	i2s_enable_irqs(dev, substream->stream, config->chan_nr);
159
160	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
161		i2s_write_reg(dev->i2s_base, ITER, 1);
162	else
163		i2s_write_reg(dev->i2s_base, IRER, 1);
164
165	i2s_write_reg(dev->i2s_base, CER, 1);
166}
167
168static void i2s_stop(struct dw_i2s_dev *dev,
169		struct snd_pcm_substream *substream)
170{
171
172	i2s_clear_irqs(dev, substream->stream);
173	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
174		i2s_write_reg(dev->i2s_base, ITER, 0);
175	else
176		i2s_write_reg(dev->i2s_base, IRER, 0);
177
178	i2s_disable_irqs(dev, substream->stream, 8);
179
180	if (!dev->active) {
181		i2s_write_reg(dev->i2s_base, CER, 0);
182		i2s_write_reg(dev->i2s_base, IER, 0);
183	}
184}
185
186static int dw_i2s_startup(struct snd_pcm_substream *substream,
187		struct snd_soc_dai *cpu_dai)
188{
189	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
190	union dw_i2s_snd_dma_data *dma_data = NULL;
191
192	if (!(dev->capability & DWC_I2S_RECORD) &&
193			(substream->stream == SNDRV_PCM_STREAM_CAPTURE))
194		return -EINVAL;
195
196	if (!(dev->capability & DWC_I2S_PLAY) &&
197			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
198		return -EINVAL;
199
200	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
201		dma_data = &dev->play_dma_data;
202	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
203		dma_data = &dev->capture_dma_data;
204
205	snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data);
206
207	return 0;
208}
209
210static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
211{
212	u32 ch_reg;
213	struct i2s_clk_config_data *config = &dev->config;
214
215
216	i2s_disable_channels(dev, stream);
217
218	for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) {
219		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
220			i2s_write_reg(dev->i2s_base, TCR(ch_reg),
221				      dev->xfer_resolution);
222			i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
223				      dev->fifo_th - 1);
224			i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
225		} else {
226			i2s_write_reg(dev->i2s_base, RCR(ch_reg),
227				      dev->xfer_resolution);
228			i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
229				      dev->fifo_th - 1);
230			i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
231		}
232
233	}
234}
235
236static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
237		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
238{
239	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
240	struct i2s_clk_config_data *config = &dev->config;
241	int ret;
242
243	switch (params_format(params)) {
244	case SNDRV_PCM_FORMAT_S16_LE:
245		config->data_width = 16;
246		dev->ccr = 0x00;
247		dev->xfer_resolution = 0x02;
248		break;
249
250	case SNDRV_PCM_FORMAT_S24_LE:
251		config->data_width = 24;
252		dev->ccr = 0x08;
253		dev->xfer_resolution = 0x04;
254		break;
255
256	case SNDRV_PCM_FORMAT_S32_LE:
257		config->data_width = 32;
258		dev->ccr = 0x10;
259		dev->xfer_resolution = 0x05;
260		break;
261
262	default:
263		dev_err(dev->dev, "designware-i2s: unsupported PCM fmt");
264		return -EINVAL;
265	}
266
267	config->chan_nr = params_channels(params);
268
269	switch (config->chan_nr) {
270	case EIGHT_CHANNEL_SUPPORT:
271	case SIX_CHANNEL_SUPPORT:
272	case FOUR_CHANNEL_SUPPORT:
273	case TWO_CHANNEL_SUPPORT:
274		break;
275	default:
276		dev_err(dev->dev, "channel not supported\n");
277		return -EINVAL;
278	}
279
280	dw_i2s_config(dev, substream->stream);
281
282	i2s_write_reg(dev->i2s_base, CCR, dev->ccr);
283
284	config->sample_rate = params_rate(params);
285
286	if (dev->capability & DW_I2S_MASTER) {
287		if (dev->i2s_clk_cfg) {
288			ret = dev->i2s_clk_cfg(config);
289			if (ret < 0) {
290				dev_err(dev->dev, "runtime audio clk config fail\n");
291				return ret;
292			}
293		} else {
294			u32 bitclk = config->sample_rate *
295					config->data_width * 2;
296
297			ret = clk_set_rate(dev->clk, bitclk);
298			if (ret) {
299				dev_err(dev->dev, "Can't set I2S clock rate: %d\n",
300					ret);
301				return ret;
302			}
303		}
304	}
305	return 0;
306}
307
308static void dw_i2s_shutdown(struct snd_pcm_substream *substream,
309		struct snd_soc_dai *dai)
310{
311	snd_soc_dai_set_dma_data(dai, substream, NULL);
312}
313
314static int dw_i2s_prepare(struct snd_pcm_substream *substream,
315			  struct snd_soc_dai *dai)
316{
317	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
318
319	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
320		i2s_write_reg(dev->i2s_base, TXFFR, 1);
321	else
322		i2s_write_reg(dev->i2s_base, RXFFR, 1);
323
324	return 0;
325}
326
327static int dw_i2s_trigger(struct snd_pcm_substream *substream,
328		int cmd, struct snd_soc_dai *dai)
329{
330	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
331	int ret = 0;
332
333	switch (cmd) {
334	case SNDRV_PCM_TRIGGER_START:
335	case SNDRV_PCM_TRIGGER_RESUME:
336	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
337		dev->active++;
338		i2s_start(dev, substream);
339		break;
340
341	case SNDRV_PCM_TRIGGER_STOP:
342	case SNDRV_PCM_TRIGGER_SUSPEND:
343	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
344		dev->active--;
345		i2s_stop(dev, substream);
346		break;
347	default:
348		ret = -EINVAL;
349		break;
350	}
351	return ret;
352}
353
354static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
355{
356	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
357	int ret = 0;
358
359	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
360	case SND_SOC_DAIFMT_BC_FC:
361		if (dev->capability & DW_I2S_SLAVE)
362			ret = 0;
363		else
364			ret = -EINVAL;
365		break;
366	case SND_SOC_DAIFMT_BP_FP:
367		if (dev->capability & DW_I2S_MASTER)
368			ret = 0;
369		else
370			ret = -EINVAL;
371		break;
372	case SND_SOC_DAIFMT_BC_FP:
373	case SND_SOC_DAIFMT_BP_FC:
374		ret = -EINVAL;
375		break;
376	default:
377		dev_dbg(dev->dev, "dwc : Invalid clock provider format\n");
378		ret = -EINVAL;
379		break;
380	}
381	return ret;
382}
383
384static const struct snd_soc_dai_ops dw_i2s_dai_ops = {
385	.startup	= dw_i2s_startup,
386	.shutdown	= dw_i2s_shutdown,
387	.hw_params	= dw_i2s_hw_params,
388	.prepare	= dw_i2s_prepare,
389	.trigger	= dw_i2s_trigger,
390	.set_fmt	= dw_i2s_set_fmt,
391};
392
393#ifdef CONFIG_PM
394static int dw_i2s_runtime_suspend(struct device *dev)
395{
396	struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
397
398	if (dw_dev->capability & DW_I2S_MASTER)
399		clk_disable(dw_dev->clk);
400	return 0;
401}
402
403static int dw_i2s_runtime_resume(struct device *dev)
404{
405	struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
406	int ret;
407
408	if (dw_dev->capability & DW_I2S_MASTER) {
409		ret = clk_enable(dw_dev->clk);
410		if (ret)
411			return ret;
412	}
413	return 0;
414}
415
416static int dw_i2s_suspend(struct snd_soc_component *component)
417{
418	struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component);
419
420	if (dev->capability & DW_I2S_MASTER)
421		clk_disable(dev->clk);
422	return 0;
423}
424
425static int dw_i2s_resume(struct snd_soc_component *component)
426{
427	struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component);
428	struct snd_soc_dai *dai;
429	int stream, ret;
430
431	if (dev->capability & DW_I2S_MASTER) {
432		ret = clk_enable(dev->clk);
433		if (ret)
434			return ret;
435	}
436
437	for_each_component_dais(component, dai) {
438		for_each_pcm_streams(stream)
439			if (snd_soc_dai_stream_active(dai, stream))
440				dw_i2s_config(dev, stream);
441	}
442
443	return 0;
444}
445
446#else
447#define dw_i2s_suspend	NULL
448#define dw_i2s_resume	NULL
449#endif
450
451static const struct snd_soc_component_driver dw_i2s_component = {
452	.name			= "dw-i2s",
453	.suspend		= dw_i2s_suspend,
454	.resume			= dw_i2s_resume,
455	.legacy_dai_naming	= 1,
456};
457
458/*
459 * The following tables allow a direct lookup of various parameters
460 * defined in the I2S block's configuration in terms of sound system
461 * parameters.  Each table is sized to the number of entries possible
462 * according to the number of configuration bits describing an I2S
463 * block parameter.
464 */
465
466/* Maximum bit resolution of a channel - not uniformly spaced */
467static const u32 fifo_width[COMP_MAX_WORDSIZE] = {
468	12, 16, 20, 24, 32, 0, 0, 0
469};
470
471/* Width of (DMA) bus */
472static const u32 bus_widths[COMP_MAX_DATA_WIDTH] = {
473	DMA_SLAVE_BUSWIDTH_1_BYTE,
474	DMA_SLAVE_BUSWIDTH_2_BYTES,
475	DMA_SLAVE_BUSWIDTH_4_BYTES,
476	DMA_SLAVE_BUSWIDTH_UNDEFINED
477};
478
479/* PCM format to support channel resolution */
480static const u32 formats[COMP_MAX_WORDSIZE] = {
481	SNDRV_PCM_FMTBIT_S16_LE,
482	SNDRV_PCM_FMTBIT_S16_LE,
483	SNDRV_PCM_FMTBIT_S24_LE,
484	SNDRV_PCM_FMTBIT_S24_LE,
485	SNDRV_PCM_FMTBIT_S32_LE,
486	0,
487	0,
488	0
489};
490
491static int dw_configure_dai(struct dw_i2s_dev *dev,
492				   struct snd_soc_dai_driver *dw_i2s_dai,
493				   unsigned int rates)
494{
495	/*
496	 * Read component parameter registers to extract
497	 * the I2S block's configuration.
498	 */
499	u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
500	u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2);
501	u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
502	u32 idx;
503
504	if (dev->capability & DWC_I2S_RECORD &&
505			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
506		comp1 = comp1 & ~BIT(5);
507
508	if (dev->capability & DWC_I2S_PLAY &&
509			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
510		comp1 = comp1 & ~BIT(6);
511
512	if (COMP1_TX_ENABLED(comp1)) {
513		dev_dbg(dev->dev, " designware: play supported\n");
514		idx = COMP1_TX_WORDSIZE_0(comp1);
515		if (WARN_ON(idx >= ARRAY_SIZE(formats)))
516			return -EINVAL;
517		if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
518			idx = 1;
519		dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
520		dw_i2s_dai->playback.channels_max =
521				1 << (COMP1_TX_CHANNELS(comp1) + 1);
522		dw_i2s_dai->playback.formats = formats[idx];
523		dw_i2s_dai->playback.rates = rates;
524	}
525
526	if (COMP1_RX_ENABLED(comp1)) {
527		dev_dbg(dev->dev, "designware: record supported\n");
528		idx = COMP2_RX_WORDSIZE_0(comp2);
529		if (WARN_ON(idx >= ARRAY_SIZE(formats)))
530			return -EINVAL;
531		if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
532			idx = 1;
533		dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
534		dw_i2s_dai->capture.channels_max =
535				1 << (COMP1_RX_CHANNELS(comp1) + 1);
536		dw_i2s_dai->capture.formats = formats[idx];
537		dw_i2s_dai->capture.rates = rates;
538	}
539
540	if (COMP1_MODE_EN(comp1)) {
541		dev_dbg(dev->dev, "designware: i2s master mode supported\n");
542		dev->capability |= DW_I2S_MASTER;
543	} else {
544		dev_dbg(dev->dev, "designware: i2s slave mode supported\n");
545		dev->capability |= DW_I2S_SLAVE;
546	}
547
548	dev->fifo_th = fifo_depth / 2;
549	return 0;
550}
551
552static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev,
553				   struct snd_soc_dai_driver *dw_i2s_dai,
554				   struct resource *res,
555				   const struct i2s_platform_data *pdata)
556{
557	u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
558	u32 idx = COMP1_APB_DATA_WIDTH(comp1);
559	int ret;
560
561	if (WARN_ON(idx >= ARRAY_SIZE(bus_widths)))
562		return -EINVAL;
563
564	ret = dw_configure_dai(dev, dw_i2s_dai, pdata->snd_rates);
565	if (ret < 0)
566		return ret;
567
568	if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
569		idx = 1;
570	/* Set DMA slaves info */
571	dev->play_dma_data.pd.data = pdata->play_dma_data;
572	dev->capture_dma_data.pd.data = pdata->capture_dma_data;
573	dev->play_dma_data.pd.addr = res->start + I2S_TXDMA;
574	dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA;
575	dev->play_dma_data.pd.max_burst = 16;
576	dev->capture_dma_data.pd.max_burst = 16;
577	dev->play_dma_data.pd.addr_width = bus_widths[idx];
578	dev->capture_dma_data.pd.addr_width = bus_widths[idx];
579	dev->play_dma_data.pd.filter = pdata->filter;
580	dev->capture_dma_data.pd.filter = pdata->filter;
581
582	return 0;
583}
584
585static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev,
586				   struct snd_soc_dai_driver *dw_i2s_dai,
587				   struct resource *res)
588{
589	u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1);
590	u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2);
591	u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
592	u32 idx = COMP1_APB_DATA_WIDTH(comp1);
593	u32 idx2;
594	int ret;
595
596	if (WARN_ON(idx >= ARRAY_SIZE(bus_widths)))
597		return -EINVAL;
598
599	ret = dw_configure_dai(dev, dw_i2s_dai, SNDRV_PCM_RATE_8000_192000);
600	if (ret < 0)
601		return ret;
602
603	if (COMP1_TX_ENABLED(comp1)) {
604		idx2 = COMP1_TX_WORDSIZE_0(comp1);
605
606		dev->capability |= DWC_I2S_PLAY;
607		dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
608		dev->play_dma_data.dt.addr_width = bus_widths[idx];
609		dev->play_dma_data.dt.fifo_size = fifo_depth *
610			(fifo_width[idx2]) >> 8;
611		dev->play_dma_data.dt.maxburst = 16;
612	}
613	if (COMP1_RX_ENABLED(comp1)) {
614		idx2 = COMP2_RX_WORDSIZE_0(comp2);
615
616		dev->capability |= DWC_I2S_RECORD;
617		dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
618		dev->capture_dma_data.dt.addr_width = bus_widths[idx];
619		dev->capture_dma_data.dt.fifo_size = fifo_depth *
620			(fifo_width[idx2] >> 8);
621		dev->capture_dma_data.dt.maxburst = 16;
622	}
623
624	return 0;
625
626}
627
628static int dw_i2s_probe(struct platform_device *pdev)
629{
630	const struct i2s_platform_data *pdata = pdev->dev.platform_data;
631	struct dw_i2s_dev *dev;
632	struct resource *res;
633	int ret, irq;
634	struct snd_soc_dai_driver *dw_i2s_dai;
635	const char *clk_id;
636
637	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
638	if (!dev)
639		return -ENOMEM;
640
641	dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
642	if (!dw_i2s_dai)
643		return -ENOMEM;
644
645	dw_i2s_dai->ops = &dw_i2s_dai_ops;
646
647	dev->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 
648	if (IS_ERR(dev->i2s_base))
649		return PTR_ERR(dev->i2s_base);
650
651	dev->dev = &pdev->dev;
652
653	irq = platform_get_irq_optional(pdev, 0);
654	if (irq >= 0) {
655		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
656				pdev->name, dev);
657		if (ret < 0) {
658			dev_err(&pdev->dev, "failed to request irq\n");
659			return ret;
660		}
661	}
662
663	dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
664	dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
665	if (pdata) {
666		dev->capability = pdata->cap;
667		clk_id = NULL;
668		dev->quirks = pdata->quirks;
669		if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
670			dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
671			dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
672		}
673		ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
674	} else {
675		clk_id = "i2sclk";
676		ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
677	}
678	if (ret < 0)
679		return ret;
680
681	if (dev->capability & DW_I2S_MASTER) {
682		if (pdata) {
683			dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
684			if (!dev->i2s_clk_cfg) {
685				dev_err(&pdev->dev, "no clock configure method\n");
686				return -ENODEV;
687			}
688		}
689		dev->clk = devm_clk_get(&pdev->dev, clk_id);
690
691		if (IS_ERR(dev->clk))
692			return PTR_ERR(dev->clk);
693
694		ret = clk_prepare_enable(dev->clk);
695		if (ret < 0)
696			return ret;
697	}
698
699	dev_set_drvdata(&pdev->dev, dev);
700	ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component,
701					 dw_i2s_dai, 1);
702	if (ret != 0) {
703		dev_err(&pdev->dev, "not able to register dai\n");
704		goto err_clk_disable;
705	}
706
707	if (!pdata) {
708		if (irq >= 0) {
709			ret = dw_pcm_register(pdev);
710			dev->use_pio = true;
711		} else {
712			ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
713					0);
714			dev->use_pio = false;
715		}
716
717		if (ret) {
718			dev_err(&pdev->dev, "could not register pcm: %d\n",
719					ret);
720			goto err_clk_disable;
721		}
722	}
723
724	pm_runtime_enable(&pdev->dev);
725	return 0;
726
727err_clk_disable:
728	if (dev->capability & DW_I2S_MASTER)
729		clk_disable_unprepare(dev->clk);
730	return ret;
731}
732
733static int dw_i2s_remove(struct platform_device *pdev)
734{
735	struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
736
737	if (dev->capability & DW_I2S_MASTER)
738		clk_disable_unprepare(dev->clk);
739
740	pm_runtime_disable(&pdev->dev);
741	return 0;
742}
743
744#ifdef CONFIG_OF
745static const struct of_device_id dw_i2s_of_match[] = {
746	{ .compatible = "snps,designware-i2s",	 },
747	{},
748};
749
750MODULE_DEVICE_TABLE(of, dw_i2s_of_match);
751#endif
752
753static const struct dev_pm_ops dwc_pm_ops = {
754	SET_RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL)
755};
756
757static struct platform_driver dw_i2s_driver = {
758	.probe		= dw_i2s_probe,
759	.remove		= dw_i2s_remove,
760	.driver		= {
761		.name	= "designware-i2s",
762		.of_match_table = of_match_ptr(dw_i2s_of_match),
763		.pm = &dwc_pm_ops,
764	},
765};
766
767module_platform_driver(dw_i2s_driver);
768
769MODULE_AUTHOR("Rajeev Kumar <rajeevkumar.linux@gmail.com>");
770MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
771MODULE_LICENSE("GPL");
772MODULE_ALIAS("platform:designware_i2s");
v5.9
  1/*
  2 * ALSA SoC Synopsys I2S Audio Layer
  3 *
  4 * sound/soc/dwc/designware_i2s.c
  5 *
  6 * Copyright (C) 2010 ST Microelectronics
  7 * Rajeev Kumar <rajeevkumar.linux@gmail.com>
  8 *
  9 * This file is licensed under the terms of the GNU General Public
 10 * License version 2. This program is licensed "as is" without any
 11 * warranty of any kind, whether express or implied.
 12 */
 13
 14#include <linux/clk.h>
 15#include <linux/device.h>
 16#include <linux/init.h>
 17#include <linux/io.h>
 18#include <linux/interrupt.h>
 19#include <linux/module.h>
 20#include <linux/slab.h>
 21#include <linux/pm_runtime.h>
 22#include <sound/designware_i2s.h>
 23#include <sound/pcm.h>
 24#include <sound/pcm_params.h>
 25#include <sound/soc.h>
 26#include <sound/dmaengine_pcm.h>
 27#include "local.h"
 28
 29static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
 30{
 31	writel(val, io_base + reg);
 32}
 33
 34static inline u32 i2s_read_reg(void __iomem *io_base, int reg)
 35{
 36	return readl(io_base + reg);
 37}
 38
 39static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream)
 40{
 41	u32 i = 0;
 42
 43	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 44		for (i = 0; i < 4; i++)
 45			i2s_write_reg(dev->i2s_base, TER(i), 0);
 46	} else {
 47		for (i = 0; i < 4; i++)
 48			i2s_write_reg(dev->i2s_base, RER(i), 0);
 49	}
 50}
 51
 52static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
 53{
 54	u32 i = 0;
 55
 56	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 57		for (i = 0; i < 4; i++)
 58			i2s_read_reg(dev->i2s_base, TOR(i));
 59	} else {
 60		for (i = 0; i < 4; i++)
 61			i2s_read_reg(dev->i2s_base, ROR(i));
 62	}
 63}
 64
 65static inline void i2s_disable_irqs(struct dw_i2s_dev *dev, u32 stream,
 66				    int chan_nr)
 67{
 68	u32 i, irq;
 69
 70	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 71		for (i = 0; i < (chan_nr / 2); i++) {
 72			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 73			i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
 74		}
 75	} else {
 76		for (i = 0; i < (chan_nr / 2); i++) {
 77			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 78			i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
 79		}
 80	}
 81}
 82
 83static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
 84				   int chan_nr)
 85{
 86	u32 i, irq;
 87
 88	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 89		for (i = 0; i < (chan_nr / 2); i++) {
 90			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 91			i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
 92		}
 93	} else {
 94		for (i = 0; i < (chan_nr / 2); i++) {
 95			irq = i2s_read_reg(dev->i2s_base, IMR(i));
 96			i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
 97		}
 98	}
 99}
100
101static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
102{
103	struct dw_i2s_dev *dev = dev_id;
104	bool irq_valid = false;
105	u32 isr[4];
106	int i;
107
108	for (i = 0; i < 4; i++)
109		isr[i] = i2s_read_reg(dev->i2s_base, ISR(i));
110
111	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_PLAYBACK);
112	i2s_clear_irqs(dev, SNDRV_PCM_STREAM_CAPTURE);
113
114	for (i = 0; i < 4; i++) {
115		/*
116		 * Check if TX fifo is empty. If empty fill FIFO with samples
117		 * NOTE: Only two channels supported
118		 */
119		if ((isr[i] & ISR_TXFE) && (i == 0) && dev->use_pio) {
120			dw_pcm_push_tx(dev);
121			irq_valid = true;
122		}
123
124		/*
125		 * Data available. Retrieve samples from FIFO
126		 * NOTE: Only two channels supported
127		 */
128		if ((isr[i] & ISR_RXDA) && (i == 0) && dev->use_pio) {
129			dw_pcm_pop_rx(dev);
130			irq_valid = true;
131		}
132
133		/* Error Handling: TX */
134		if (isr[i] & ISR_TXFO) {
135			dev_err(dev->dev, "TX overrun (ch_id=%d)\n", i);
136			irq_valid = true;
137		}
138
139		/* Error Handling: TX */
140		if (isr[i] & ISR_RXFO) {
141			dev_err(dev->dev, "RX overrun (ch_id=%d)\n", i);
142			irq_valid = true;
143		}
144	}
145
146	if (irq_valid)
147		return IRQ_HANDLED;
148	else
149		return IRQ_NONE;
150}
151
152static void i2s_start(struct dw_i2s_dev *dev,
153		      struct snd_pcm_substream *substream)
154{
155	struct i2s_clk_config_data *config = &dev->config;
156
157	i2s_write_reg(dev->i2s_base, IER, 1);
158	i2s_enable_irqs(dev, substream->stream, config->chan_nr);
159
160	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
161		i2s_write_reg(dev->i2s_base, ITER, 1);
162	else
163		i2s_write_reg(dev->i2s_base, IRER, 1);
164
165	i2s_write_reg(dev->i2s_base, CER, 1);
166}
167
168static void i2s_stop(struct dw_i2s_dev *dev,
169		struct snd_pcm_substream *substream)
170{
171
172	i2s_clear_irqs(dev, substream->stream);
173	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
174		i2s_write_reg(dev->i2s_base, ITER, 0);
175	else
176		i2s_write_reg(dev->i2s_base, IRER, 0);
177
178	i2s_disable_irqs(dev, substream->stream, 8);
179
180	if (!dev->active) {
181		i2s_write_reg(dev->i2s_base, CER, 0);
182		i2s_write_reg(dev->i2s_base, IER, 0);
183	}
184}
185
186static int dw_i2s_startup(struct snd_pcm_substream *substream,
187		struct snd_soc_dai *cpu_dai)
188{
189	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
190	union dw_i2s_snd_dma_data *dma_data = NULL;
191
192	if (!(dev->capability & DWC_I2S_RECORD) &&
193			(substream->stream == SNDRV_PCM_STREAM_CAPTURE))
194		return -EINVAL;
195
196	if (!(dev->capability & DWC_I2S_PLAY) &&
197			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
198		return -EINVAL;
199
200	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
201		dma_data = &dev->play_dma_data;
202	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
203		dma_data = &dev->capture_dma_data;
204
205	snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data);
206
207	return 0;
208}
209
210static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
211{
212	u32 ch_reg;
213	struct i2s_clk_config_data *config = &dev->config;
214
215
216	i2s_disable_channels(dev, stream);
217
218	for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) {
219		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
220			i2s_write_reg(dev->i2s_base, TCR(ch_reg),
221				      dev->xfer_resolution);
222			i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
223				      dev->fifo_th - 1);
224			i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
225		} else {
226			i2s_write_reg(dev->i2s_base, RCR(ch_reg),
227				      dev->xfer_resolution);
228			i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
229				      dev->fifo_th - 1);
230			i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
231		}
232
233	}
234}
235
236static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
237		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
238{
239	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
240	struct i2s_clk_config_data *config = &dev->config;
241	int ret;
242
243	switch (params_format(params)) {
244	case SNDRV_PCM_FORMAT_S16_LE:
245		config->data_width = 16;
246		dev->ccr = 0x00;
247		dev->xfer_resolution = 0x02;
248		break;
249
250	case SNDRV_PCM_FORMAT_S24_LE:
251		config->data_width = 24;
252		dev->ccr = 0x08;
253		dev->xfer_resolution = 0x04;
254		break;
255
256	case SNDRV_PCM_FORMAT_S32_LE:
257		config->data_width = 32;
258		dev->ccr = 0x10;
259		dev->xfer_resolution = 0x05;
260		break;
261
262	default:
263		dev_err(dev->dev, "designware-i2s: unsupported PCM fmt");
264		return -EINVAL;
265	}
266
267	config->chan_nr = params_channels(params);
268
269	switch (config->chan_nr) {
270	case EIGHT_CHANNEL_SUPPORT:
271	case SIX_CHANNEL_SUPPORT:
272	case FOUR_CHANNEL_SUPPORT:
273	case TWO_CHANNEL_SUPPORT:
274		break;
275	default:
276		dev_err(dev->dev, "channel not supported\n");
277		return -EINVAL;
278	}
279
280	dw_i2s_config(dev, substream->stream);
281
282	i2s_write_reg(dev->i2s_base, CCR, dev->ccr);
283
284	config->sample_rate = params_rate(params);
285
286	if (dev->capability & DW_I2S_MASTER) {
287		if (dev->i2s_clk_cfg) {
288			ret = dev->i2s_clk_cfg(config);
289			if (ret < 0) {
290				dev_err(dev->dev, "runtime audio clk config fail\n");
291				return ret;
292			}
293		} else {
294			u32 bitclk = config->sample_rate *
295					config->data_width * 2;
296
297			ret = clk_set_rate(dev->clk, bitclk);
298			if (ret) {
299				dev_err(dev->dev, "Can't set I2S clock rate: %d\n",
300					ret);
301				return ret;
302			}
303		}
304	}
305	return 0;
306}
307
308static void dw_i2s_shutdown(struct snd_pcm_substream *substream,
309		struct snd_soc_dai *dai)
310{
311	snd_soc_dai_set_dma_data(dai, substream, NULL);
312}
313
314static int dw_i2s_prepare(struct snd_pcm_substream *substream,
315			  struct snd_soc_dai *dai)
316{
317	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
318
319	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
320		i2s_write_reg(dev->i2s_base, TXFFR, 1);
321	else
322		i2s_write_reg(dev->i2s_base, RXFFR, 1);
323
324	return 0;
325}
326
327static int dw_i2s_trigger(struct snd_pcm_substream *substream,
328		int cmd, struct snd_soc_dai *dai)
329{
330	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
331	int ret = 0;
332
333	switch (cmd) {
334	case SNDRV_PCM_TRIGGER_START:
335	case SNDRV_PCM_TRIGGER_RESUME:
336	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
337		dev->active++;
338		i2s_start(dev, substream);
339		break;
340
341	case SNDRV_PCM_TRIGGER_STOP:
342	case SNDRV_PCM_TRIGGER_SUSPEND:
343	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
344		dev->active--;
345		i2s_stop(dev, substream);
346		break;
347	default:
348		ret = -EINVAL;
349		break;
350	}
351	return ret;
352}
353
354static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
355{
356	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
357	int ret = 0;
358
359	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
360	case SND_SOC_DAIFMT_CBM_CFM:
361		if (dev->capability & DW_I2S_SLAVE)
362			ret = 0;
363		else
364			ret = -EINVAL;
365		break;
366	case SND_SOC_DAIFMT_CBS_CFS:
367		if (dev->capability & DW_I2S_MASTER)
368			ret = 0;
369		else
370			ret = -EINVAL;
371		break;
372	case SND_SOC_DAIFMT_CBM_CFS:
373	case SND_SOC_DAIFMT_CBS_CFM:
374		ret = -EINVAL;
375		break;
376	default:
377		dev_dbg(dev->dev, "dwc : Invalid master/slave format\n");
378		ret = -EINVAL;
379		break;
380	}
381	return ret;
382}
383
384static const struct snd_soc_dai_ops dw_i2s_dai_ops = {
385	.startup	= dw_i2s_startup,
386	.shutdown	= dw_i2s_shutdown,
387	.hw_params	= dw_i2s_hw_params,
388	.prepare	= dw_i2s_prepare,
389	.trigger	= dw_i2s_trigger,
390	.set_fmt	= dw_i2s_set_fmt,
391};
392
393#ifdef CONFIG_PM
394static int dw_i2s_runtime_suspend(struct device *dev)
395{
396	struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
397
398	if (dw_dev->capability & DW_I2S_MASTER)
399		clk_disable(dw_dev->clk);
400	return 0;
401}
402
403static int dw_i2s_runtime_resume(struct device *dev)
404{
405	struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
 
406
407	if (dw_dev->capability & DW_I2S_MASTER)
408		clk_enable(dw_dev->clk);
 
 
 
409	return 0;
410}
411
412static int dw_i2s_suspend(struct snd_soc_component *component)
413{
414	struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component);
415
416	if (dev->capability & DW_I2S_MASTER)
417		clk_disable(dev->clk);
418	return 0;
419}
420
421static int dw_i2s_resume(struct snd_soc_component *component)
422{
423	struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component);
424	struct snd_soc_dai *dai;
425	int stream;
426
427	if (dev->capability & DW_I2S_MASTER)
428		clk_enable(dev->clk);
 
 
 
429
430	for_each_component_dais(component, dai) {
431		for_each_pcm_streams(stream)
432			if (snd_soc_dai_stream_active(dai, stream))
433				dw_i2s_config(dev, stream);
434	}
435
436	return 0;
437}
438
439#else
440#define dw_i2s_suspend	NULL
441#define dw_i2s_resume	NULL
442#endif
443
444static const struct snd_soc_component_driver dw_i2s_component = {
445	.name		= "dw-i2s",
446	.suspend	= dw_i2s_suspend,
447	.resume		= dw_i2s_resume,
 
448};
449
450/*
451 * The following tables allow a direct lookup of various parameters
452 * defined in the I2S block's configuration in terms of sound system
453 * parameters.  Each table is sized to the number of entries possible
454 * according to the number of configuration bits describing an I2S
455 * block parameter.
456 */
457
458/* Maximum bit resolution of a channel - not uniformly spaced */
459static const u32 fifo_width[COMP_MAX_WORDSIZE] = {
460	12, 16, 20, 24, 32, 0, 0, 0
461};
462
463/* Width of (DMA) bus */
464static const u32 bus_widths[COMP_MAX_DATA_WIDTH] = {
465	DMA_SLAVE_BUSWIDTH_1_BYTE,
466	DMA_SLAVE_BUSWIDTH_2_BYTES,
467	DMA_SLAVE_BUSWIDTH_4_BYTES,
468	DMA_SLAVE_BUSWIDTH_UNDEFINED
469};
470
471/* PCM format to support channel resolution */
472static const u32 formats[COMP_MAX_WORDSIZE] = {
473	SNDRV_PCM_FMTBIT_S16_LE,
474	SNDRV_PCM_FMTBIT_S16_LE,
475	SNDRV_PCM_FMTBIT_S24_LE,
476	SNDRV_PCM_FMTBIT_S24_LE,
477	SNDRV_PCM_FMTBIT_S32_LE,
478	0,
479	0,
480	0
481};
482
483static int dw_configure_dai(struct dw_i2s_dev *dev,
484				   struct snd_soc_dai_driver *dw_i2s_dai,
485				   unsigned int rates)
486{
487	/*
488	 * Read component parameter registers to extract
489	 * the I2S block's configuration.
490	 */
491	u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
492	u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2);
493	u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
494	u32 idx;
495
496	if (dev->capability & DWC_I2S_RECORD &&
497			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
498		comp1 = comp1 & ~BIT(5);
499
500	if (dev->capability & DWC_I2S_PLAY &&
501			dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
502		comp1 = comp1 & ~BIT(6);
503
504	if (COMP1_TX_ENABLED(comp1)) {
505		dev_dbg(dev->dev, " designware: play supported\n");
506		idx = COMP1_TX_WORDSIZE_0(comp1);
507		if (WARN_ON(idx >= ARRAY_SIZE(formats)))
508			return -EINVAL;
509		if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
510			idx = 1;
511		dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
512		dw_i2s_dai->playback.channels_max =
513				1 << (COMP1_TX_CHANNELS(comp1) + 1);
514		dw_i2s_dai->playback.formats = formats[idx];
515		dw_i2s_dai->playback.rates = rates;
516	}
517
518	if (COMP1_RX_ENABLED(comp1)) {
519		dev_dbg(dev->dev, "designware: record supported\n");
520		idx = COMP2_RX_WORDSIZE_0(comp2);
521		if (WARN_ON(idx >= ARRAY_SIZE(formats)))
522			return -EINVAL;
523		if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
524			idx = 1;
525		dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
526		dw_i2s_dai->capture.channels_max =
527				1 << (COMP1_RX_CHANNELS(comp1) + 1);
528		dw_i2s_dai->capture.formats = formats[idx];
529		dw_i2s_dai->capture.rates = rates;
530	}
531
532	if (COMP1_MODE_EN(comp1)) {
533		dev_dbg(dev->dev, "designware: i2s master mode supported\n");
534		dev->capability |= DW_I2S_MASTER;
535	} else {
536		dev_dbg(dev->dev, "designware: i2s slave mode supported\n");
537		dev->capability |= DW_I2S_SLAVE;
538	}
539
540	dev->fifo_th = fifo_depth / 2;
541	return 0;
542}
543
544static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev,
545				   struct snd_soc_dai_driver *dw_i2s_dai,
546				   struct resource *res,
547				   const struct i2s_platform_data *pdata)
548{
549	u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
550	u32 idx = COMP1_APB_DATA_WIDTH(comp1);
551	int ret;
552
553	if (WARN_ON(idx >= ARRAY_SIZE(bus_widths)))
554		return -EINVAL;
555
556	ret = dw_configure_dai(dev, dw_i2s_dai, pdata->snd_rates);
557	if (ret < 0)
558		return ret;
559
560	if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE)
561		idx = 1;
562	/* Set DMA slaves info */
563	dev->play_dma_data.pd.data = pdata->play_dma_data;
564	dev->capture_dma_data.pd.data = pdata->capture_dma_data;
565	dev->play_dma_data.pd.addr = res->start + I2S_TXDMA;
566	dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA;
567	dev->play_dma_data.pd.max_burst = 16;
568	dev->capture_dma_data.pd.max_burst = 16;
569	dev->play_dma_data.pd.addr_width = bus_widths[idx];
570	dev->capture_dma_data.pd.addr_width = bus_widths[idx];
571	dev->play_dma_data.pd.filter = pdata->filter;
572	dev->capture_dma_data.pd.filter = pdata->filter;
573
574	return 0;
575}
576
577static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev,
578				   struct snd_soc_dai_driver *dw_i2s_dai,
579				   struct resource *res)
580{
581	u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1);
582	u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2);
583	u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
584	u32 idx = COMP1_APB_DATA_WIDTH(comp1);
585	u32 idx2;
586	int ret;
587
588	if (WARN_ON(idx >= ARRAY_SIZE(bus_widths)))
589		return -EINVAL;
590
591	ret = dw_configure_dai(dev, dw_i2s_dai, SNDRV_PCM_RATE_8000_192000);
592	if (ret < 0)
593		return ret;
594
595	if (COMP1_TX_ENABLED(comp1)) {
596		idx2 = COMP1_TX_WORDSIZE_0(comp1);
597
598		dev->capability |= DWC_I2S_PLAY;
599		dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
600		dev->play_dma_data.dt.addr_width = bus_widths[idx];
601		dev->play_dma_data.dt.fifo_size = fifo_depth *
602			(fifo_width[idx2]) >> 8;
603		dev->play_dma_data.dt.maxburst = 16;
604	}
605	if (COMP1_RX_ENABLED(comp1)) {
606		idx2 = COMP2_RX_WORDSIZE_0(comp2);
607
608		dev->capability |= DWC_I2S_RECORD;
609		dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
610		dev->capture_dma_data.dt.addr_width = bus_widths[idx];
611		dev->capture_dma_data.dt.fifo_size = fifo_depth *
612			(fifo_width[idx2] >> 8);
613		dev->capture_dma_data.dt.maxburst = 16;
614	}
615
616	return 0;
617
618}
619
620static int dw_i2s_probe(struct platform_device *pdev)
621{
622	const struct i2s_platform_data *pdata = pdev->dev.platform_data;
623	struct dw_i2s_dev *dev;
624	struct resource *res;
625	int ret, irq;
626	struct snd_soc_dai_driver *dw_i2s_dai;
627	const char *clk_id;
628
629	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
630	if (!dev)
631		return -ENOMEM;
632
633	dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
634	if (!dw_i2s_dai)
635		return -ENOMEM;
636
637	dw_i2s_dai->ops = &dw_i2s_dai_ops;
638
639	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
640	dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
641	if (IS_ERR(dev->i2s_base))
642		return PTR_ERR(dev->i2s_base);
643
644	dev->dev = &pdev->dev;
645
646	irq = platform_get_irq(pdev, 0);
647	if (irq >= 0) {
648		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
649				pdev->name, dev);
650		if (ret < 0) {
651			dev_err(&pdev->dev, "failed to request irq\n");
652			return ret;
653		}
654	}
655
656	dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
657	dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
658	if (pdata) {
659		dev->capability = pdata->cap;
660		clk_id = NULL;
661		dev->quirks = pdata->quirks;
662		if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
663			dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
664			dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
665		}
666		ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
667	} else {
668		clk_id = "i2sclk";
669		ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
670	}
671	if (ret < 0)
672		return ret;
673
674	if (dev->capability & DW_I2S_MASTER) {
675		if (pdata) {
676			dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
677			if (!dev->i2s_clk_cfg) {
678				dev_err(&pdev->dev, "no clock configure method\n");
679				return -ENODEV;
680			}
681		}
682		dev->clk = devm_clk_get(&pdev->dev, clk_id);
683
684		if (IS_ERR(dev->clk))
685			return PTR_ERR(dev->clk);
686
687		ret = clk_prepare_enable(dev->clk);
688		if (ret < 0)
689			return ret;
690	}
691
692	dev_set_drvdata(&pdev->dev, dev);
693	ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component,
694					 dw_i2s_dai, 1);
695	if (ret != 0) {
696		dev_err(&pdev->dev, "not able to register dai\n");
697		goto err_clk_disable;
698	}
699
700	if (!pdata) {
701		if (irq >= 0) {
702			ret = dw_pcm_register(pdev);
703			dev->use_pio = true;
704		} else {
705			ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
706					0);
707			dev->use_pio = false;
708		}
709
710		if (ret) {
711			dev_err(&pdev->dev, "could not register pcm: %d\n",
712					ret);
713			goto err_clk_disable;
714		}
715	}
716
717	pm_runtime_enable(&pdev->dev);
718	return 0;
719
720err_clk_disable:
721	if (dev->capability & DW_I2S_MASTER)
722		clk_disable_unprepare(dev->clk);
723	return ret;
724}
725
726static int dw_i2s_remove(struct platform_device *pdev)
727{
728	struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
729
730	if (dev->capability & DW_I2S_MASTER)
731		clk_disable_unprepare(dev->clk);
732
733	pm_runtime_disable(&pdev->dev);
734	return 0;
735}
736
737#ifdef CONFIG_OF
738static const struct of_device_id dw_i2s_of_match[] = {
739	{ .compatible = "snps,designware-i2s",	 },
740	{},
741};
742
743MODULE_DEVICE_TABLE(of, dw_i2s_of_match);
744#endif
745
746static const struct dev_pm_ops dwc_pm_ops = {
747	SET_RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL)
748};
749
750static struct platform_driver dw_i2s_driver = {
751	.probe		= dw_i2s_probe,
752	.remove		= dw_i2s_remove,
753	.driver		= {
754		.name	= "designware-i2s",
755		.of_match_table = of_match_ptr(dw_i2s_of_match),
756		.pm = &dwc_pm_ops,
757	},
758};
759
760module_platform_driver(dw_i2s_driver);
761
762MODULE_AUTHOR("Rajeev Kumar <rajeevkumar.linux@gmail.com>");
763MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
764MODULE_LICENSE("GPL");
765MODULE_ALIAS("platform:designware_i2s");