aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-11-08 05:43:37 -0500
committerMark Brown <broonie@linaro.org>2013-11-08 05:43:37 -0500
commitd4af6be4f87bf522cfb981c6582497a0f68d456e (patch)
tree0fa8c920eb7986c176a7ecd818b59657a36df84f /sound/soc
parentbe529a5b7f3490c9c57295cc8c9891a3ab94b250 (diff)
parent5e049fce368dfe07702c3664add9ae7b45df1a9a (diff)
Merge remote-tracking branch 'asoc/topic/tegra' into asoc-next
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/tegra/tegra30_ahub.c115
-rw-r--r--sound/soc/tegra/tegra30_ahub.h38
-rw-r--r--sound/soc/tegra/tegra30_i2s.c51
-rw-r--r--sound/soc/tegra/tegra30_i2s.h7
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c2
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h1
6 files changed, 186 insertions, 28 deletions
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index d554d46d08b5..bdd19db4a08b 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -100,6 +100,7 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
100{ 100{
101 int channel; 101 int channel;
102 u32 reg, val; 102 u32 reg, val;
103 struct tegra30_ahub_cif_conf cif_conf;
103 104
104 channel = find_first_zero_bit(ahub->rx_usage, 105 channel = find_first_zero_bit(ahub->rx_usage,
105 TEGRA30_AHUB_CHANNEL_CTRL_COUNT); 106 TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
@@ -123,15 +124,21 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
123 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16; 124 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16;
124 tegra30_apbif_write(reg, val); 125 tegra30_apbif_write(reg, val);
125 126
127 cif_conf.threshold = 0;
128 cif_conf.audio_channels = 2;
129 cif_conf.client_channels = 2;
130 cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16;
131 cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16;
132 cif_conf.expand = 0;
133 cif_conf.stereo_conv = 0;
134 cif_conf.replicate = 0;
135 cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_RX;
136 cif_conf.truncate = 0;
137 cif_conf.mono_conv = 0;
138
126 reg = TEGRA30_AHUB_CIF_RX_CTRL + 139 reg = TEGRA30_AHUB_CIF_RX_CTRL +
127 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); 140 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
128 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | 141 ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
129 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
130 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
131 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 |
132 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16 |
133 TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
134 tegra30_apbif_write(reg, val);
135 142
136 return 0; 143 return 0;
137} 144}
@@ -183,6 +190,7 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
183{ 190{
184 int channel; 191 int channel;
185 u32 reg, val; 192 u32 reg, val;
193 struct tegra30_ahub_cif_conf cif_conf;
186 194
187 channel = find_first_zero_bit(ahub->tx_usage, 195 channel = find_first_zero_bit(ahub->tx_usage,
188 TEGRA30_AHUB_CHANNEL_CTRL_COUNT); 196 TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
@@ -206,15 +214,21 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
206 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16; 214 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16;
207 tegra30_apbif_write(reg, val); 215 tegra30_apbif_write(reg, val);
208 216
217 cif_conf.threshold = 0;
218 cif_conf.audio_channels = 2;
219 cif_conf.client_channels = 2;
220 cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16;
221 cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16;
222 cif_conf.expand = 0;
223 cif_conf.stereo_conv = 0;
224 cif_conf.replicate = 0;
225 cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_TX;
226 cif_conf.truncate = 0;
227 cif_conf.mono_conv = 0;
228
209 reg = TEGRA30_AHUB_CIF_TX_CTRL + 229 reg = TEGRA30_AHUB_CIF_TX_CTRL +
210 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE); 230 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
211 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | 231 ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
212 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
213 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
214 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 |
215 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16 |
216 TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
217 tegra30_apbif_write(reg, val);
218 232
219 return 0; 233 return 0;
220} 234}
@@ -437,13 +451,21 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
437 451
438static struct tegra30_ahub_soc_data soc_data_tegra30 = { 452static struct tegra30_ahub_soc_data soc_data_tegra30 = {
439 .clk_list_mask = CLK_LIST_MASK_TEGRA30, 453 .clk_list_mask = CLK_LIST_MASK_TEGRA30,
454 .set_audio_cif = tegra30_ahub_set_cif,
440}; 455};
441 456
442static struct tegra30_ahub_soc_data soc_data_tegra114 = { 457static struct tegra30_ahub_soc_data soc_data_tegra114 = {
443 .clk_list_mask = CLK_LIST_MASK_TEGRA114, 458 .clk_list_mask = CLK_LIST_MASK_TEGRA114,
459 .set_audio_cif = tegra30_ahub_set_cif,
460};
461
462static struct tegra30_ahub_soc_data soc_data_tegra124 = {
463 .clk_list_mask = CLK_LIST_MASK_TEGRA114,
464 .set_audio_cif = tegra124_ahub_set_cif,
444}; 465};
445 466
446static const struct of_device_id tegra30_ahub_of_match[] = { 467static const struct of_device_id tegra30_ahub_of_match[] = {
468 { .compatible = "nvidia,tegra124-ahub", .data = &soc_data_tegra124 },
447 { .compatible = "nvidia,tegra114-ahub", .data = &soc_data_tegra114 }, 469 { .compatible = "nvidia,tegra114-ahub", .data = &soc_data_tegra114 },
448 { .compatible = "nvidia,tegra30-ahub", .data = &soc_data_tegra30 }, 470 { .compatible = "nvidia,tegra30-ahub", .data = &soc_data_tegra30 },
449 {}, 471 {},
@@ -497,6 +519,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
497 } 519 }
498 dev_set_drvdata(&pdev->dev, ahub); 520 dev_set_drvdata(&pdev->dev, ahub);
499 521
522 ahub->soc_data = soc_data;
500 ahub->dev = &pdev->dev; 523 ahub->dev = &pdev->dev;
501 524
502 ahub->clk_d_audio = clk_get(&pdev->dev, "d_audio"); 525 ahub->clk_d_audio = clk_get(&pdev->dev, "d_audio");
@@ -669,6 +692,70 @@ static struct platform_driver tegra30_ahub_driver = {
669}; 692};
670module_platform_driver(tegra30_ahub_driver); 693module_platform_driver(tegra30_ahub_driver);
671 694
695void tegra30_ahub_set_cif(struct regmap *regmap, unsigned int reg,
696 struct tegra30_ahub_cif_conf *conf)
697{
698 unsigned int value;
699
700 value = (conf->threshold <<
701 TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
702 ((conf->audio_channels - 1) <<
703 TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
704 ((conf->client_channels - 1) <<
705 TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
706 (conf->audio_bits <<
707 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) |
708 (conf->client_bits <<
709 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) |
710 (conf->expand <<
711 TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT) |
712 (conf->stereo_conv <<
713 TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) |
714 (conf->replicate <<
715 TEGRA30_AUDIOCIF_CTRL_REPLICATE_SHIFT) |
716 (conf->direction <<
717 TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT) |
718 (conf->truncate <<
719 TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT) |
720 (conf->mono_conv <<
721 TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT);
722
723 regmap_write(regmap, reg, value);
724}
725EXPORT_SYMBOL_GPL(tegra30_ahub_set_cif);
726
727void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg,
728 struct tegra30_ahub_cif_conf *conf)
729{
730 unsigned int value;
731
732 value = (conf->threshold <<
733 TEGRA124_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
734 ((conf->audio_channels - 1) <<
735 TEGRA124_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
736 ((conf->client_channels - 1) <<
737 TEGRA124_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
738 (conf->audio_bits <<
739 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) |
740 (conf->client_bits <<
741 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) |
742 (conf->expand <<
743 TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT) |
744 (conf->stereo_conv <<
745 TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) |
746 (conf->replicate <<
747 TEGRA30_AUDIOCIF_CTRL_REPLICATE_SHIFT) |
748 (conf->direction <<
749 TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT) |
750 (conf->truncate <<
751 TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT) |
752 (conf->mono_conv <<
753 TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT);
754
755 regmap_write(regmap, reg, value);
756}
757EXPORT_SYMBOL_GPL(tegra124_ahub_set_cif);
758
672MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 759MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
673MODULE_DESCRIPTION("Tegra30 AHUB driver"); 760MODULE_DESCRIPTION("Tegra30 AHUB driver");
674MODULE_LICENSE("GPL v2"); 761MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h
index 09766cdc45ca..d67321d90faa 100644
--- a/sound/soc/tegra/tegra30_ahub.h
+++ b/sound/soc/tegra/tegra30_ahub.h
@@ -25,16 +25,30 @@
25#define TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US 0xf 25#define TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US 0xf
26#define TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK (TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) 26#define TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK (TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT)
27 27
28#define TEGRA124_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT 24
29#define TEGRA124_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US 0x3f
30#define TEGRA124_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK (TEGRA124_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US << TEGRA124_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT)
31
28/* Channel count minus 1 */ 32/* Channel count minus 1 */
29#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT 24 33#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT 24
30#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US 7 34#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US 7
31#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK (TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) 35#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK (TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT)
32 36
33/* Channel count minus 1 */ 37/* Channel count minus 1 */
38#define TEGRA124_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT 20
39#define TEGRA124_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US 0xf
40#define TEGRA124_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK (TEGRA124_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US << TEGRA124_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT)
41
42/* Channel count minus 1 */
34#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT 16 43#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT 16
35#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US 7 44#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US 7
36#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK (TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) 45#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK (TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT)
37 46
47/* Channel count minus 1 */
48#define TEGRA124_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT 16
49#define TEGRA124_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US 0xf
50#define TEGRA124_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK (TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT)
51
38#define TEGRA30_AUDIOCIF_BITS_4 0 52#define TEGRA30_AUDIOCIF_BITS_4 0
39#define TEGRA30_AUDIOCIF_BITS_8 1 53#define TEGRA30_AUDIOCIF_BITS_8 1
40#define TEGRA30_AUDIOCIF_BITS_12 2 54#define TEGRA30_AUDIOCIF_BITS_12 2
@@ -86,7 +100,7 @@
86#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_CH1 (TEGRA30_AUDIOCIF_STEREO_CONV_CH1 << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) 100#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_CH1 (TEGRA30_AUDIOCIF_STEREO_CONV_CH1 << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT)
87#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_AVG (TEGRA30_AUDIOCIF_STEREO_CONV_AVG << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) 101#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_AVG (TEGRA30_AUDIOCIF_STEREO_CONV_AVG << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT)
88 102
89#define TEGRA30_AUDIOCIF_CTRL_REPLICATE 3 103#define TEGRA30_AUDIOCIF_CTRL_REPLICATE_SHIFT 3
90 104
91#define TEGRA30_AUDIOCIF_DIRECTION_TX 0 105#define TEGRA30_AUDIOCIF_DIRECTION_TX 0
92#define TEGRA30_AUDIOCIF_DIRECTION_RX 1 106#define TEGRA30_AUDIOCIF_DIRECTION_RX 1
@@ -468,8 +482,30 @@ extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
468 enum tegra30_ahub_txcif txcif); 482 enum tegra30_ahub_txcif txcif);
469extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); 483extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif);
470 484
485struct tegra30_ahub_cif_conf {
486 unsigned int threshold;
487 unsigned int audio_channels;
488 unsigned int client_channels;
489 unsigned int audio_bits;
490 unsigned int client_bits;
491 unsigned int expand;
492 unsigned int stereo_conv;
493 unsigned int replicate;
494 unsigned int direction;
495 unsigned int truncate;
496 unsigned int mono_conv;
497};
498
499void tegra30_ahub_set_cif(struct regmap *regmap, unsigned int reg,
500 struct tegra30_ahub_cif_conf *conf);
501void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg,
502 struct tegra30_ahub_cif_conf *conf);
503
471struct tegra30_ahub_soc_data { 504struct tegra30_ahub_soc_data {
472 u32 clk_list_mask; 505 u32 clk_list_mask;
506 void (*set_audio_cif)(struct regmap *regmap,
507 unsigned int reg,
508 struct tegra30_ahub_cif_conf *conf);
473 /* 509 /*
474 * FIXME: There are many more differences in HW, such as: 510 * FIXME: There are many more differences in HW, such as:
475 * - More APBIF channels. 511 * - More APBIF channels.
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 47565fd04505..5f20b695eba2 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -30,6 +30,7 @@
30#include <linux/io.h> 30#include <linux/io.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/of.h> 32#include <linux/of.h>
33#include <linux/of_device.h>
33#include <linux/platform_device.h> 34#include <linux/platform_device.h>
34#include <linux/pm_runtime.h> 35#include <linux/pm_runtime.h>
35#include <linux/regmap.h> 36#include <linux/regmap.h>
@@ -179,6 +180,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
179 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 180 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
180 unsigned int mask, val, reg; 181 unsigned int mask, val, reg;
181 int ret, sample_size, srate, i2sclock, bitcnt; 182 int ret, sample_size, srate, i2sclock, bitcnt;
183 struct tegra30_ahub_cif_conf cif_conf;
182 184
183 if (params_channels(params) != 2) 185 if (params_channels(params) != 2)
184 return -EINVAL; 186 return -EINVAL;
@@ -217,21 +219,26 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
217 219
218 regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val); 220 regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val);
219 221
220 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | 222 cif_conf.threshold = 0;
221 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | 223 cif_conf.audio_channels = 2;
222 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) | 224 cif_conf.client_channels = 2;
223 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 | 225 cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16;
224 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16; 226 cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16;
227 cif_conf.expand = 0;
228 cif_conf.stereo_conv = 0;
229 cif_conf.replicate = 0;
230 cif_conf.truncate = 0;
231 cif_conf.mono_conv = 0;
225 232
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 233 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
227 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; 234 cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_RX;
228 reg = TEGRA30_I2S_CIF_RX_CTRL; 235 reg = TEGRA30_I2S_CIF_RX_CTRL;
229 } else { 236 } else {
230 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; 237 cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_TX;
231 reg = TEGRA30_I2S_CIF_TX_CTRL; 238 reg = TEGRA30_I2S_CIF_TX_CTRL;
232 } 239 }
233 240
234 regmap_write(i2s->regmap, reg, val); 241 i2s->soc_data->set_audio_cif(i2s->regmap, reg, &cif_conf);
235 242
236 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | 243 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) |
237 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); 244 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
@@ -396,9 +403,24 @@ static const struct regmap_config tegra30_i2s_regmap_config = {
396 .cache_type = REGCACHE_RBTREE, 403 .cache_type = REGCACHE_RBTREE,
397}; 404};
398 405
406static const struct tegra30_i2s_soc_data tegra30_i2s_config = {
407 .set_audio_cif = tegra30_ahub_set_cif,
408};
409
410static const struct tegra30_i2s_soc_data tegra124_i2s_config = {
411 .set_audio_cif = tegra124_ahub_set_cif,
412};
413
414static const struct of_device_id tegra30_i2s_of_match[] = {
415 { .compatible = "nvidia,tegra124-i2s", .data = &tegra124_i2s_config },
416 { .compatible = "nvidia,tegra30-i2s", .data = &tegra30_i2s_config },
417 {},
418};
419
399static int tegra30_i2s_platform_probe(struct platform_device *pdev) 420static int tegra30_i2s_platform_probe(struct platform_device *pdev)
400{ 421{
401 struct tegra30_i2s *i2s; 422 struct tegra30_i2s *i2s;
423 const struct of_device_id *match;
402 u32 cif_ids[2]; 424 u32 cif_ids[2];
403 struct resource *mem, *memregion; 425 struct resource *mem, *memregion;
404 void __iomem *regs; 426 void __iomem *regs;
@@ -412,6 +434,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
412 } 434 }
413 dev_set_drvdata(&pdev->dev, i2s); 435 dev_set_drvdata(&pdev->dev, i2s);
414 436
437 match = of_match_device(tegra30_i2s_of_match, &pdev->dev);
438 if (!match) {
439 dev_err(&pdev->dev, "Error: No device match found\n");
440 ret = -ENODEV;
441 goto err;
442 }
443 i2s->soc_data = (struct tegra30_i2s_soc_data *)match->data;
444
415 i2s->dai = tegra30_i2s_dai_template; 445 i2s->dai = tegra30_i2s_dai_template;
416 i2s->dai.name = dev_name(&pdev->dev); 446 i2s->dai.name = dev_name(&pdev->dev);
417 447
@@ -539,11 +569,6 @@ static int tegra30_i2s_resume(struct device *dev)
539} 569}
540#endif 570#endif
541 571
542static const struct of_device_id tegra30_i2s_of_match[] = {
543 { .compatible = "nvidia,tegra30-i2s", },
544 {},
545};
546
547static const struct dev_pm_ops tegra30_i2s_pm_ops = { 572static const struct dev_pm_ops tegra30_i2s_pm_ops = {
548 SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, 573 SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend,
549 tegra30_i2s_runtime_resume, NULL) 574 tegra30_i2s_runtime_resume, NULL)
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index bea23afe3b9f..4d0b0a30dbfb 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -225,7 +225,14 @@
225#define TEGRA30_I2S_LCOEF_COEF_MASK_US 0xffff 225#define TEGRA30_I2S_LCOEF_COEF_MASK_US 0xffff
226#define TEGRA30_I2S_LCOEF_COEF_MASK (TEGRA30_I2S_LCOEF_COEF_MASK_US << TEGRA30_I2S_LCOEF_COEF_SHIFT) 226#define TEGRA30_I2S_LCOEF_COEF_MASK (TEGRA30_I2S_LCOEF_COEF_MASK_US << TEGRA30_I2S_LCOEF_COEF_SHIFT)
227 227
228struct tegra30_i2s_soc_data {
229 void (*set_audio_cif)(struct regmap *regmap,
230 unsigned int reg,
231 struct tegra30_ahub_cif_conf *conf);
232};
233
228struct tegra30_i2s { 234struct tegra30_i2s {
235 const struct tegra30_i2s_soc_data *soc_data;
229 struct snd_soc_dai_driver dai; 236 struct snd_soc_dai_driver dai;
230 int cif_id; 237 int cif_id;
231 struct clk *clk_i2s; 238 struct clk *clk_i2s;
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index d173880f290d..1be311c51a18 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -182,6 +182,8 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
182 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; 182 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
183 else if (of_machine_is_compatible("nvidia,tegra114")) 183 else if (of_machine_is_compatible("nvidia,tegra114"))
184 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114; 184 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114;
185 else if (of_machine_is_compatible("nvidia,tegra124"))
186 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA124;
185 else { 187 else {
186 dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n"); 188 dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n");
187 return -EINVAL; 189 return -EINVAL;
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index 19fdcafed32f..9577121ce971 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -30,6 +30,7 @@ enum tegra_asoc_utils_soc {
30 TEGRA_ASOC_UTILS_SOC_TEGRA20, 30 TEGRA_ASOC_UTILS_SOC_TEGRA20,
31 TEGRA_ASOC_UTILS_SOC_TEGRA30, 31 TEGRA_ASOC_UTILS_SOC_TEGRA30,
32 TEGRA_ASOC_UTILS_SOC_TEGRA114, 32 TEGRA_ASOC_UTILS_SOC_TEGRA114,
33 TEGRA_ASOC_UTILS_SOC_TEGRA124,
33}; 34};
34 35
35struct tegra_asoc_utils_data { 36struct tegra_asoc_utils_data {