diff options
author | Mark Brown <broonie@linaro.org> | 2013-11-08 05:43:37 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-11-08 05:43:37 -0500 |
commit | d4af6be4f87bf522cfb981c6582497a0f68d456e (patch) | |
tree | 0fa8c920eb7986c176a7ecd818b59657a36df84f /sound/soc | |
parent | be529a5b7f3490c9c57295cc8c9891a3ab94b250 (diff) | |
parent | 5e049fce368dfe07702c3664add9ae7b45df1a9a (diff) |
Merge remote-tracking branch 'asoc/topic/tegra' into asoc-next
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/tegra/tegra30_ahub.c | 115 | ||||
-rw-r--r-- | sound/soc/tegra/tegra30_ahub.h | 38 | ||||
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.c | 51 | ||||
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.h | 7 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_asoc_utils.c | 2 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_asoc_utils.h | 1 |
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 | ||
438 | static struct tegra30_ahub_soc_data soc_data_tegra30 = { | 452 | static 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 | ||
442 | static struct tegra30_ahub_soc_data soc_data_tegra114 = { | 457 | static 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 | |||
462 | static 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 | ||
446 | static const struct of_device_id tegra30_ahub_of_match[] = { | 467 | static 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 | }; |
670 | module_platform_driver(tegra30_ahub_driver); | 693 | module_platform_driver(tegra30_ahub_driver); |
671 | 694 | ||
695 | void 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 | } | ||
725 | EXPORT_SYMBOL_GPL(tegra30_ahub_set_cif); | ||
726 | |||
727 | void 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 | } | ||
757 | EXPORT_SYMBOL_GPL(tegra124_ahub_set_cif); | ||
758 | |||
672 | MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); | 759 | MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); |
673 | MODULE_DESCRIPTION("Tegra30 AHUB driver"); | 760 | MODULE_DESCRIPTION("Tegra30 AHUB driver"); |
674 | MODULE_LICENSE("GPL v2"); | 761 | MODULE_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); |
469 | extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); | 483 | extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); |
470 | 484 | ||
485 | struct 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 | |||
499 | void tegra30_ahub_set_cif(struct regmap *regmap, unsigned int reg, | ||
500 | struct tegra30_ahub_cif_conf *conf); | ||
501 | void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg, | ||
502 | struct tegra30_ahub_cif_conf *conf); | ||
503 | |||
471 | struct tegra30_ahub_soc_data { | 504 | struct 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 | ||
406 | static const struct tegra30_i2s_soc_data tegra30_i2s_config = { | ||
407 | .set_audio_cif = tegra30_ahub_set_cif, | ||
408 | }; | ||
409 | |||
410 | static const struct tegra30_i2s_soc_data tegra124_i2s_config = { | ||
411 | .set_audio_cif = tegra124_ahub_set_cif, | ||
412 | }; | ||
413 | |||
414 | static 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 | |||
399 | static int tegra30_i2s_platform_probe(struct platform_device *pdev) | 420 | static 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 | ||
542 | static const struct of_device_id tegra30_i2s_of_match[] = { | ||
543 | { .compatible = "nvidia,tegra30-i2s", }, | ||
544 | {}, | ||
545 | }; | ||
546 | |||
547 | static const struct dev_pm_ops tegra30_i2s_pm_ops = { | 572 | static 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 | ||
228 | struct 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 | |||
228 | struct tegra30_i2s { | 234 | struct 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 | ||
35 | struct tegra_asoc_utils_data { | 36 | struct tegra_asoc_utils_data { |