| @@ -71,6 +71,7 @@ struct davinci_mcasp_context { · 70 unmodified lines |
| 71 | struct davinci_mcasp_ruledata { | 71 | struct davinci_mcasp_ruledata { |
| 72 | struct davinci_mcasp *mcasp; | 72 | struct davinci_mcasp *mcasp; |
| 73 | int serializers; | 73 | int serializers; |
| | 74 | int stream; |
| 74 | }; | 75 | }; |
| 75 | | 76 | |
| 76 | struct davinci_mcasp { | 77 | struct davinci_mcasp { |
| @@ -88,21 +89,27 @@ struct davinci_mcasp { · 11 unmodified lines |
| 88 | bool missing_audio_param; | 89 | bool missing_audio_param; |
| 89 | | 90 | |
| 90 | /* McASP specific data */ | 91 | /* McASP specific data */ |
| 91 | int tdm_slots; | 92 | int tdm_slots_tx; |
| | 93 | int tdm_slots_rx; |
| 92 | u32 tdm_mask[2]; | 94 | u32 tdm_mask[2]; |
| 93 | int slot_width; | 95 | int slot_width_tx; |
| | 96 | int slot_width_rx; |
| 94 | u8 op_mode; | 97 | u8 op_mode; |
| 95 | u8 dismod; | 98 | u8 dismod; |
| 96 | u8 num_serializer; | 99 | u8 num_serializer; |
| 97 | u8 *serial_dir; | 100 | u8 *serial_dir; |
| 98 | u8 version; | 101 | u8 version; |
| 99 | u8 bclk_div; | 102 | u8 bclk_div_tx; |
| | 103 | u8 bclk_div_rx; |
| 100 | int streams; | 104 | int streams; |
| 101 | u32 irq_request[2]; | 105 | u32 irq_request[2]; |
| 102 | | 106 | |
| 103 | int sysclk_freq; | 107 | unsigned int sysclk_freq_tx; |
| | 108 | unsigned int sysclk_freq_rx; |
| 104 | bool bclk_master; | 109 | bool bclk_master; |
| 105 | u32 auxclk_fs_ratio; | 110 | bool async_mode; |
| | 111 | u32 auxclk_fs_ratio_tx; |
| | 112 | u32 auxclk_fs_ratio_rx; |
| 106 | | 113 | |
| 107 | unsigned long pdir; /* Pin direction bitfield */ | 114 | unsigned long pdir; /* Pin direction bitfield */ |
| 108 | | 115 | |
| @@ -204,6 +211,27 @@ static inline void mcasp_set_clk_pdir(struct davinci_mcasp *mcasp, bool enable) · 95 unmodified lines |
| 204 | } | 211 | } |
| 205 | } | 212 | } |
| 206 | | 213 | |
| | 214 | static inline void mcasp_set_clk_pdir_stream(struct davinci_mcasp *mcasp, |
| | 215 | int stream, bool enable) |
| | 216 | { |
| | 217 | u32 bit, bit_end; |
| | 218 | |
| | 219 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| | 220 | bit = PIN_BIT_ACLKX; |
| | 221 | bit_end = PIN_BIT_AFSX + 1; |
| | 222 | } else { |
| | 223 | bit = PIN_BIT_ACLKR; |
| | 224 | bit_end = PIN_BIT_AFSR + 1; |
| | 225 | } |
| | 226 | |
| | 227 | for_each_set_bit_from(bit, &mcasp->pdir, bit_end) { |
| | 228 | if (enable) |
| | 229 | mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit)); |
| | 230 | else |
| | 231 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit)); |
| | 232 | } |
| | 233 | } |
| | 234 | |
| 207 | static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable) | 235 | static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable) |
| 208 | { | 236 | { |
| 209 | u32 bit; | 237 | u32 bit; |
| @@ -216,6 +244,36 @@ static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable) · 6 unmodified lines |
| 216 | } | 244 | } |
| 217 | } | 245 | } |
| 218 | | 246 | |
| | 247 | static inline int mcasp_get_tdm_slots(struct davinci_mcasp *mcasp, int stream) |
| | 248 | { |
| | 249 | return (stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
| | 250 | mcasp->tdm_slots_tx : mcasp->tdm_slots_rx; |
| | 251 | } |
| | 252 | |
| | 253 | static inline int mcasp_get_slot_width(struct davinci_mcasp *mcasp, int stream) |
| | 254 | { |
| | 255 | return (stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
| | 256 | mcasp->slot_width_tx : mcasp->slot_width_rx; |
| | 257 | } |
| | 258 | |
| | 259 | static inline unsigned int mcasp_get_sysclk_freq(struct davinci_mcasp *mcasp, int stream) |
| | 260 | { |
| | 261 | return (stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
| | 262 | mcasp->sysclk_freq_tx : mcasp->sysclk_freq_rx; |
| | 263 | } |
| | 264 | |
| | 265 | static inline unsigned int mcasp_get_bclk_div(struct davinci_mcasp *mcasp, int stream) |
| | 266 | { |
| | 267 | return (stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
| | 268 | mcasp->bclk_div_tx : mcasp->bclk_div_rx; |
| | 269 | } |
| | 270 | |
| | 271 | static inline unsigned int mcasp_get_auxclk_fs_ratio(struct davinci_mcasp *mcasp, int stream) |
| | 272 | { |
| | 273 | return (stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
| | 274 | mcasp->auxclk_fs_ratio_tx : mcasp->auxclk_fs_ratio_rx; |
| | 275 | } |
| | 276 | |
| 219 | static void mcasp_start_rx(struct davinci_mcasp *mcasp) | 277 | static void mcasp_start_rx(struct davinci_mcasp *mcasp) |
| 220 | { | 278 | { |
| 221 | if (mcasp->rxnumevt) { /* enable FIFO */ | 279 | if (mcasp->rxnumevt) { /* enable FIFO */ |
| @@ -231,13 +289,17 @@ static void mcasp_start_rx(struct davinci_mcasp *mcasp) · 9 unmodified lines |
| 231 | /* | 289 | /* |
| 232 | * When ASYNC == 0 the transmit and receive sections operate | 290 | * When ASYNC == 0 the transmit and receive sections operate |
| 233 | * synchronously from the transmit clock and frame sync. We need to make | 291 | * synchronously from the transmit clock and frame sync. We need to make |
| 234 | * sure that the TX signlas are enabled when starting reception. | 292 | * sure that the TX signals are enabled when starting reception, |
| | 293 | * when the McASP is the producer. |
| 235 | */ | 294 | */ |
| 236 | if (mcasp_is_frame_producer(mcasp) && mcasp_is_synchronous(mcasp)) { | 295 | if (mcasp_is_frame_producer(mcasp) && mcasp_is_synchronous(mcasp)) { |
| 237 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); | 296 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); |
| 238 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); | 297 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); |
| 239 | } | 298 | } |
| 240 | mcasp_set_clk_pdir(mcasp, true); | 299 | if (mcasp_is_synchronous(mcasp)) |
| | 300 | mcasp_set_clk_pdir(mcasp, true); |
| | 301 | else |
| | 302 | mcasp_set_clk_pdir_stream(mcasp, SNDRV_PCM_STREAM_CAPTURE, true); |
| 241 | | 303 | |
| 242 | /* Activate serializer(s) */ | 304 | /* Activate serializer(s) */ |
| 243 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); | 305 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); |
| @@ -268,7 +330,10 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp) · 24 unmodified lines |
| 268 | /* Start clocks */ | 330 | /* Start clocks */ |
| 269 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); | 331 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); |
| 270 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); | 332 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); |
| 271 | mcasp_set_clk_pdir(mcasp, true); | 333 | if (mcasp_is_synchronous(mcasp)) |
| | 334 | mcasp_set_clk_pdir(mcasp, true); |
| | 335 | else |
| | 336 | mcasp_set_clk_pdir_stream(mcasp, SNDRV_PCM_STREAM_PLAYBACK, true); |
| 272 | | 337 | |
| 273 | /* Activate serializer(s) */ | 338 | /* Activate serializer(s) */ |
| 274 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); | 339 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); |
| @@ -311,9 +376,17 @@ static void mcasp_stop_rx(struct davinci_mcasp *mcasp) · 36 unmodified lines |
| 311 | /* | 376 | /* |
| 312 | * In synchronous mode stop the TX clocks if no other stream is | 377 | * In synchronous mode stop the TX clocks if no other stream is |
| 313 | * running | 378 | * running |
| | 379 | * Otherwise in async mode only stop RX clocks |
| 314 | */ | 380 | */ |
| 315 | if (!mcasp->streams) | 381 | if (mcasp_is_synchronous(mcasp) && !mcasp->streams) |
| 316 | mcasp_set_clk_pdir(mcasp, false); | 382 | mcasp_set_clk_pdir(mcasp, false); |
| | 383 | else if (!mcasp_is_synchronous(mcasp)) |
| | 384 | mcasp_set_clk_pdir_stream(mcasp, SNDRV_PCM_STREAM_CAPTURE, false); |
| | 385 | /* |
| | 386 | * When McASP is the producer and operating in synchronous mode, |
| | 387 | * stop the transmit clocks if no other stream is running. As |
| | 388 | * tx & rx operate synchronously from the transmit clock. |
| | 389 | */ |
| 317 | if (mcasp_is_frame_producer(mcasp) && mcasp_is_synchronous(mcasp) && !mcasp->streams) | 390 | if (mcasp_is_frame_producer(mcasp) && mcasp_is_synchronous(mcasp) && !mcasp->streams) |
| 318 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, 0); | 391 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, 0); |
| 319 | | 392 | |
| @@ -338,11 +411,14 @@ static void mcasp_stop_tx(struct davinci_mcasp *mcasp) · 18 unmodified lines |
| 338 | /* | 411 | /* |
| 339 | * In synchronous mode keep TX clocks running if the capture stream is | 412 | * In synchronous mode keep TX clocks running if the capture stream is |
| 340 | * still running. | 413 | * still running. |
| | 414 | * Otherwise in async mode only stop TX clocks |
| 341 | */ | 415 | */ |
| 342 | if (mcasp_is_frame_producer(mcasp) && mcasp_is_synchronous(mcasp) && mcasp->streams) | 416 | if (mcasp_is_frame_producer(mcasp) && mcasp_is_synchronous(mcasp) && mcasp->streams) |
| 343 | val = TXHCLKRST | TXCLKRST | TXFSRST; | 417 | val = TXHCLKRST | TXCLKRST | TXFSRST; |
| 344 | if (!mcasp->streams) | 418 | if (mcasp_is_synchronous(mcasp) && !mcasp->streams) |
| 345 | mcasp_set_clk_pdir(mcasp, false); | 419 | mcasp_set_clk_pdir(mcasp, false); |
| | 420 | else if (!mcasp_is_synchronous(mcasp)) |
| | 421 | mcasp_set_clk_pdir_stream(mcasp, SNDRV_PCM_STREAM_PLAYBACK, false); |
| 346 | | 422 | |
| 347 | | 423 | |
| 348 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); | 424 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); |
| @@ -626,13 +702,39 @@ static int __davinci_mcasp_set_clkdiv(struct davinci_mcasp *mcasp, int div_id, · 277 unmodified lines |
| 626 | AHCLKRDIV(div - 1), AHCLKRDIV_MASK); | 702 | AHCLKRDIV(div - 1), AHCLKRDIV_MASK); |
| 627 | break; | 703 | break; |
| 628 | | 704 | |
| | 705 | case MCASP_CLKDIV_AUXCLK_TXONLY: /* MCLK divider for TX only */ |
| | 706 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, |
| | 707 | AHCLKXDIV(div - 1), AHCLKXDIV_MASK); |
| | 708 | break; |
| | 709 | |
| | 710 | case MCASP_CLKDIV_AUXCLK_RXONLY: /* MCLK divider for RX only */ |
| | 711 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| | 712 | AHCLKRDIV(div - 1), AHCLKRDIV_MASK); |
| | 713 | break; |
| | 714 | |
| 629 | case MCASP_CLKDIV_BCLK: /* BCLK divider */ | 715 | case MCASP_CLKDIV_BCLK: /* BCLK divider */ |
| 630 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, | 716 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, |
| 631 | ACLKXDIV(div - 1), ACLKXDIV_MASK); | 717 | ACLKXDIV(div - 1), ACLKXDIV_MASK); |
| | 718 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, |
| | 719 | ACLKRDIV(div - 1), ACLKRDIV_MASK); |
| | 720 | if (explicit) { |
| | 721 | mcasp->bclk_div_tx = div; |
| | 722 | mcasp->bclk_div_rx = div; |
| | 723 | } |
| | 724 | break; |
| | 725 | |
| | 726 | case MCASP_CLKDIV_BCLK_TXONLY: /* BCLK divider for TX only */ |
| | 727 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, |
| | 728 | ACLKXDIV(div - 1), ACLKXDIV_MASK); |
| | 729 | if (explicit) |
| | 730 | mcasp->bclk_div_tx = div; |
| | 731 | break; |
| | 732 | |
| | 733 | case MCASP_CLKDIV_BCLK_RXONLY: /* BCLK divider for RX only */ |
| 632 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, | 734 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, |
| 633 | ACLKRDIV(div - 1), ACLKRDIV_MASK); | 735 | ACLKRDIV(div - 1), ACLKRDIV_MASK); |
| 634 | if (explicit) | 736 | if (explicit) |
| 635 | mcasp->bclk_div = div; | 737 | mcasp->bclk_div_rx = div; |
| 636 | break; | 738 | break; |
| 637 | | 739 | |
| 638 | case MCASP_CLKDIV_BCLK_FS_RATIO: | 740 | case MCASP_CLKDIV_BCLK_FS_RATIO: |
| @@ -646,11 +748,33 @@ static int __davinci_mcasp_set_clkdiv(struct davinci_mcasp *mcasp, int div_id, · 7 unmodified lines |
| 646 | * tdm_slot width by dividing the ratio by the | 748 | * tdm_slot width by dividing the ratio by the |
| 647 | * number of configured tdm slots. | 749 | * number of configured tdm slots. |
| 648 | */ | 750 | */ |
| 649 | mcasp->slot_width = div / mcasp->tdm_slots; | 751 | mcasp->slot_width_tx = div / mcasp->tdm_slots_tx; |
| 650 | if (div % mcasp->tdm_slots) | 752 | if (div % mcasp->tdm_slots_tx) |
| 651 | dev_warn(mcasp->dev, | 753 | dev_warn(mcasp->dev, |
| 652 | "%s(): BCLK/LRCLK %d is not divisible by %d tdm slots", | 754 | "%s(): BCLK/LRCLK %d is not divisible by %d tx tdm slots", |
| 653 | __func__, div, mcasp->tdm_slots); | 755 | __func__, div, mcasp->tdm_slots_tx); |
| | 756 | |
| | 757 | mcasp->slot_width_rx = div / mcasp->tdm_slots_rx; |
| | 758 | if (div % mcasp->tdm_slots_rx) |
| | 759 | dev_warn(mcasp->dev, |
| | 760 | "%s(): BCLK/LRCLK %d is not divisible by %d rx tdm slots", |
| | 761 | __func__, div, mcasp->tdm_slots_rx); |
| | 762 | break; |
| | 763 | |
| | 764 | case MCASP_CLKDIV_BCLK_FS_RATIO_TXONLY: |
| | 765 | mcasp->slot_width_tx = div / mcasp->tdm_slots_tx; |
| | 766 | if (div % mcasp->tdm_slots_tx) |
| | 767 | dev_warn(mcasp->dev, |
| | 768 | "%s(): BCLK/LRCLK %d is not divisible by %d tx tdm slots", |
| | 769 | __func__, div, mcasp->tdm_slots_tx); |
| | 770 | break; |
| | 771 | |
| | 772 | case MCASP_CLKDIV_BCLK_FS_RATIO_RXONLY: |
| | 773 | mcasp->slot_width_rx = div / mcasp->tdm_slots_rx; |
| | 774 | if (div % mcasp->tdm_slots_rx) |
| | 775 | dev_warn(mcasp->dev, |
| | 776 | "%s(): BCLK/LRCLK %d is not divisible by %d rx tdm slots", |
| | 777 | __func__, div, mcasp->tdm_slots_rx); |
| 654 | break; | 778 | break; |
| 655 | | 779 | |
| 656 | default: | 780 | default: |
| @@ -684,6 +808,20 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, · 27 unmodified lines |
| 684 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, | 808 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| 685 | AHCLKRE); | 809 | AHCLKRE); |
| 686 | clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); | 810 | clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); |
| | 811 | mcasp->sysclk_freq_tx = freq; |
| | 812 | mcasp->sysclk_freq_rx = freq; |
| | 813 | break; |
| | 814 | case MCASP_CLK_HCLK_AHCLK_TXONLY: |
| | 815 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, |
| | 816 | AHCLKXE); |
| | 817 | clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); |
| | 818 | mcasp->sysclk_freq_tx = freq; |
| | 819 | break; |
| | 820 | case MCASP_CLK_HCLK_AHCLK_RXONLY: |
| | 821 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| | 822 | AHCLKRE); |
| | 823 | clear_bit(PIN_BIT_AHCLKR, &mcasp->pdir); |
| | 824 | mcasp->sysclk_freq_rx = freq; |
| 687 | break; | 825 | break; |
| 688 | case MCASP_CLK_HCLK_AUXCLK: | 826 | case MCASP_CLK_HCLK_AUXCLK: |
| 689 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, | 827 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, |
| @@ -691,22 +829,56 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, · 1 unmodified line |
| 691 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, | 829 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| 692 | AHCLKRE); | 830 | AHCLKRE); |
| 693 | set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); | 831 | set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); |
| | 832 | mcasp->sysclk_freq_tx = freq; |
| | 833 | mcasp->sysclk_freq_rx = freq; |
| | 834 | break; |
| | 835 | case MCASP_CLK_HCLK_AUXCLK_TXONLY: |
| | 836 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, |
| | 837 | AHCLKXE); |
| | 838 | set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); |
| | 839 | mcasp->sysclk_freq_tx = freq; |
| | 840 | break; |
| | 841 | case MCASP_CLK_HCLK_AUXCLK_RXONLY: |
| | 842 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| | 843 | AHCLKRE); |
| | 844 | set_bit(PIN_BIT_AHCLKR, &mcasp->pdir); |
| | 845 | mcasp->sysclk_freq_rx = freq; |
| 694 | break; | 846 | break; |
| 695 | default: | 847 | default: |
| 696 | dev_err(mcasp->dev, "Invalid clk id: %d\n", clk_id); | 848 | dev_err(mcasp->dev, "Invalid clk id: %d\n", clk_id); |
| 697 | goto out; | 849 | goto out; |
| 698 | } | 850 | } |
| 699 | } else { | 851 | } else { |
| 700 | /* Select AUXCLK as HCLK */ | 852 | /* McASP is clock master, select AUXCLK as HCLK */ |
| 701 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); | 853 | switch (clk_id) { |
| 702 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | 854 | case MCASP_CLK_HCLK_AUXCLK_TXONLY: |
| 703 | set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); | 855 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, |
| | 856 | AHCLKXE); |
| | 857 | set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); |
| | 858 | mcasp->sysclk_freq_tx = freq; |
| | 859 | break; |
| | 860 | case MCASP_CLK_HCLK_AUXCLK_RXONLY: |
| | 861 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| | 862 | AHCLKRE); |
| | 863 | set_bit(PIN_BIT_AHCLKR, &mcasp->pdir); |
| | 864 | mcasp->sysclk_freq_rx = freq; |
| | 865 | break; |
| | 866 | default: |
| | 867 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, |
| | 868 | AHCLKXE); |
| | 869 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, |
| | 870 | AHCLKRE); |
| | 871 | set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); |
| | 872 | set_bit(PIN_BIT_AHCLKR, &mcasp->pdir); |
| | 873 | mcasp->sysclk_freq_tx = freq; |
| | 874 | mcasp->sysclk_freq_rx = freq; |
| | 875 | break; |
| | 876 | } |
| 704 | } | 877 | } |
| 705 | /* | 878 | /* |
| 706 | * When AHCLK X/R is selected to be output it means that the HCLK is | 879 | * When AHCLK X/R is selected to be output it means that the HCLK is |
| 707 | * the same clock - coming via AUXCLK. | 880 | * the same clock - coming via AUXCLK. |
| 708 | */ | 881 | */ |
| 709 | mcasp->sysclk_freq = freq; | | |
| 710 | out: | 882 | out: |
| 711 | pm_runtime_put(mcasp->dev); | 883 | pm_runtime_put(mcasp->dev); |
| 712 | return 0; | 884 | return 0; |
| @@ -718,9 +890,11 @@ static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, int stream, · 5 unmodified lines |
| 718 | { | 890 | { |
| 719 | struct snd_pcm_hw_constraint_list *cl = &mcasp->chconstr[stream]; | 891 | struct snd_pcm_hw_constraint_list *cl = &mcasp->chconstr[stream]; |
| 720 | unsigned int *list = (unsigned int *) cl->list; | 892 | unsigned int *list = (unsigned int *) cl->list; |
| 721 | int slots = mcasp->tdm_slots; | 893 | int slots; |
| 722 | int i, count = 0; | 894 | int i, count = 0; |
| 723 | | 895 | |
| | 896 | slots = mcasp_get_tdm_slots(mcasp, stream); |
| | 897 | |
| 724 | if (mcasp->tdm_mask[stream]) | 898 | if (mcasp->tdm_mask[stream]) |
| 725 | slots = hweight32(mcasp->tdm_mask[stream]); | 899 | slots = hweight32(mcasp->tdm_mask[stream]); |
| 726 | | 900 | |
| @@ -785,27 +959,42 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai, · 58 unmodified lines |
| 785 | return -EINVAL; | 959 | return -EINVAL; |
| 786 | } | 960 | } |
| 787 | | 961 | |
| 788 | mcasp->tdm_slots = slots; | 962 | if (mcasp->async_mode) { |
| | 963 | if (tx_mask) { |
| | 964 | mcasp->tdm_slots_tx = slots; |
| | 965 | mcasp->slot_width_tx = slot_width; |
| | 966 | } |
| | 967 | if (rx_mask) { |
| | 968 | mcasp->tdm_slots_rx = slots; |
| | 969 | mcasp->slot_width_rx = slot_width; |
| | 970 | } |
| | 971 | } else { |
| | 972 | mcasp->tdm_slots_tx = slots; |
| | 973 | mcasp->tdm_slots_rx = slots; |
| | 974 | mcasp->slot_width_tx = slot_width; |
| | 975 | mcasp->slot_width_rx = slot_width; |
| | 976 | } |
| | 977 | |
| 789 | mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask; | 978 | mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask; |
| 790 | mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask; | 979 | mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask; |
| 791 | mcasp->slot_width = slot_width; | | |
| 792 | | 980 | |
| 793 | return davinci_mcasp_set_ch_constraints(mcasp); | 981 | return davinci_mcasp_set_ch_constraints(mcasp); |
| 794 | } | 982 | } |
| 795 | | 983 | |
| 796 | static int davinci_config_channel_size(struct davinci_mcasp *mcasp, | 984 | static int davinci_config_channel_size(struct davinci_mcasp *mcasp, |
| 797 | int sample_width) | 985 | int sample_width, int stream) |
| 798 | { | 986 | { |
| 799 | u32 fmt; | 987 | u32 fmt; |
| 800 | u32 tx_rotate, rx_rotate, slot_width; | 988 | u32 tx_rotate, rx_rotate, slot_width; |
| 801 | u32 mask = (1ULL << sample_width) - 1; | 989 | u32 mask = (1ULL << sample_width) - 1; |
| 802 | | 990 | |
| 803 | if (mcasp->slot_width) | 991 | slot_width = mcasp_get_slot_width(mcasp, stream); |
| 804 | slot_width = mcasp->slot_width; | 992 | if (!slot_width) { |
| 805 | else if (mcasp->max_format_width) | 993 | if (mcasp->max_format_width) |
| 806 | slot_width = mcasp->max_format_width; | 994 | slot_width = mcasp->max_format_width; |
| 807 | else | 995 | else |
| 808 | slot_width = sample_width; | 996 | slot_width = sample_width; |
| | 997 | } |
| 809 | /* | 998 | /* |
| 810 | * TX rotation: | 999 | * TX rotation: |
| 811 | * right aligned formats: rotate w/ slot_width | 1000 | * right aligned formats: rotate w/ slot_width |
| @@ -828,17 +1017,23 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, · 16 unmodified lines |
| 828 | fmt = (slot_width >> 1) - 1; | 1017 | fmt = (slot_width >> 1) - 1; |
| 829 | | 1018 | |
| 830 | if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { | 1019 | if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { |
| 831 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), | 1020 | if (!mcasp->async_mode || stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 832 | RXSSZ(0x0F)); | 1021 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt), |
| 833 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt), | 1022 | TXSSZ(0x0F)); |
| 834 | TXSSZ(0x0F)); | 1023 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate), |
| 835 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate), | 1024 | TXROT(7)); |
| 836 | TXROT(7)); | 1025 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask); |
| 837 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate), | 1026 | } |
| 838 | RXROT(7)); | 1027 | if (!mcasp->async_mode || stream == SNDRV_PCM_STREAM_CAPTURE) { |
| 839 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask); | 1028 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), |
| | 1029 | RXSSZ(0x0F)); |
| | 1030 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate), |
| | 1031 | RXROT(7)); |
| | 1032 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask); |
| | 1033 | } |
| 840 | } else { | 1034 | } else { |
| 841 | /* | 1035 | /* |
| | 1036 | * DIT mode only use TX serializers |
| 842 | * according to the TRM it should be TXROT=0, this one works: | 1037 | * according to the TRM it should be TXROT=0, this one works: |
| 843 | * 16 bit to 23-8 (TXROT=6, rotate 24 bits) | 1038 | * 16 bit to 23-8 (TXROT=6, rotate 24 bits) |
| 844 | * 24 bit to 23-0 (TXROT=0, rotate 0 bits) | 1039 | * 24 bit to 23-0 (TXROT=0, rotate 0 bits) |
| @@ -851,10 +1046,9 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, · 6 unmodified lines |
| 851 | TXROT(7)); | 1046 | TXROT(7)); |
| 852 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(15), | 1047 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(15), |
| 853 | TXSSZ(0x0F)); | 1048 | TXSSZ(0x0F)); |
| | 1049 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask); |
| 854 | } | 1050 | } |
| 855 | | 1051 | |
| 856 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask); | | |
| 857 | | | |
| 858 | return 0; | 1052 | return 0; |
| 859 | } | 1053 | } |
| 860 | | 1054 | |
| @@ -865,11 +1059,13 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, · 4 unmodified lines |
| 865 | int i; | 1059 | int i; |
| 866 | u8 tx_ser = 0; | 1060 | u8 tx_ser = 0; |
| 867 | u8 rx_ser = 0; | 1061 | u8 rx_ser = 0; |
| 868 | u8 slots = mcasp->tdm_slots; | 1062 | int slots; |
| 869 | u8 max_active_serializers, max_rx_serializers, max_tx_serializers; | 1063 | u8 max_active_serializers, max_rx_serializers, max_tx_serializers; |
| 870 | int active_serializers, numevt; | 1064 | int active_serializers, numevt; |
| 871 | u32 reg; | 1065 | u32 reg; |
| 872 | | 1066 | |
| | 1067 | slots = mcasp_get_tdm_slots(mcasp, stream); |
| | 1068 | |
| 873 | /* In DIT mode we only allow maximum of one serializers for now */ | 1069 | /* In DIT mode we only allow maximum of one serializers for now */ |
| 874 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) | 1070 | if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) |
| 875 | max_active_serializers = 1; | 1071 | max_active_serializers = 1; |
| @@ -997,7 +1193,7 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, · 121 unmodified lines |
| 997 | u32 mask = 0; | 1193 | u32 mask = 0; |
| 998 | u32 busel = 0; | 1194 | u32 busel = 0; |
| 999 | | 1195 | |
| 1000 | total_slots = mcasp->tdm_slots; | 1196 | total_slots = mcasp_get_tdm_slots(mcasp, stream); |
| 1001 | | 1197 | |
| 1002 | /* | 1198 | /* |
| 1003 | * If more than one serializer is needed, then use them with | 1199 | * If more than one serializer is needed, then use them with |
| @@ -1028,7 +1224,10 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, · 24 unmodified lines |
| 1028 | mask |= (1 << i); | 1224 | mask |= (1 << i); |
| 1029 | } | 1225 | } |
| 1030 | | 1226 | |
| 1031 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); | 1227 | if (mcasp->async_mode) |
| | 1228 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); |
| | 1229 | else |
| | 1230 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); |
| 1032 | | 1231 | |
| 1033 | if (!mcasp->dat_port) | 1232 | if (!mcasp->dat_port) |
| 1034 | busel = TXSEL; | 1233 | busel = TXSEL; |
| @@ -1127,16 +1326,33 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp, · 92 unmodified lines |
| 1127 | | 1326 | |
| 1128 | static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp, | 1327 | static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp, |
| 1129 | unsigned int sysclk_freq, | 1328 | unsigned int sysclk_freq, |
| 1130 | unsigned int bclk_freq, bool set) | 1329 | unsigned int bclk_freq, |
| | 1330 | int stream, |
| | 1331 | bool set) |
| 1131 | { | 1332 | { |
| 1132 | u32 reg = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG); | | |
| 1133 | int div = sysclk_freq / bclk_freq; | 1333 | int div = sysclk_freq / bclk_freq; |
| 1134 | int rem = sysclk_freq % bclk_freq; | 1334 | int rem = sysclk_freq % bclk_freq; |
| 1135 | int error_ppm; | 1335 | int error_ppm; |
| 1136 | int aux_div = 1; | 1336 | int aux_div = 1; |
| | 1337 | int bclk_div_id, auxclk_div_id; |
| | 1338 | bool auxclk_enabled; |
| | 1339 | |
| | 1340 | if (mcasp->async_mode && stream == SNDRV_PCM_STREAM_CAPTURE) { |
| | 1341 | auxclk_enabled = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG) & AHCLKRE; |
| | 1342 | bclk_div_id = MCASP_CLKDIV_BCLK_RXONLY; |
| | 1343 | auxclk_div_id = MCASP_CLKDIV_AUXCLK_RXONLY; |
| | 1344 | } else if (mcasp->async_mode && stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| | 1345 | auxclk_enabled = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG) & AHCLKXE; |
| | 1346 | bclk_div_id = MCASP_CLKDIV_BCLK_TXONLY; |
| | 1347 | auxclk_div_id = MCASP_CLKDIV_AUXCLK_TXONLY; |
| | 1348 | } else { |
| | 1349 | auxclk_enabled = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG) & AHCLKXE; |
| | 1350 | bclk_div_id = MCASP_CLKDIV_BCLK; |
| | 1351 | auxclk_div_id = MCASP_CLKDIV_AUXCLK; |
| | 1352 | } |
| 1137 | | 1353 | |
| 1138 | if (div > (ACLKXDIV_MASK + 1)) { | 1354 | if (div > (ACLKXDIV_MASK + 1)) { |
| 1139 | if (reg & AHCLKXE) { | 1355 | if (auxclk_enabled) { |
| 1140 | aux_div = div / (ACLKXDIV_MASK + 1); | 1356 | aux_div = div / (ACLKXDIV_MASK + 1); |
| 1141 | if (div % (ACLKXDIV_MASK + 1)) | 1357 | if (div % (ACLKXDIV_MASK + 1)) |
| 1142 | aux_div++; | 1358 | aux_div++; |
| @@ -1166,10 +1382,10 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp, · 23 unmodified lines |
| 1166 | dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", | 1382 | dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", |
| 1167 | error_ppm); | 1383 | error_ppm); |
| 1168 | | 1384 | |
| 1169 | __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_BCLK, div, 0); | 1385 | __davinci_mcasp_set_clkdiv(mcasp, bclk_div_id, div, false); |
| 1170 | if (reg & AHCLKXE) | 1386 | if (auxclk_enabled) |
| 1171 | __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_AUXCLK, | 1387 | __davinci_mcasp_set_clkdiv(mcasp, auxclk_div_id, |
| 1172 | aux_div, 0); | 1388 | aux_div, false); |
| 1173 | } | 1389 | } |
| 1174 | | 1390 | |
| 1175 | return error_ppm; | 1391 | return error_ppm; |
| @@ -1220,6 +1436,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, · 44 unmodified lines |
| 1220 | int channels = params_channels(params); | 1436 | int channels = params_channels(params); |
| 1221 | int period_size = params_period_size(params); | 1437 | int period_size = params_period_size(params); |
| 1222 | int ret; | 1438 | int ret; |
| | 1439 | unsigned int sysclk_freq = mcasp_get_sysclk_freq(mcasp, substream->stream); |
| 1223 | | 1440 | |
| 1224 | switch (params_format(params)) { | 1441 | switch (params_format(params)) { |
| 1225 | case SNDRV_PCM_FORMAT_U8: | 1442 | case SNDRV_PCM_FORMAT_U8: |
| @@ -1260,22 +1477,26 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, · 34 unmodified lines |
| 1260 | * If mcasp is BCLK master, and a BCLK divider was not provided by | 1477 | * If mcasp is BCLK master, and a BCLK divider was not provided by |
| 1261 | * the machine driver, we need to calculate the ratio. | 1478 | * the machine driver, we need to calculate the ratio. |
| 1262 | */ | 1479 | */ |
| 1263 | if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { | 1480 | if (mcasp->bclk_master && mcasp_get_bclk_div(mcasp, substream->stream) == 0 && |
| 1264 | int slots = mcasp->tdm_slots; | 1481 | sysclk_freq) { |
| | 1482 | int slots, slot_width; |
| 1265 | int rate = params_rate(params); | 1483 | int rate = params_rate(params); |
| 1266 | int sbits = params_width(params); | 1484 | int sbits = params_width(params); |
| 1267 | unsigned int bclk_target; | 1485 | unsigned int bclk_target; |
| 1268 | | 1486 | |
| 1269 | if (mcasp->slot_width) | 1487 | slots = mcasp_get_tdm_slots(mcasp, substream->stream); |
| 1270 | sbits = mcasp->slot_width; | 1488 | |
| | 1489 | slot_width = mcasp_get_slot_width(mcasp, substream->stream); |
| | 1490 | if (slot_width) |
| | 1491 | sbits = slot_width; |
| 1271 | | 1492 | |
| 1272 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) | 1493 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) |
| 1273 | bclk_target = rate * sbits * slots; | 1494 | bclk_target = rate * sbits * slots; |
| 1274 | else | 1495 | else |
| 1275 | bclk_target = rate * 128; | 1496 | bclk_target = rate * 128; |
| 1276 | | 1497 | |
| 1277 | davinci_mcasp_calc_clk_div(mcasp, mcasp->sysclk_freq, | 1498 | davinci_mcasp_calc_clk_div(mcasp, sysclk_freq, |
| 1278 | bclk_target, true); | 1499 | bclk_target, substream->stream, true); |
| 1279 | } | 1500 | } |
| 1280 | | 1501 | |
| 1281 | ret = mcasp_common_hw_param(mcasp, substream->stream, | 1502 | ret = mcasp_common_hw_param(mcasp, substream->stream, |
| @@ -1292,9 +1513,10 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, · 10 unmodified lines |
| 1292 | if (ret) | 1513 | if (ret) |
| 1293 | return ret; | 1514 | return ret; |
| 1294 | | 1515 | |
| 1295 | davinci_config_channel_size(mcasp, word_length); | 1516 | davinci_config_channel_size(mcasp, word_length, substream->stream); |
| 1296 | | 1517 | |
| 1297 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) { | 1518 | /* Channel constraints are disabled for async mode */ |
| | 1519 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE && !mcasp->async_mode) { |
| 1298 | mcasp->channels = channels; | 1520 | mcasp->channels = channels; |
| 1299 | if (!mcasp->max_format_width) | 1521 | if (!mcasp->max_format_width) |
| 1300 | mcasp->max_format_width = word_length; | 1522 | mcasp->max_format_width = word_length; |
| @@ -1338,7 +1560,7 @@ static int davinci_mcasp_hw_rule_slot_width(struct snd_pcm_hw_params *params, · 37 unmodified lines |
| 1338 | snd_pcm_format_t i; | 1560 | snd_pcm_format_t i; |
| 1339 | | 1561 | |
| 1340 | snd_mask_none(&nfmt); | 1562 | snd_mask_none(&nfmt); |
| 1341 | slot_width = rd->mcasp->slot_width; | 1563 | slot_width = mcasp_get_slot_width(rd->mcasp, rd->stream); |
| 1342 | | 1564 | |
| 1343 | pcm_for_each_format(i) { | 1565 | pcm_for_each_format(i) { |
| 1344 | if (snd_mask_test_format(fmt, i)) { | 1566 | if (snd_mask_test_format(fmt, i)) { |
| @@ -1388,12 +1610,15 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params, · 43 unmodified lines |
| 1388 | struct snd_interval *ri = | 1610 | struct snd_interval *ri = |
| 1389 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 1611 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
| 1390 | int sbits = params_width(params); | 1612 | int sbits = params_width(params); |
| 1391 | int slots = rd->mcasp->tdm_slots; | 1613 | int slots, slot_width; |
| 1392 | struct snd_interval range; | 1614 | struct snd_interval range; |
| 1393 | int i; | 1615 | int i; |
| 1394 | | 1616 | |
| 1395 | if (rd->mcasp->slot_width) | 1617 | slots = mcasp_get_tdm_slots(rd->mcasp, rd->stream); |
| 1396 | sbits = rd->mcasp->slot_width; | 1618 | |
| | 1619 | slot_width = mcasp_get_slot_width(rd->mcasp, rd->stream); |
| | 1620 | if (slot_width) |
| | 1621 | sbits = slot_width; |
| 1397 | | 1622 | |
| 1398 | snd_interval_any(&range); | 1623 | snd_interval_any(&range); |
| 1399 | range.empty = 1; | 1624 | range.empty = 1; |
| @@ -1403,16 +1628,17 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params, · 3 unmodified lines |
| 1403 | uint bclk_freq = sbits * slots * | 1628 | uint bclk_freq = sbits * slots * |
| 1404 | davinci_mcasp_dai_rates[i]; | 1629 | davinci_mcasp_dai_rates[i]; |
| 1405 | unsigned int sysclk_freq; | 1630 | unsigned int sysclk_freq; |
| | 1631 | unsigned int ratio; |
| 1406 | int ppm; | 1632 | int ppm; |
| 1407 | | 1633 | |
| 1408 | if (rd->mcasp->auxclk_fs_ratio) | 1634 | ratio = mcasp_get_auxclk_fs_ratio(rd->mcasp, rd->stream); |
| 1409 | sysclk_freq = davinci_mcasp_dai_rates[i] * | 1635 | if (ratio) |
| 1410 | rd->mcasp->auxclk_fs_ratio; | 1636 | sysclk_freq = davinci_mcasp_dai_rates[i] * ratio; |
| 1411 | else | 1637 | else |
| 1412 | sysclk_freq = rd->mcasp->sysclk_freq; | 1638 | sysclk_freq = mcasp_get_sysclk_freq(rd->mcasp, rd->stream); |
| 1413 | | 1639 | |
| 1414 | ppm = davinci_mcasp_calc_clk_div(rd->mcasp, sysclk_freq, | 1640 | ppm = davinci_mcasp_calc_clk_div(rd->mcasp, sysclk_freq, |
| 1415 | bclk_freq, false); | 1641 | bclk_freq, rd->stream, false); |
| 1416 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { | 1642 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { |
| 1417 | if (range.empty) { | 1643 | if (range.empty) { |
| 1418 | range.min = davinci_mcasp_dai_rates[i]; | 1644 | range.min = davinci_mcasp_dai_rates[i]; |
| @@ -1438,30 +1664,34 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, · 19 unmodified lines |
| 1438 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 1664 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
| 1439 | struct snd_mask nfmt; | 1665 | struct snd_mask nfmt; |
| 1440 | int rate = params_rate(params); | 1666 | int rate = params_rate(params); |
| 1441 | int slots = rd->mcasp->tdm_slots; | 1667 | int slots; |
| 1442 | int count = 0; | 1668 | int count = 0; |
| 1443 | snd_pcm_format_t i; | 1669 | snd_pcm_format_t i; |
| 1444 | | 1670 | |
| | 1671 | slots = mcasp_get_tdm_slots(rd->mcasp, rd->stream); |
| | 1672 | |
| 1445 | snd_mask_none(&nfmt); | 1673 | snd_mask_none(&nfmt); |
| 1446 | | 1674 | |
| 1447 | pcm_for_each_format(i) { | 1675 | pcm_for_each_format(i) { |
| 1448 | if (snd_mask_test_format(fmt, i)) { | 1676 | if (snd_mask_test_format(fmt, i)) { |
| 1449 | uint sbits = snd_pcm_format_width(i); | 1677 | uint sbits = snd_pcm_format_width(i); |
| 1450 | unsigned int sysclk_freq; | 1678 | unsigned int sysclk_freq; |
| 1451 | int ppm; | 1679 | unsigned int ratio; |
| | 1680 | int ppm, slot_width; |
| 1452 | | 1681 | |
| 1453 | if (rd->mcasp->auxclk_fs_ratio) | 1682 | ratio = mcasp_get_auxclk_fs_ratio(rd->mcasp, rd->stream); |
| 1454 | sysclk_freq = rate * | 1683 | if (ratio) |
| 1455 | rd->mcasp->auxclk_fs_ratio; | 1684 | sysclk_freq = rate * ratio; |
| 1456 | else | 1685 | else |
| 1457 | sysclk_freq = rd->mcasp->sysclk_freq; | 1686 | sysclk_freq = mcasp_get_sysclk_freq(rd->mcasp, rd->stream); |
| 1458 | | 1687 | |
| 1459 | if (rd->mcasp->slot_width) | 1688 | slot_width = mcasp_get_slot_width(rd->mcasp, rd->stream); |
| 1460 | sbits = rd->mcasp->slot_width; | 1689 | if (slot_width) |
| | 1690 | sbits = slot_width; |
| 1461 | | 1691 | |
| 1462 | ppm = davinci_mcasp_calc_clk_div(rd->mcasp, sysclk_freq, | 1692 | ppm = davinci_mcasp_calc_clk_div(rd->mcasp, sysclk_freq, |
| 1463 | sbits * slots * rate, | 1693 | sbits * slots * rate, |
| 1464 | false); | 1694 | rd->stream, false); |
| 1465 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { | 1695 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { |
| 1466 | snd_mask_set_format(&nfmt, i); | 1696 | snd_mask_set_format(&nfmt, i); |
| 1467 | count++; | 1697 | count++; |
| @@ -1498,7 +1728,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 30 unmodified lines |
| 1498 | &mcasp->ruledata[substream->stream]; | 1728 | &mcasp->ruledata[substream->stream]; |
| 1499 | u32 max_channels = 0; | 1729 | u32 max_channels = 0; |
| 1500 | int i, dir, ret; | 1730 | int i, dir, ret; |
| 1501 | int tdm_slots = mcasp->tdm_slots; | 1731 | int tdm_slots; |
| 1502 | u8 *numevt; | 1732 | u8 *numevt; |
| 1503 | | 1733 | |
| 1504 | /* Do not allow more then one stream per direction */ | 1734 | /* Do not allow more then one stream per direction */ |
| @@ -1507,6 +1737,8 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 2 unmodified lines |
| 1507 | | 1737 | |
| 1508 | mcasp->substreams[substream->stream] = substream; | 1738 | mcasp->substreams[substream->stream] = substream; |
| 1509 | | 1739 | |
| | 1740 | tdm_slots = mcasp_get_tdm_slots(mcasp, substream->stream); |
| | 1741 | |
| 1510 | if (mcasp->tdm_mask[substream->stream]) | 1742 | if (mcasp->tdm_mask[substream->stream]) |
| 1511 | tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]); | 1743 | tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]); |
| 1512 | | 1744 | |
| @@ -1528,6 +1760,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 15 unmodified lines |
| 1528 | } | 1760 | } |
| 1529 | ruledata->serializers = max_channels; | 1761 | ruledata->serializers = max_channels; |
| 1530 | ruledata->mcasp = mcasp; | 1762 | ruledata->mcasp = mcasp; |
| | 1763 | ruledata->stream = substream->stream; |
| 1531 | max_channels *= tdm_slots; | 1764 | max_channels *= tdm_slots; |
| 1532 | /* | 1765 | /* |
| 1533 | * If the already active stream has less channels than the calculated | 1766 | * If the already active stream has less channels than the calculated |
| @@ -1535,9 +1768,13 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 1 unmodified line |
| 1535 | * is in use we need to use that as a constraint for the second stream. | 1768 | * is in use we need to use that as a constraint for the second stream. |
| 1536 | * Otherwise (first stream or less allowed channels or more than one | 1769 | * Otherwise (first stream or less allowed channels or more than one |
| 1537 | * serializer in use) we use the calculated constraint. | 1770 | * serializer in use) we use the calculated constraint. |
| | 1771 | * |
| | 1772 | * However, in async mode, TX and RX have independent clocks and can |
| | 1773 | * use different configurations, so don't apply the constraint. |
| 1538 | */ | 1774 | */ |
| 1539 | if (mcasp->channels && mcasp->channels < max_channels && | 1775 | if (mcasp->channels && mcasp->channels < max_channels && |
| 1540 | ruledata->serializers == 1) | 1776 | ruledata->serializers == 1 && |
| | 1777 | !mcasp->async_mode) |
| 1541 | max_channels = mcasp->channels; | 1778 | max_channels = mcasp->channels; |
| 1542 | /* | 1779 | /* |
| 1543 | * But we can always allow channels upto the amount of | 1780 | * But we can always allow channels upto the amount of |
| @@ -1554,10 +1791,10 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 10 unmodified lines |
| 1554 | 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 1791 | 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
| 1555 | &mcasp->chconstr[substream->stream]); | 1792 | &mcasp->chconstr[substream->stream]); |
| 1556 | | 1793 | |
| 1557 | if (mcasp->max_format_width) { | 1794 | if (mcasp->max_format_width && !mcasp->async_mode) { |
| 1558 | /* | 1795 | /* |
| 1559 | * Only allow formats which require same amount of bits on the | 1796 | * Only allow formats which require same amount of bits on the |
| 1560 | * bus as the currently running stream | 1797 | * bus as the currently running stream to ensure sync mode |
| 1561 | */ | 1798 | */ |
| 1562 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, | 1799 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, |
| 1563 | SNDRV_PCM_HW_PARAM_FORMAT, | 1800 | SNDRV_PCM_HW_PARAM_FORMAT, |
| @@ -1566,8 +1803,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 2 unmodified lines |
| 1566 | SNDRV_PCM_HW_PARAM_FORMAT, -1); | 1803 | SNDRV_PCM_HW_PARAM_FORMAT, -1); |
| 1567 | if (ret) | 1804 | if (ret) |
| 1568 | return ret; | 1805 | return ret; |
| 1569 | } | 1806 | } else if (mcasp_get_slot_width(mcasp, substream->stream)) { |
| 1570 | else if (mcasp->slot_width) { | | |
| 1571 | /* Only allow formats require <= slot_width bits on the bus */ | 1807 | /* Only allow formats require <= slot_width bits on the bus */ |
| 1572 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, | 1808 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, |
| 1573 | SNDRV_PCM_HW_PARAM_FORMAT, | 1809 | SNDRV_PCM_HW_PARAM_FORMAT, |
| @@ -1582,7 +1818,8 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 8 unmodified lines |
| 1582 | * If we rely on implicit BCLK divider setting we should | 1818 | * If we rely on implicit BCLK divider setting we should |
| 1583 | * set constraints based on what we can provide. | 1819 | * set constraints based on what we can provide. |
| 1584 | */ | 1820 | */ |
| 1585 | if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { | 1821 | if (mcasp->bclk_master && mcasp_get_bclk_div(mcasp, substream->stream) == 0 && |
| | 1822 | mcasp_get_sysclk_freq(mcasp, substream->stream)) { |
| 1586 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, | 1823 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, |
| 1587 | SNDRV_PCM_HW_PARAM_RATE, | 1824 | SNDRV_PCM_HW_PARAM_RATE, |
| 1588 | davinci_mcasp_hw_rule_rate, | 1825 | davinci_mcasp_hw_rule_rate, |
| @@ -1759,8 +1996,6 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { · 170 unmodified lines |
| 1759 | .formats = DAVINCI_MCASP_PCM_FMTS, | 1996 | .formats = DAVINCI_MCASP_PCM_FMTS, |
| 1760 | }, | 1997 | }, |
| 1761 | .ops = &davinci_mcasp_dai_ops, | 1998 | .ops = &davinci_mcasp_dai_ops, |
| 1762 | | | |
| 1763 | .symmetric_rate = 1, | | |
| 1764 | }, | 1999 | }, |
| 1765 | { | 2000 | { |
| 1766 | .name = "davinci-mcasp.1", | 2001 | .name = "davinci-mcasp.1", |
| @@ -1918,18 +2153,33 @@ static int davinci_mcasp_get_config(struct davinci_mcasp *mcasp, · 151 unmodified lines |
| 1918 | goto out; | 2153 | goto out; |
| 1919 | } | 2154 | } |
| 1920 | | 2155 | |
| | 2156 | /* Parse TX-specific TDM slot and use it as default for RX */ |
| 1921 | if (of_property_read_u32(np, "tdm-slots", &val) == 0) { | 2157 | if (of_property_read_u32(np, "tdm-slots", &val) == 0) { |
| 1922 | if (val < 2 || val > 32) { | 2158 | if (val < 2 || val > 32) { |
| 1923 | dev_err(&pdev->dev, "tdm-slots must be in rage [2-32]\n"); | 2159 | dev_err(&pdev->dev, "tdm-slots must be in range [2-32]\n"); |
| 1924 | return -EINVAL; | 2160 | return -EINVAL; |
| 1925 | } | 2161 | } |
| 1926 | | 2162 | |
| 1927 | pdata->tdm_slots = val; | 2163 | pdata->tdm_slots_tx = val; |
| | 2164 | pdata->tdm_slots_rx = val; |
| 1928 | } else if (pdata->op_mode == DAVINCI_MCASP_IIS_MODE) { | 2165 | } else if (pdata->op_mode == DAVINCI_MCASP_IIS_MODE) { |
| 1929 | mcasp->missing_audio_param = true; | 2166 | mcasp->missing_audio_param = true; |
| 1930 | goto out; | 2167 | goto out; |
| 1931 | } | 2168 | } |
| 1932 | | 2169 | |
| | 2170 | /* Parse RX-specific TDM slot count if provided */ |
| | 2171 | if (of_property_read_u32(np, "tdm-slots-rx", &val) == 0) { |
| | 2172 | if (val < 2 || val > 32) { |
| | 2173 | dev_err(&pdev->dev, "tdm-slots-rx must be in range [2-32]\n"); |
| | 2174 | return -EINVAL; |
| | 2175 | } |
| | 2176 | |
| | 2177 | pdata->tdm_slots_rx = val; |
| | 2178 | } |
| | 2179 | |
| | 2180 | if (pdata->op_mode != DAVINCI_MCASP_DIT_MODE) |
| | 2181 | mcasp->async_mode = of_property_read_bool(np, "ti,async-mode"); |
| | 2182 | |
| 1933 | of_serial_dir32 = of_get_property(np, "serial-dir", &val); | 2183 | of_serial_dir32 = of_get_property(np, "serial-dir", &val); |
| 1934 | val /= sizeof(u32); | 2184 | val /= sizeof(u32); |
| 1935 | if (of_serial_dir32) { | 2185 | if (of_serial_dir32) { |
| @@ -1955,8 +2205,15 @@ static int davinci_mcasp_get_config(struct davinci_mcasp *mcasp, · 19 unmodified lines |
| 1955 | if (of_property_read_u32(np, "rx-num-evt", &val) == 0) | 2205 | if (of_property_read_u32(np, "rx-num-evt", &val) == 0) |
| 1956 | pdata->rxnumevt = val; | 2206 | pdata->rxnumevt = val; |
| 1957 | | 2207 | |
| 1958 | if (of_property_read_u32(np, "auxclk-fs-ratio", &val) == 0) | 2208 | /* Parse TX-specific auxclk/fs ratio and use it as default for RX */ |
| 1959 | mcasp->auxclk_fs_ratio = val; | 2209 | if (of_property_read_u32(np, "auxclk-fs-ratio", &val) == 0) { |
| | 2210 | mcasp->auxclk_fs_ratio_tx = val; |
| | 2211 | mcasp->auxclk_fs_ratio_rx = val; |
| | 2212 | } |
| | 2213 | |
| | 2214 | /* Parse RX-specific auxclk/fs ratio if provided */ |
| | 2215 | if (of_property_read_u32(np, "auxclk-fs-ratio-rx", &val) == 0) |
| | 2216 | mcasp->auxclk_fs_ratio_rx = val; |
| 1960 | | 2217 | |
| 1961 | if (of_property_read_u32(np, "dismod", &val) == 0) { | 2218 | if (of_property_read_u32(np, "dismod", &val) == 0) { |
| 1962 | if (val == 0 || val == 2 || val == 3) { | 2219 | if (val == 0 || val == 2 || val == 3) { |
| @@ -1985,19 +2242,51 @@ out: · 22 unmodified lines |
| 1985 | mcasp->op_mode = pdata->op_mode; | 2242 | mcasp->op_mode = pdata->op_mode; |
| 1986 | /* sanity check for tdm slots parameter */ | 2243 | /* sanity check for tdm slots parameter */ |
| 1987 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) { | 2244 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) { |
| 1988 | if (pdata->tdm_slots < 2) { | 2245 | if (pdata->tdm_slots_tx < 2) { |
| 1989 | dev_warn(&pdev->dev, "invalid tdm slots: %d\n", | 2246 | dev_warn(&pdev->dev, "invalid tdm tx slots: %d\n", |
| 1990 | pdata->tdm_slots); | 2247 | pdata->tdm_slots_tx); |
| 1991 | mcasp->tdm_slots = 2; | 2248 | mcasp->tdm_slots_tx = 2; |
| 1992 | } else if (pdata->tdm_slots > 32) { | 2249 | } else if (pdata->tdm_slots_tx > 32) { |
| 1993 | dev_warn(&pdev->dev, "invalid tdm slots: %d\n", | 2250 | dev_warn(&pdev->dev, "invalid tdm tx slots: %d\n", |
| 1994 | pdata->tdm_slots); | 2251 | pdata->tdm_slots_tx); |
| 1995 | mcasp->tdm_slots = 32; | 2252 | mcasp->tdm_slots_tx = 32; |
| | 2253 | } else { |
| | 2254 | mcasp->tdm_slots_tx = pdata->tdm_slots_tx; |
| | 2255 | } |
| | 2256 | |
| | 2257 | if (pdata->tdm_slots_rx < 2) { |
| | 2258 | dev_warn(&pdev->dev, "invalid tdm rx slots: %d\n", |
| | 2259 | pdata->tdm_slots_rx); |
| | 2260 | mcasp->tdm_slots_rx = 2; |
| | 2261 | } else if (pdata->tdm_slots_rx > 32) { |
| | 2262 | dev_warn(&pdev->dev, "invalid tdm rx slots: %d\n", |
| | 2263 | pdata->tdm_slots_rx); |
| | 2264 | mcasp->tdm_slots_rx = 32; |
| 1996 | } else { | 2265 | } else { |
| 1997 | mcasp->tdm_slots = pdata->tdm_slots; | 2266 | mcasp->tdm_slots_rx = pdata->tdm_slots_rx; |
| 1998 | } | 2267 | } |
| 1999 | } else { | 2268 | } else { |
| 2000 | mcasp->tdm_slots = 32; | 2269 | mcasp->tdm_slots_tx = 32; |
| | 2270 | mcasp->tdm_slots_rx = 32; |
| | 2271 | } |
| | 2272 | |
| | 2273 | /* Different TX/RX slot counts require async mode */ |
| | 2274 | if (pdata->op_mode != DAVINCI_MCASP_DIT_MODE && |
| | 2275 | mcasp->tdm_slots_tx != mcasp->tdm_slots_rx && !mcasp->async_mode) { |
| | 2276 | dev_err(&pdev->dev, |
| | 2277 | "Different TX (%d) and RX (%d) TDM slots require ti,async-mode\n", |
| | 2278 | mcasp->tdm_slots_tx, mcasp->tdm_slots_rx); |
| | 2279 | return -EINVAL; |
| | 2280 | } |
| | 2281 | |
| | 2282 | /* Different TX/RX auxclk-fs-ratio require async mode */ |
| | 2283 | if (pdata->op_mode != DAVINCI_MCASP_DIT_MODE && |
| | 2284 | mcasp->auxclk_fs_ratio_tx && mcasp->auxclk_fs_ratio_rx && |
| | 2285 | mcasp->auxclk_fs_ratio_tx != mcasp->auxclk_fs_ratio_rx && !mcasp->async_mode) { |
| | 2286 | dev_err(&pdev->dev, |
| | 2287 | "Different TX (%d) and RX (%d) auxclk-fs-ratio require ti,async-mode\n", |
| | 2288 | mcasp->auxclk_fs_ratio_tx, mcasp->auxclk_fs_ratio_rx); |
| | 2289 | return -EINVAL; |
| 2001 | } | 2290 | } |
| 2002 | | 2291 | |
| 2003 | mcasp->num_serializer = pdata->num_serializer; | 2292 | mcasp->num_serializer = pdata->num_serializer; |