Lines Matching +full:tri +full:- +full:default +full:- +full:2
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (C) 2014-2015 Broadcom Corporation
14 #include <sound/soc-dai.h>
16 #include "cygnus-ssp.h"
37 #define AUD_MISC_SEROUT_LRCK_OE 2
147 #define BF_SRC_CFGX_SAMPLE_CH_MODE 2
156 #define BF_DST_CFGX_DFIFO_SZ_DOUBLE 2
192 * PLL has 3 output channels (1x, 2x, and 4x). Below are
198 {16384000, 2},
202 {22579200, 2},
206 {24576000, 2},
210 {49152000, 2},
214 {90316800, 2},
218 {98304000, 2},
241 return &cygaud->portinfo[dai->id]; in cygnus_dai_get_portinfo()
249 switch (aio->port_type) { in audio_ssp_init_portregs()
251 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_init_portregs()
255 writel(aio->portnum, in audio_ssp_init_portregs()
256 aio->cygaud->audio + aio->regs.bf_sourcech_grp); in audio_ssp_init_portregs()
259 value |= aio->portnum << I2S_OUT_STREAM_CFG_GROUP_ID; in audio_ssp_init_portregs()
260 value |= aio->portnum; /* FCI ID is the port num */ in audio_ssp_init_portregs()
262 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_init_portregs()
265 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
269 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
272 value = readl(aio->cygaud->i2s_in + in audio_ssp_init_portregs()
273 aio->regs.i2s_cap_stream_cfg); in audio_ssp_init_portregs()
275 value |= aio->portnum << I2S_IN_STREAM_CFG_0_GROUP_ID; in audio_ssp_init_portregs()
276 writel(value, aio->cygaud->i2s_in + in audio_ssp_init_portregs()
277 aio->regs.i2s_cap_stream_cfg); in audio_ssp_init_portregs()
280 fci_id = CAPTURE_FCI_ID_BASE + aio->portnum; in audio_ssp_init_portregs()
282 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_init_portregs()
287 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_init_portregs()
290 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
291 value &= ~BIT((aio->portnum * 4) + AUD_MISC_SEROUT_SDAT_OE); in audio_ssp_init_portregs()
292 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
295 writel(aio->portnum, aio->cygaud->audio + BF_SRC_GRP3_OFFSET); in audio_ssp_init_portregs()
297 value = readl(aio->cygaud->audio + SPDIF_CTRL_OFFSET); in audio_ssp_init_portregs()
299 writel(value, aio->cygaud->audio + SPDIF_CTRL_OFFSET); in audio_ssp_init_portregs()
302 value = readl(aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET); in audio_ssp_init_portregs()
304 value |= aio->portnum; /* FCI ID is the port num */ in audio_ssp_init_portregs()
306 writel(value, aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET); in audio_ssp_init_portregs()
308 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
312 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
315 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
317 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
319 default: in audio_ssp_init_portregs()
320 dev_err(aio->cygaud->dev, "Port not supported\n"); in audio_ssp_init_portregs()
321 status = -EINVAL; in audio_ssp_init_portregs()
331 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_enable()
333 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_enable()
335 writel(0x1, aio->cygaud->audio + aio->regs.bf_destch_ctrl); in audio_ssp_in_enable()
337 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_enable()
340 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_enable()
342 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_enable()
344 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_enable()
346 aio->streams_on |= CAPTURE_STREAM_MASK; in audio_ssp_in_enable()
353 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_disable()
355 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_disable()
357 aio->streams_on &= ~CAPTURE_STREAM_MASK; in audio_ssp_in_disable()
360 if (!aio->streams_on) { in audio_ssp_in_disable()
361 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_disable()
364 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_disable()
367 writel(0x0, aio->cygaud->audio + aio->regs.bf_destch_ctrl); in audio_ssp_in_disable()
369 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_disable()
371 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_disable()
379 switch (aio->port_type) { in audio_ssp_out_enable()
381 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_enable()
383 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_enable()
385 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_enable()
387 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_enable()
390 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_enable()
392 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
394 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
396 aio->streams_on |= PLAYBACK_STREAM_MASK; in audio_ssp_out_enable()
399 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_enable()
401 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_enable()
403 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_enable()
405 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
407 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
409 default: in audio_ssp_out_enable()
410 dev_err(aio->cygaud->dev, in audio_ssp_out_enable()
411 "Port not supported %d\n", aio->portnum); in audio_ssp_out_enable()
412 status = -EINVAL; in audio_ssp_out_enable()
423 switch (aio->port_type) { in audio_ssp_out_disable()
425 aio->streams_on &= ~PLAYBACK_STREAM_MASK; in audio_ssp_out_disable()
428 if (!aio->streams_on) { in audio_ssp_out_disable()
429 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_disable()
432 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_disable()
436 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
437 value |= BIT(aio->portnum); in audio_ssp_out_disable()
438 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
440 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_disable()
442 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
444 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
447 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
448 value &= ~BIT(aio->portnum); in audio_ssp_out_disable()
449 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
451 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_disable()
453 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_disable()
456 value = readl(aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC); in audio_ssp_out_disable()
457 value |= BIT(aio->portnum); in audio_ssp_out_disable()
458 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC); in audio_ssp_out_disable()
459 value &= ~BIT(aio->portnum); in audio_ssp_out_disable()
460 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC); in audio_ssp_out_disable()
463 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_disable()
465 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_disable()
466 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_disable()
468 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
470 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
472 default: in audio_ssp_out_disable()
473 dev_err(aio->cygaud->dev, in audio_ssp_out_disable()
474 "Port not supported %d\n", aio->portnum); in audio_ssp_out_disable()
475 status = -EINVAL; in audio_ssp_out_disable()
491 if (p_entry->mclk == mclk) { in pll_configure_mclk()
497 dev_err(cygaud->dev, in pll_configure_mclk()
499 return -EINVAL; in pll_configure_mclk()
502 ch_clk = cygaud->audio_clk[p_entry->pll_ch_num]; in pll_configure_mclk()
504 if ((aio->clk_trace.cap_en) && (!aio->clk_trace.cap_clk_en)) { in pll_configure_mclk()
507 dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n", in pll_configure_mclk()
511 aio->clk_trace.cap_clk_en = true; in pll_configure_mclk()
514 if ((aio->clk_trace.play_en) && (!aio->clk_trace.play_clk_en)) { in pll_configure_mclk()
517 dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n", in pll_configure_mclk()
521 aio->clk_trace.play_clk_en = true; in pll_configure_mclk()
526 dev_err(cygaud->dev, "%s Set MCLK rate failed: %d\n", in pll_configure_mclk()
531 return p_entry->pll_ch_num; in pll_configure_mclk()
543 bit_rate = aio->bit_per_frame * aio->lrclk; in cygnus_ssp_set_clocks()
548 * following values... (2,4,6,8,10,12,14) in cygnus_ssp_set_clocks()
550 if ((aio->mclk % bit_rate) != 0) in cygnus_ssp_set_clocks()
551 return -EINVAL; in cygnus_ssp_set_clocks()
553 ratio = aio->mclk / bit_rate; in cygnus_ssp_set_clocks()
555 case 2: in cygnus_ssp_set_clocks()
562 mclk_rate = ratio / 2; in cygnus_ssp_set_clocks()
565 default: in cygnus_ssp_set_clocks()
566 dev_err(aio->cygaud->dev, in cygnus_ssp_set_clocks()
568 dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n", in cygnus_ssp_set_clocks()
569 aio->lrclk, aio->bit_per_frame, aio->mclk); in cygnus_ssp_set_clocks()
570 return -EINVAL; in cygnus_ssp_set_clocks()
574 switch (aio->port_type) { in cygnus_ssp_set_clocks()
576 sclk = aio->bit_per_frame; in cygnus_ssp_set_clocks()
584 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_clocks()
587 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_clocks()
588 dev_dbg(aio->cygaud->dev, in cygnus_ssp_set_clocks()
593 default: in cygnus_ssp_set_clocks()
594 dev_err(aio->cygaud->dev, "Unknown port type\n"); in cygnus_ssp_set_clocks()
595 return -EINVAL; in cygnus_ssp_set_clocks()
599 value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_clocks()
602 writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_clocks()
604 dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value); in cygnus_ssp_set_clocks()
605 dev_dbg(aio->cygaud->dev, "bits per frame = %u, mclk = %u Hz, lrclk = %u Hz\n", in cygnus_ssp_set_clocks()
606 aio->bit_per_frame, aio->mclk, aio->lrclk); in cygnus_ssp_set_clocks()
620 dev_dbg(aio->cygaud->dev, "%s port = %d\n", __func__, aio->portnum); in cygnus_ssp_hw_params()
621 dev_dbg(aio->cygaud->dev, "params_channels %d\n", in cygnus_ssp_hw_params()
623 dev_dbg(aio->cygaud->dev, "rate %d\n", params_rate(params)); in cygnus_ssp_hw_params()
624 dev_dbg(aio->cygaud->dev, "format %d\n", params_format(params)); in cygnus_ssp_hw_params()
628 switch (aio->mode) { in cygnus_ssp_hw_params()
631 dev_err(aio->cygaud->dev, "Cannot run %d channels at %dHz\n", in cygnus_ssp_hw_params()
633 return -EINVAL; in cygnus_ssp_hw_params()
637 aio->bit_per_frame = 64; /* I2S must be 64 bit per frame */ in cygnus_ssp_hw_params()
639 default: in cygnus_ssp_hw_params()
640 dev_err(aio->cygaud->dev, in cygnus_ssp_hw_params()
642 return -EINVAL; in cygnus_ssp_hw_params()
645 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cygnus_ssp_hw_params()
646 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
649 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
661 default: in cygnus_ssp_hw_params()
662 return -EINVAL; in cygnus_ssp_hw_params()
665 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
668 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
674 value = readl(aio->cygaud->audio + in cygnus_ssp_hw_params()
675 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
677 writel(value, aio->cygaud->audio + in cygnus_ssp_hw_params()
678 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
682 value = readl(aio->cygaud->audio + in cygnus_ssp_hw_params()
683 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
685 writel(value, aio->cygaud->audio + in cygnus_ssp_hw_params()
686 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
689 default: in cygnus_ssp_hw_params()
690 return -EINVAL; in cygnus_ssp_hw_params()
694 aio->lrclk = rate; in cygnus_ssp_hw_params()
696 if (!aio->is_slave) in cygnus_ssp_hw_params()
713 dev_dbg(aio->cygaud->dev, in cygnus_ssp_set_sysclk()
714 "%s Enter port = %d\n", __func__, aio->portnum); in cygnus_ssp_set_sysclk()
717 dev_err(aio->cygaud->dev, in cygnus_ssp_set_sysclk()
719 return -EINVAL; in cygnus_ssp_set_sysclk()
722 aio->mclk = freq; in cygnus_ssp_set_sysclk()
724 dev_dbg(aio->cygaud->dev, "%s Setting MCLKSEL to %d\n", __func__, sel); in cygnus_ssp_set_sysclk()
725 value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_sysclk()
728 writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_sysclk()
739 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_startup()
740 aio->clk_trace.play_en = true; in cygnus_ssp_startup()
742 aio->clk_trace.cap_en = true; in cygnus_ssp_startup()
744 substream->runtime->hw.rate_min = CYGNUS_RATE_MIN; in cygnus_ssp_startup()
745 substream->runtime->hw.rate_max = CYGNUS_RATE_MAX; in cygnus_ssp_startup()
747 snd_pcm_hw_constraint_list(substream->runtime, 0, in cygnus_ssp_startup()
757 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_shutdown()
758 aio->clk_trace.play_en = false; in cygnus_ssp_shutdown()
760 aio->clk_trace.cap_en = false; in cygnus_ssp_shutdown()
762 if (!aio->is_slave) { in cygnus_ssp_shutdown()
765 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_shutdown()
767 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) { in cygnus_ssp_shutdown()
768 dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n", in cygnus_ssp_shutdown()
773 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cygnus_ssp_shutdown()
774 if (aio->clk_trace.play_clk_en) { in cygnus_ssp_shutdown()
775 clk_disable_unprepare(aio->cygaud-> in cygnus_ssp_shutdown()
777 aio->clk_trace.play_clk_en = false; in cygnus_ssp_shutdown()
780 if (aio->clk_trace.cap_clk_en) { in cygnus_ssp_shutdown()
781 clk_disable_unprepare(aio->cygaud-> in cygnus_ssp_shutdown()
783 aio->clk_trace.cap_clk_en = false; in cygnus_ssp_shutdown()
802 * 03:02 Yes Reserved - write as zero
816 aio->fsync_width = len; in cygnus_ssp_set_custom_fsync_width()
819 return -EINVAL; in cygnus_ssp_set_custom_fsync_width()
834 dev_dbg(aio->cygaud->dev, "%s Enter fmt: %x\n", __func__, fmt); in cygnus_ssp_set_fmt()
836 if (aio->port_type == PORT_SPDIF) in cygnus_ssp_set_fmt()
837 return -EINVAL; in cygnus_ssp_set_fmt()
844 aio->is_slave = 1; in cygnus_ssp_set_fmt()
848 aio->is_slave = 0; in cygnus_ssp_set_fmt()
850 default: in cygnus_ssp_set_fmt()
851 return -EINVAL; in cygnus_ssp_set_fmt()
858 aio->mode = CYGNUS_SSPMODE_I2S; in cygnus_ssp_set_fmt()
869 if ((aio->fsync_width > 0) && (aio->fsync_width < 256)) in cygnus_ssp_set_fmt()
871 (aio->fsync_width << I2S_OUT_CFGX_FSYNC_WIDTH); in cygnus_ssp_set_fmt()
875 aio->mode = CYGNUS_SSPMODE_TDM; in cygnus_ssp_set_fmt()
878 default: in cygnus_ssp_set_fmt()
879 return -EINVAL; in cygnus_ssp_set_fmt()
886 ssp_curcfg = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_fmt()
888 writel(ssp_outcfg, aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_fmt()
894 ssp_curcfg = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_ssp_set_fmt()
896 writel(ssp_incfg, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_ssp_set_fmt()
898 val = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in cygnus_ssp_set_fmt()
908 mask = mask << (aio->portnum * 4); in cygnus_ssp_set_fmt()
909 if (aio->is_slave) in cygnus_ssp_set_fmt()
910 /* Set bit for tri-state */ in cygnus_ssp_set_fmt()
916 dev_dbg(aio->cygaud->dev, "%s Set OE bits 0x%x\n", __func__, val); in cygnus_ssp_set_fmt()
917 writel(val, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in cygnus_ssp_set_fmt()
928 dev_dbg(aio->cygaud->dev, in cygnus_ssp_trigger()
929 "%s cmd %d at port = %d\n", __func__, cmd, aio->portnum); in cygnus_ssp_trigger()
935 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_trigger()
939 cygaud->active_ports++; in cygnus_ssp_trigger()
946 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_trigger()
950 cygaud->active_ports--; in cygnus_ssp_trigger()
953 default: in cygnus_ssp_trigger()
954 return -EINVAL; in cygnus_ssp_trigger()
965 int bits_per_slot = 0; /* default to 32-bits per slot */ in cygnus_set_dai_tdm_slot()
972 dev_err(aio->cygaud->dev, in cygnus_set_dai_tdm_slot()
974 return -EINVAL; in cygnus_set_dai_tdm_slot()
980 return -EINVAL; in cygnus_set_dai_tdm_slot()
983 if (active_slots % 2) in cygnus_set_dai_tdm_slot()
984 return -EINVAL; in cygnus_set_dai_tdm_slot()
998 default: in cygnus_set_dai_tdm_slot()
1000 dev_warn(aio->cygaud->dev, in cygnus_set_dai_tdm_slot()
1014 dev_err(aio->cygaud->dev, in cygnus_set_dai_tdm_slot()
1017 return -EINVAL; in cygnus_set_dai_tdm_slot()
1020 aio->bit_per_frame = frame_bits; in cygnus_set_dai_tdm_slot()
1022 dev_dbg(aio->cygaud->dev, "%s active_slots %u, bits per frame %d\n", in cygnus_set_dai_tdm_slot()
1026 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_set_dai_tdm_slot()
1031 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_set_dai_tdm_slot()
1034 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_set_dai_tdm_slot()
1039 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_set_dai_tdm_slot()
1052 if (!aio->is_slave) { in __cygnus_ssp_suspend()
1055 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in __cygnus_ssp_suspend()
1057 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) { in __cygnus_ssp_suspend()
1058 dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n", in __cygnus_ssp_suspend()
1060 return -EINVAL; in __cygnus_ssp_suspend()
1063 if (aio->clk_trace.cap_clk_en) in __cygnus_ssp_suspend()
1064 clk_disable_unprepare(aio->cygaud->audio_clk[val]); in __cygnus_ssp_suspend()
1065 if (aio->clk_trace.play_clk_en) in __cygnus_ssp_suspend()
1066 clk_disable_unprepare(aio->cygaud->audio_clk[val]); in __cygnus_ssp_suspend()
1068 aio->pll_clk_num = val; in __cygnus_ssp_suspend()
1093 if (!aio->is_slave) { in __cygnus_ssp_resume()
1094 if (aio->clk_trace.cap_clk_en) { in __cygnus_ssp_resume()
1095 error = clk_prepare_enable(aio->cygaud-> in __cygnus_ssp_resume()
1096 audio_clk[aio->pll_clk_num]); in __cygnus_ssp_resume()
1098 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n", in __cygnus_ssp_resume()
1100 return -EINVAL; in __cygnus_ssp_resume()
1103 if (aio->clk_trace.play_clk_en) { in __cygnus_ssp_resume()
1104 error = clk_prepare_enable(aio->cygaud-> in __cygnus_ssp_resume()
1105 audio_clk[aio->pll_clk_num]); in __cygnus_ssp_resume()
1107 if (aio->clk_trace.cap_clk_en) in __cygnus_ssp_resume()
1108 clk_disable_unprepare(aio->cygaud-> in __cygnus_ssp_resume()
1109 audio_clk[aio->pll_clk_num]); in __cygnus_ssp_resume()
1110 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n", in __cygnus_ssp_resume()
1112 return -EINVAL; in __cygnus_ssp_resume()
1155 .name = "cygnus-ssp" #num, \
1157 .channels_min = 2, \
1164 .channels_min = 2, \
1176 INIT_CPU_DAI(2),
1180 .name = "cygnus-spdif",
1182 .channels_min = 2,
1183 .channels_max = 2,
1194 .name = "cygnus-audio",
1213 int portnum = -1; in parse_ssp_child_node()
1217 dev_err(&pdev->dev, "Missing reg property\n"); in parse_ssp_child_node()
1218 return -EINVAL; in parse_ssp_child_node()
1231 case 2: in parse_ssp_child_node()
1232 ssp_regs[2] = INIT_SSP_REGS(2); in parse_ssp_child_node()
1238 default: in parse_ssp_child_node()
1239 dev_err(&pdev->dev, "Bad value for reg %u\n", rawval); in parse_ssp_child_node()
1240 return -EINVAL; in parse_ssp_child_node()
1243 aio = &cygaud->portinfo[portnum]; in parse_ssp_child_node()
1244 aio->cygaud = cygaud; in parse_ssp_child_node()
1245 aio->portnum = portnum; in parse_ssp_child_node()
1246 aio->port_type = port_type; in parse_ssp_child_node()
1247 aio->fsync_width = -1; in parse_ssp_child_node()
1251 aio->regs = ssp_regs[portnum]; in parse_ssp_child_node()
1253 aio->mode = CYGNUS_SSPMODE_UNKNOWN; in parse_ssp_child_node()
1257 aio->regs.bf_sourcech_cfg = BF_SRC_CFG3_OFFSET; in parse_ssp_child_node()
1258 aio->regs.bf_sourcech_ctrl = BF_SRC_CTRL3_OFFSET; in parse_ssp_child_node()
1259 aio->regs.i2s_mclk_cfg = SPDIF_MCLK_CFG_OFFSET; in parse_ssp_child_node()
1260 aio->regs.i2s_stream_cfg = SPDIF_STREAM_CFG_OFFSET; in parse_ssp_child_node()
1264 aio->mode = CYGNUS_SSPMODE_I2S; in parse_ssp_child_node()
1266 default: in parse_ssp_child_node()
1267 dev_err(&pdev->dev, "Bad value for port_type %d\n", port_type); in parse_ssp_child_node()
1268 return -EINVAL; in parse_ssp_child_node()
1271 dev_dbg(&pdev->dev, "%s portnum = %d\n", __func__, aio->portnum); in parse_ssp_child_node()
1272 aio->streams_on = 0; in parse_ssp_child_node()
1273 aio->cygaud->dev = &pdev->dev; in parse_ssp_child_node()
1274 aio->clk_trace.play_en = false; in parse_ssp_child_node()
1275 aio->clk_trace.cap_en = false; in parse_ssp_child_node()
1287 for (i = 0; i < ARRAY_SIZE(cygaud->audio_clk); i++) { in audio_clk_init()
1290 cygaud->audio_clk[i] = devm_clk_get(&pdev->dev, clk_name); in audio_clk_init()
1291 if (IS_ERR(cygaud->audio_clk[i])) in audio_clk_init()
1292 return PTR_ERR(cygaud->audio_clk[i]); in audio_clk_init()
1300 struct device *dev = &pdev->dev; in cygnus_ssp_probe()
1309 return -ENOMEM; in cygnus_ssp_probe()
1313 cygaud->audio = devm_platform_ioremap_resource_byname(pdev, "aud"); in cygnus_ssp_probe()
1314 if (IS_ERR(cygaud->audio)) in cygnus_ssp_probe()
1315 return PTR_ERR(cygaud->audio); in cygnus_ssp_probe()
1317 cygaud->i2s_in = devm_platform_ioremap_resource_byname(pdev, "i2s_in"); in cygnus_ssp_probe()
1318 if (IS_ERR(cygaud->i2s_in)) in cygnus_ssp_probe()
1319 return PTR_ERR(cygaud->i2s_in); in cygnus_ssp_probe()
1321 /* Tri-state all controlable pins until we know that we need them */ in cygnus_ssp_probe()
1323 cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in cygnus_ssp_probe()
1325 node_count = of_get_child_count(pdev->dev.of_node); in cygnus_ssp_probe()
1329 return -EINVAL; in cygnus_ssp_probe()
1334 for_each_available_child_of_node(pdev->dev.of_node, child_node) { in cygnus_ssp_probe()
1350 cygaud->dev = dev; in cygnus_ssp_probe()
1351 cygaud->active_ports = 0; in cygnus_ssp_probe()
1361 cygaud->irq_num = platform_get_irq(pdev, 0); in cygnus_ssp_probe()
1362 if (cygaud->irq_num <= 0) in cygnus_ssp_probe()
1363 return cygaud->irq_num; in cygnus_ssp_probe()
1382 cygnus_soc_platform_unregister(&pdev->dev); in cygnus_ssp_remove()
1386 { .compatible = "brcm,cygnus-audio" },
1395 .name = "cygnus-ssp",
1402 MODULE_ALIAS("platform:cygnus-ssp");