Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: fsl_sai: add several improvements

Merge series from Shengjiu Wang <shengjiu.wang@nxp.com>:

Add several improvements for the sai interface.
1.allow to set mclk rate with zero clk_id for master mode
2.add xlate_tdm_slot_mask() callback to avoid channel constrain
3.separate 'is_dsp_mode' for tx and rx
4.separate set_tdm_slot() for tx and rx

+65 -31
+62 -28
sound/soc/fsl/fsl_sai.c
··· 163 163 return iret; 164 164 } 165 165 166 - static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, 167 - u32 rx_mask, int slots, int slot_width) 166 + static int fsl_sai_set_dai_tdm_slot_tx(struct snd_soc_dai *cpu_dai, u32 tx_mask, 167 + u32 rx_mask, int slots, int slot_width) 168 168 { 169 169 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 170 + bool tx = true; 170 171 171 - sai->slots = slots; 172 - sai->slot_width = slot_width; 172 + sai->slots[tx] = slots; 173 + sai->slot_width[tx] = slot_width; 173 174 175 + return 0; 176 + } 177 + 178 + static int fsl_sai_set_dai_tdm_slot_rx(struct snd_soc_dai *cpu_dai, u32 tx_mask, 179 + u32 rx_mask, int slots, int slot_width) 180 + { 181 + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 182 + bool tx = false; 183 + 184 + sai->slots[tx] = slots; 185 + sai->slot_width[tx] = slot_width; 186 + 187 + return 0; 188 + } 189 + 190 + static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, 191 + u32 rx_mask, int slots, int slot_width) 192 + { 193 + int ret; 194 + 195 + ret = fsl_sai_set_dai_tdm_slot_tx(cpu_dai, tx_mask, rx_mask, slots, slot_width); 196 + if (ret) 197 + return ret; 198 + 199 + return fsl_sai_set_dai_tdm_slot_rx(cpu_dai, tx_mask, rx_mask, slots, slot_width); 200 + } 201 + 202 + static int fsl_sai_xlate_tdm_slot_mask(unsigned int slots, 203 + unsigned int *tx_mask, unsigned int *rx_mask) 204 + { 205 + /* Leave it empty, don't change the value of tx_mask and rx_mask */ 174 206 return 0; 175 207 } 176 208 ··· 270 238 if (dir == SND_SOC_CLOCK_IN) 271 239 return 0; 272 240 273 - if (freq > 0 && clk_id != FSL_SAI_CLK_BUS) { 274 - if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { 275 - dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); 276 - return -EINVAL; 277 - } 241 + if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { 242 + dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); 243 + return -EINVAL; 244 + } 278 245 279 - if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) { 280 - dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id); 281 - return -EINVAL; 282 - } 246 + if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) { 247 + dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id); 248 + return -EINVAL; 249 + } 283 250 284 - if (sai->mclk_streams == 0) { 285 - ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq); 286 - if (ret < 0) 287 - return ret; 288 - } 251 + if (sai->mclk_streams == 0 && freq > 0) { 252 + ret = fsl_sai_set_mclk_rate(cpu_dai, 253 + clk_id ? clk_id : FSL_SAI_CLK_MAST1, 254 + freq); 255 + if (ret < 0) 256 + return ret; 289 257 } 290 258 291 259 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, true); ··· 312 280 val_cr4 |= FSL_SAI_CR4_MF; 313 281 314 282 sai->is_pdm_mode = false; 315 - sai->is_dsp_mode = false; 283 + sai->is_dsp_mode[tx] = false; 316 284 /* DAI mode */ 317 285 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 318 286 case SND_SOC_DAIFMT_I2S: ··· 341 309 */ 342 310 val_cr2 |= FSL_SAI_CR2_BCP; 343 311 val_cr4 |= FSL_SAI_CR4_FSE; 344 - sai->is_dsp_mode = true; 312 + sai->is_dsp_mode[tx] = true; 345 313 break; 346 314 case SND_SOC_DAIFMT_DSP_B: 347 315 /* ··· 349 317 * frame sync asserts with the first bit of the frame. 350 318 */ 351 319 val_cr2 |= FSL_SAI_CR2_BCP; 352 - sai->is_dsp_mode = true; 320 + sai->is_dsp_mode[tx] = true; 353 321 break; 354 322 case SND_SOC_DAIFMT_PDM: 355 323 val_cr2 |= FSL_SAI_CR2_BCP; ··· 573 541 u32 watermark; 574 542 int ret, i; 575 543 576 - if (sai->slot_width) 577 - slot_width = sai->slot_width; 544 + if (sai->slot_width[tx]) 545 + slot_width = sai->slot_width[tx]; 578 546 579 - if (sai->slots) 580 - slots = sai->slots; 547 + if (sai->slots[tx]) 548 + slots = sai->slots[tx]; 581 549 else if (sai->bclk_ratio) 582 550 slots = sai->bclk_ratio / slot_width; 583 551 ··· 632 600 } 633 601 } 634 602 635 - if (!sai->is_dsp_mode && !sai->is_pdm_mode) 603 + if (!sai->is_dsp_mode[tx] && !sai->is_pdm_mode) 636 604 val_cr4 |= FSL_SAI_CR4_SYWD(slot_width); 637 605 638 606 val_cr5 |= FSL_SAI_CR5_WNW(slot_width); ··· 964 932 .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, 965 933 .set_sysclk = fsl_sai_set_dai_sysclk, 966 934 .set_fmt = fsl_sai_set_dai_fmt_tx, 967 - .set_tdm_slot = fsl_sai_set_dai_tdm_slot, 935 + .set_tdm_slot = fsl_sai_set_dai_tdm_slot_tx, 936 + .xlate_tdm_slot_mask = fsl_sai_xlate_tdm_slot_mask, 968 937 .hw_params = fsl_sai_hw_params, 969 938 .hw_free = fsl_sai_hw_free, 970 939 .trigger = fsl_sai_trigger, ··· 977 944 .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, 978 945 .set_sysclk = fsl_sai_set_dai_sysclk, 979 946 .set_fmt = fsl_sai_set_dai_fmt_rx, 980 - .set_tdm_slot = fsl_sai_set_dai_tdm_slot, 947 + .set_tdm_slot = fsl_sai_set_dai_tdm_slot_rx, 948 + .xlate_tdm_slot_mask = fsl_sai_xlate_tdm_slot_mask, 981 949 .hw_params = fsl_sai_hw_params, 982 950 .hw_free = fsl_sai_hw_free, 983 951 .trigger = fsl_sai_trigger,
+3 -3
sound/soc/fsl/fsl_sai.h
··· 286 286 287 287 bool is_consumer_mode[2]; 288 288 bool is_lsb_first; 289 - bool is_dsp_mode; 289 + bool is_dsp_mode[2]; 290 290 bool is_pdm_mode; 291 291 bool is_multi_fifo_dma; 292 292 bool synchronous[2]; ··· 296 296 297 297 unsigned int mclk_id[2]; 298 298 unsigned int mclk_streams; 299 - unsigned int slots; 300 - unsigned int slot_width; 299 + unsigned int slots[2]; 300 + unsigned int slot_width[2]; 301 301 unsigned int bclk_ratio; 302 302 303 303 const struct fsl_sai_soc_data *soc_data;