diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-07-19 02:03:20 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-07-19 02:03:20 -0400 |
commit | 4609ed6b1f0ab9f11a9d0361573b53d9d057c440 (patch) | |
tree | 802119cc6ddea286bc03d56431286ac52166352e /sound/soc/tegra/tegra20_i2s.c | |
parent | 639aa4bd58582f3015ae5621b7e9e754dcb58e6b (diff) | |
parent | 409b78cc17a4a3d07a541037575da648ced99437 (diff) |
Merge tag 'asoc-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for 3.6
This has been a pretty quiet release - very little activity in framework
terms, mostly just a few new drivers and updates:
- Added the ability to add and remove DAPM paths dynamically, mostly for
reparenting on clock changes.
- New machine drivers for Marvell Brownstone, ST-Ericsson Ux500
reference platform and ttc-dkp.
- New CPU drivers for Blackfin BF6xx SPORTs in I2S mode, Marvell MMP,
Synopsis Designware I2S controllers, and SPEAr DMA and S/PDIF
- New CODEC drivers for Dialog DA732x, ST STA529, ST-Ericsson AB8500, TI
Isabelle and Wolfson Microelectronics WM5102 and WM5110
Diffstat (limited to 'sound/soc/tegra/tegra20_i2s.c')
-rw-r--r-- | sound/soc/tegra/tegra20_i2s.c | 94 |
1 files changed, 46 insertions, 48 deletions
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 0c7af63d444b..c5fc6b1404f6 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c | |||
@@ -46,18 +46,6 @@ | |||
46 | 46 | ||
47 | #define DRV_NAME "tegra20-i2s" | 47 | #define DRV_NAME "tegra20-i2s" |
48 | 48 | ||
49 | static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val) | ||
50 | { | ||
51 | regmap_write(i2s->regmap, reg, val); | ||
52 | } | ||
53 | |||
54 | static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg) | ||
55 | { | ||
56 | u32 val; | ||
57 | regmap_read(i2s->regmap, reg, &val); | ||
58 | return val; | ||
59 | } | ||
60 | |||
61 | static int tegra20_i2s_runtime_suspend(struct device *dev) | 49 | static int tegra20_i2s_runtime_suspend(struct device *dev) |
62 | { | 50 | { |
63 | struct tegra20_i2s *i2s = dev_get_drvdata(dev); | 51 | struct tegra20_i2s *i2s = dev_get_drvdata(dev); |
@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
85 | unsigned int fmt) | 73 | unsigned int fmt) |
86 | { | 74 | { |
87 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 75 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
76 | unsigned int mask, val; | ||
88 | 77 | ||
89 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 78 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
90 | case SND_SOC_DAIFMT_NB_NF: | 79 | case SND_SOC_DAIFMT_NB_NF: |
@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
93 | return -EINVAL; | 82 | return -EINVAL; |
94 | } | 83 | } |
95 | 84 | ||
96 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; | 85 | mask = TEGRA20_I2S_CTRL_MASTER_ENABLE; |
97 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 86 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
98 | case SND_SOC_DAIFMT_CBS_CFS: | 87 | case SND_SOC_DAIFMT_CBS_CFS: |
99 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; | 88 | val = TEGRA20_I2S_CTRL_MASTER_ENABLE; |
100 | break; | 89 | break; |
101 | case SND_SOC_DAIFMT_CBM_CFM: | 90 | case SND_SOC_DAIFMT_CBM_CFM: |
102 | break; | 91 | break; |
@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
104 | return -EINVAL; | 93 | return -EINVAL; |
105 | } | 94 | } |
106 | 95 | ||
107 | i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | | 96 | mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | |
108 | TEGRA20_I2S_CTRL_LRCK_MASK); | 97 | TEGRA20_I2S_CTRL_LRCK_MASK; |
109 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 98 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
110 | case SND_SOC_DAIFMT_DSP_A: | 99 | case SND_SOC_DAIFMT_DSP_A: |
111 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; | 100 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; |
112 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 101 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
113 | break; | 102 | break; |
114 | case SND_SOC_DAIFMT_DSP_B: | 103 | case SND_SOC_DAIFMT_DSP_B: |
115 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; | 104 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; |
116 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; | 105 | val |= TEGRA20_I2S_CTRL_LRCK_R_LOW; |
117 | break; | 106 | break; |
118 | case SND_SOC_DAIFMT_I2S: | 107 | case SND_SOC_DAIFMT_I2S: |
119 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; | 108 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; |
120 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 109 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
121 | break; | 110 | break; |
122 | case SND_SOC_DAIFMT_RIGHT_J: | 111 | case SND_SOC_DAIFMT_RIGHT_J: |
123 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; | 112 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; |
124 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 113 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
125 | break; | 114 | break; |
126 | case SND_SOC_DAIFMT_LEFT_J: | 115 | case SND_SOC_DAIFMT_LEFT_J: |
127 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; | 116 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; |
128 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 117 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
129 | break; | 118 | break; |
130 | default: | 119 | default: |
131 | return -EINVAL; | 120 | return -EINVAL; |
132 | } | 121 | } |
133 | 122 | ||
123 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); | ||
124 | |||
134 | return 0; | 125 | return 0; |
135 | } | 126 | } |
136 | 127 | ||
@@ -138,29 +129,34 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, | |||
138 | struct snd_pcm_hw_params *params, | 129 | struct snd_pcm_hw_params *params, |
139 | struct snd_soc_dai *dai) | 130 | struct snd_soc_dai *dai) |
140 | { | 131 | { |
141 | struct device *dev = substream->pcm->card->dev; | 132 | struct device *dev = dai->dev; |
142 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 133 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
143 | u32 reg; | 134 | unsigned int mask, val; |
144 | int ret, sample_size, srate, i2sclock, bitcnt; | 135 | int ret, sample_size, srate, i2sclock, bitcnt; |
145 | 136 | ||
146 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; | 137 | mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK; |
147 | switch (params_format(params)) { | 138 | switch (params_format(params)) { |
148 | case SNDRV_PCM_FORMAT_S16_LE: | 139 | case SNDRV_PCM_FORMAT_S16_LE: |
149 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; | 140 | val = TEGRA20_I2S_CTRL_BIT_SIZE_16; |
150 | sample_size = 16; | 141 | sample_size = 16; |
151 | break; | 142 | break; |
152 | case SNDRV_PCM_FORMAT_S24_LE: | 143 | case SNDRV_PCM_FORMAT_S24_LE: |
153 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; | 144 | val = TEGRA20_I2S_CTRL_BIT_SIZE_24; |
154 | sample_size = 24; | 145 | sample_size = 24; |
155 | break; | 146 | break; |
156 | case SNDRV_PCM_FORMAT_S32_LE: | 147 | case SNDRV_PCM_FORMAT_S32_LE: |
157 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; | 148 | val = TEGRA20_I2S_CTRL_BIT_SIZE_32; |
158 | sample_size = 32; | 149 | sample_size = 32; |
159 | break; | 150 | break; |
160 | default: | 151 | default: |
161 | return -EINVAL; | 152 | return -EINVAL; |
162 | } | 153 | } |
163 | 154 | ||
155 | mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK; | ||
156 | val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; | ||
157 | |||
158 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); | ||
159 | |||
164 | srate = params_rate(params); | 160 | srate = params_rate(params); |
165 | 161 | ||
166 | /* Final "* 2" required by Tegra hardware */ | 162 | /* Final "* 2" required by Tegra hardware */ |
@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, | |||
175 | bitcnt = (i2sclock / (2 * srate)) - 1; | 171 | bitcnt = (i2sclock / (2 * srate)) - 1; |
176 | if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) | 172 | if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) |
177 | return -EINVAL; | 173 | return -EINVAL; |
178 | reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; | 174 | val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; |
179 | 175 | ||
180 | if (i2sclock % (2 * srate)) | 176 | if (i2sclock % (2 * srate)) |
181 | reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; | 177 | val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; |
182 | 178 | ||
183 | tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); | 179 | regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val); |
184 | 180 | ||
185 | tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, | 181 | regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR, |
186 | TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | | 182 | TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | |
187 | TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); | 183 | TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); |
188 | 184 | ||
189 | return 0; | 185 | return 0; |
190 | } | 186 | } |
191 | 187 | ||
192 | static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) | 188 | static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) |
193 | { | 189 | { |
194 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; | 190 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
195 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 191 | TEGRA20_I2S_CTRL_FIFO1_ENABLE, |
192 | TEGRA20_I2S_CTRL_FIFO1_ENABLE); | ||
196 | } | 193 | } |
197 | 194 | ||
198 | static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) | 195 | static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) |
199 | { | 196 | { |
200 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; | 197 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
201 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 198 | TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0); |
202 | } | 199 | } |
203 | 200 | ||
204 | static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) | 201 | static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) |
205 | { | 202 | { |
206 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; | 203 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
207 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 204 | TEGRA20_I2S_CTRL_FIFO2_ENABLE, |
205 | TEGRA20_I2S_CTRL_FIFO2_ENABLE); | ||
208 | } | 206 | } |
209 | 207 | ||
210 | static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) | 208 | static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) |
211 | { | 209 | { |
212 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; | 210 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
213 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 211 | TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0); |
214 | } | 212 | } |
215 | 213 | ||
216 | static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | 214 | static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |
@@ -261,12 +259,14 @@ static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = { | |||
261 | static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { | 259 | static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { |
262 | .probe = tegra20_i2s_probe, | 260 | .probe = tegra20_i2s_probe, |
263 | .playback = { | 261 | .playback = { |
262 | .stream_name = "Playback", | ||
264 | .channels_min = 2, | 263 | .channels_min = 2, |
265 | .channels_max = 2, | 264 | .channels_max = 2, |
266 | .rates = SNDRV_PCM_RATE_8000_96000, | 265 | .rates = SNDRV_PCM_RATE_8000_96000, |
267 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 266 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
268 | }, | 267 | }, |
269 | .capture = { | 268 | .capture = { |
269 | .stream_name = "Capture", | ||
270 | .channels_min = 2, | 270 | .channels_min = 2, |
271 | .channels_max = 2, | 271 | .channels_max = 2, |
272 | .rates = SNDRV_PCM_RATE_8000_96000, | 272 | .rates = SNDRV_PCM_RATE_8000_96000, |
@@ -412,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) | |||
412 | i2s->playback_dma_data.width = 32; | 412 | i2s->playback_dma_data.width = 32; |
413 | i2s->playback_dma_data.req_sel = dma_ch; | 413 | i2s->playback_dma_data.req_sel = dma_ch; |
414 | 414 | ||
415 | i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; | ||
416 | |||
417 | pm_runtime_enable(&pdev->dev); | 415 | pm_runtime_enable(&pdev->dev); |
418 | if (!pm_runtime_enabled(&pdev->dev)) { | 416 | if (!pm_runtime_enabled(&pdev->dev)) { |
419 | ret = tegra20_i2s_runtime_resume(&pdev->dev); | 417 | ret = tegra20_i2s_runtime_resume(&pdev->dev); |