Lines Matching +full:mclk +full:- +full:equal +full:- +full:bclk
2 * Copyright (C) 2014-2015 Broadcom Corporation
24 #include <sound/soc-dai.h>
26 #include "cygnus-ssp.h"
197 u32 mclk; member
203 * the common MCLK frequencies used by audio driver
251 return &cygaud->portinfo[dai->id]; in cygnus_dai_get_portinfo()
259 switch (aio->port_type) { in audio_ssp_init_portregs()
261 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_init_portregs()
265 writel(aio->portnum, in audio_ssp_init_portregs()
266 aio->cygaud->audio + aio->regs.bf_sourcech_grp); in audio_ssp_init_portregs()
269 value |= aio->portnum << I2S_OUT_STREAM_CFG_GROUP_ID; in audio_ssp_init_portregs()
270 value |= aio->portnum; /* FCI ID is the port num */ in audio_ssp_init_portregs()
272 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_init_portregs()
275 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
279 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
282 value = readl(aio->cygaud->i2s_in + in audio_ssp_init_portregs()
283 aio->regs.i2s_cap_stream_cfg); in audio_ssp_init_portregs()
285 value |= aio->portnum << I2S_IN_STREAM_CFG_0_GROUP_ID; in audio_ssp_init_portregs()
286 writel(value, aio->cygaud->i2s_in + in audio_ssp_init_portregs()
287 aio->regs.i2s_cap_stream_cfg); in audio_ssp_init_portregs()
290 fci_id = CAPTURE_FCI_ID_BASE + aio->portnum; in audio_ssp_init_portregs()
292 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_init_portregs()
297 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_init_portregs()
300 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
301 value &= ~BIT((aio->portnum * 4) + AUD_MISC_SEROUT_SDAT_OE); in audio_ssp_init_portregs()
302 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
305 writel(aio->portnum, aio->cygaud->audio + BF_SRC_GRP3_OFFSET); in audio_ssp_init_portregs()
307 value = readl(aio->cygaud->audio + SPDIF_CTRL_OFFSET); in audio_ssp_init_portregs()
309 writel(value, aio->cygaud->audio + SPDIF_CTRL_OFFSET); in audio_ssp_init_portregs()
312 value = readl(aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET); in audio_ssp_init_portregs()
314 value |= aio->portnum; /* FCI ID is the port num */ in audio_ssp_init_portregs()
316 writel(value, aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET); in audio_ssp_init_portregs()
318 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
322 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_init_portregs()
325 value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
327 writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in audio_ssp_init_portregs()
330 dev_err(aio->cygaud->dev, "Port not supported\n"); in audio_ssp_init_portregs()
331 status = -EINVAL; in audio_ssp_init_portregs()
341 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_enable()
343 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_enable()
345 writel(0x1, aio->cygaud->audio + aio->regs.bf_destch_ctrl); in audio_ssp_in_enable()
347 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_enable()
350 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_enable()
352 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_enable()
354 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_enable()
356 aio->streams_on |= CAPTURE_STREAM_MASK; in audio_ssp_in_enable()
363 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_disable()
365 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg); in audio_ssp_in_disable()
367 aio->streams_on &= ~CAPTURE_STREAM_MASK; in audio_ssp_in_disable()
370 if (!aio->streams_on) { in audio_ssp_in_disable()
371 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_disable()
374 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_in_disable()
377 writel(0x0, aio->cygaud->audio + aio->regs.bf_destch_ctrl); in audio_ssp_in_disable()
379 value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_disable()
381 writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg); in audio_ssp_in_disable()
389 switch (aio->port_type) { in audio_ssp_out_enable()
391 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_enable()
393 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_enable()
395 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_enable()
397 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_enable()
400 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_enable()
402 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
404 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
406 aio->streams_on |= PLAYBACK_STREAM_MASK; in audio_ssp_out_enable()
409 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_enable()
411 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_enable()
413 writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_enable()
415 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
417 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_enable()
420 dev_err(aio->cygaud->dev, in audio_ssp_out_enable()
421 "Port not supported %d\n", aio->portnum); in audio_ssp_out_enable()
422 status = -EINVAL; in audio_ssp_out_enable()
433 switch (aio->port_type) { in audio_ssp_out_disable()
435 aio->streams_on &= ~PLAYBACK_STREAM_MASK; in audio_ssp_out_disable()
438 if (!aio->streams_on) { in audio_ssp_out_disable()
439 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_disable()
442 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in audio_ssp_out_disable()
446 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
447 value |= BIT(aio->portnum); in audio_ssp_out_disable()
448 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
450 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_disable()
452 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
454 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
457 value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
458 value &= ~BIT(aio->portnum); in audio_ssp_out_disable()
459 writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET); in audio_ssp_out_disable()
461 value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_disable()
463 writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg); in audio_ssp_out_disable()
466 value = readl(aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC); in audio_ssp_out_disable()
467 value |= BIT(aio->portnum); in audio_ssp_out_disable()
468 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC); in audio_ssp_out_disable()
469 value &= ~BIT(aio->portnum); in audio_ssp_out_disable()
470 writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC); in audio_ssp_out_disable()
473 value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_disable()
475 writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET); in audio_ssp_out_disable()
476 writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl); in audio_ssp_out_disable()
478 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
480 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in audio_ssp_out_disable()
483 dev_err(aio->cygaud->dev, in audio_ssp_out_disable()
484 "Port not supported %d\n", aio->portnum); in audio_ssp_out_disable()
485 status = -EINVAL; in audio_ssp_out_disable()
491 static int pll_configure_mclk(struct cygnus_audio *cygaud, u32 mclk, in pll_configure_mclk() argument
501 if (p_entry->mclk == mclk) { in pll_configure_mclk()
507 dev_err(cygaud->dev, in pll_configure_mclk()
508 "%s No valid mclk freq (%u) found!\n", __func__, mclk); in pll_configure_mclk()
509 return -EINVAL; in pll_configure_mclk()
512 ch_clk = cygaud->audio_clk[p_entry->pll_ch_num]; in pll_configure_mclk()
514 if ((aio->clk_trace.cap_en) && (!aio->clk_trace.cap_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.cap_clk_en = true; in pll_configure_mclk()
524 if ((aio->clk_trace.play_en) && (!aio->clk_trace.play_clk_en)) { in pll_configure_mclk()
527 dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n", in pll_configure_mclk()
531 aio->clk_trace.play_clk_en = true; in pll_configure_mclk()
534 error = clk_set_rate(ch_clk, mclk); in pll_configure_mclk()
536 dev_err(cygaud->dev, "%s Set MCLK rate failed: %d\n", in pll_configure_mclk()
541 return p_entry->pll_ch_num; in pll_configure_mclk()
553 bit_rate = aio->bit_per_frame * aio->lrclk; in cygnus_ssp_set_clocks()
556 * Check if the bit clock can be generated from the given MCLK. in cygnus_ssp_set_clocks()
557 * MCLK must be a perfect multiple of bit clock and must be one of the in cygnus_ssp_set_clocks()
560 if ((aio->mclk % bit_rate) != 0) in cygnus_ssp_set_clocks()
561 return -EINVAL; in cygnus_ssp_set_clocks()
563 ratio = aio->mclk / bit_rate; in cygnus_ssp_set_clocks()
576 dev_err(aio->cygaud->dev, in cygnus_ssp_set_clocks()
577 "Invalid combination of MCLK and BCLK\n"); in cygnus_ssp_set_clocks()
578 dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n", in cygnus_ssp_set_clocks()
579 aio->lrclk, aio->bit_per_frame, aio->mclk); in cygnus_ssp_set_clocks()
580 return -EINVAL; in cygnus_ssp_set_clocks()
584 switch (aio->port_type) { in cygnus_ssp_set_clocks()
586 sclk = aio->bit_per_frame; in cygnus_ssp_set_clocks()
594 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_clocks()
597 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_clocks()
598 dev_dbg(aio->cygaud->dev, in cygnus_ssp_set_clocks()
604 dev_err(aio->cygaud->dev, "Unknown port type\n"); in cygnus_ssp_set_clocks()
605 return -EINVAL; in cygnus_ssp_set_clocks()
609 value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_clocks()
612 writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_clocks()
614 dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value); in cygnus_ssp_set_clocks()
615 dev_dbg(aio->cygaud->dev, "bits per frame = %u, mclk = %u Hz, lrclk = %u Hz\n", in cygnus_ssp_set_clocks()
616 aio->bit_per_frame, aio->mclk, aio->lrclk); in cygnus_ssp_set_clocks()
630 dev_dbg(aio->cygaud->dev, "%s port = %d\n", __func__, aio->portnum); in cygnus_ssp_hw_params()
631 dev_dbg(aio->cygaud->dev, "params_channels %d\n", in cygnus_ssp_hw_params()
633 dev_dbg(aio->cygaud->dev, "rate %d\n", params_rate(params)); in cygnus_ssp_hw_params()
634 dev_dbg(aio->cygaud->dev, "format %d\n", params_format(params)); in cygnus_ssp_hw_params()
638 switch (aio->mode) { in cygnus_ssp_hw_params()
641 dev_err(aio->cygaud->dev, "Cannot run %d channels at %dHz\n", in cygnus_ssp_hw_params()
643 return -EINVAL; in cygnus_ssp_hw_params()
647 aio->bit_per_frame = 64; /* I2S must be 64 bit per frame */ in cygnus_ssp_hw_params()
650 dev_err(aio->cygaud->dev, in cygnus_ssp_hw_params()
652 return -EINVAL; in cygnus_ssp_hw_params()
655 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cygnus_ssp_hw_params()
656 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
659 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
672 return -EINVAL; in cygnus_ssp_hw_params()
675 value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
678 writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg); in cygnus_ssp_hw_params()
684 value = readl(aio->cygaud->audio + in cygnus_ssp_hw_params()
685 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
687 writel(value, aio->cygaud->audio + in cygnus_ssp_hw_params()
688 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
692 value = readl(aio->cygaud->audio + in cygnus_ssp_hw_params()
693 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
695 writel(value, aio->cygaud->audio + in cygnus_ssp_hw_params()
696 aio->regs.bf_destch_cfg); in cygnus_ssp_hw_params()
700 return -EINVAL; in cygnus_ssp_hw_params()
704 aio->lrclk = rate; in cygnus_ssp_hw_params()
706 if (!aio->is_slave) in cygnus_ssp_hw_params()
713 * This function sets the mclk frequency for pll clock
723 dev_dbg(aio->cygaud->dev, in cygnus_ssp_set_sysclk()
724 "%s Enter port = %d\n", __func__, aio->portnum); in cygnus_ssp_set_sysclk()
727 dev_err(aio->cygaud->dev, in cygnus_ssp_set_sysclk()
728 "%s Setting mclk failed.\n", __func__); in cygnus_ssp_set_sysclk()
729 return -EINVAL; in cygnus_ssp_set_sysclk()
732 aio->mclk = freq; in cygnus_ssp_set_sysclk()
734 dev_dbg(aio->cygaud->dev, "%s Setting MCLKSEL to %d\n", __func__, sel); in cygnus_ssp_set_sysclk()
735 value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_sysclk()
738 writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_set_sysclk()
749 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_startup()
750 aio->clk_trace.play_en = true; in cygnus_ssp_startup()
752 aio->clk_trace.cap_en = true; in cygnus_ssp_startup()
754 substream->runtime->hw.rate_min = CYGNUS_RATE_MIN; in cygnus_ssp_startup()
755 substream->runtime->hw.rate_max = CYGNUS_RATE_MAX; in cygnus_ssp_startup()
757 snd_pcm_hw_constraint_list(substream->runtime, 0, in cygnus_ssp_startup()
767 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_shutdown()
768 aio->clk_trace.play_en = false; in cygnus_ssp_shutdown()
770 aio->clk_trace.cap_en = false; in cygnus_ssp_shutdown()
772 if (!aio->is_slave) { in cygnus_ssp_shutdown()
775 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in cygnus_ssp_shutdown()
777 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) { in cygnus_ssp_shutdown()
778 dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n", in cygnus_ssp_shutdown()
783 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cygnus_ssp_shutdown()
784 if (aio->clk_trace.play_clk_en) { in cygnus_ssp_shutdown()
785 clk_disable_unprepare(aio->cygaud-> in cygnus_ssp_shutdown()
787 aio->clk_trace.play_clk_en = false; in cygnus_ssp_shutdown()
790 if (aio->clk_trace.cap_clk_en) { in cygnus_ssp_shutdown()
791 clk_disable_unprepare(aio->cygaud-> in cygnus_ssp_shutdown()
793 aio->clk_trace.cap_clk_en = false; in cygnus_ssp_shutdown()
812 * 03:02 Yes Reserved - write as zero
826 aio->fsync_width = len; in cygnus_ssp_set_custom_fsync_width()
829 return -EINVAL; in cygnus_ssp_set_custom_fsync_width()
844 dev_dbg(aio->cygaud->dev, "%s Enter fmt: %x\n", __func__, fmt); in cygnus_ssp_set_fmt()
846 if (aio->port_type == PORT_SPDIF) in cygnus_ssp_set_fmt()
847 return -EINVAL; in cygnus_ssp_set_fmt()
854 aio->is_slave = 1; in cygnus_ssp_set_fmt()
858 aio->is_slave = 0; in cygnus_ssp_set_fmt()
861 return -EINVAL; in cygnus_ssp_set_fmt()
868 aio->mode = CYGNUS_SSPMODE_I2S; in cygnus_ssp_set_fmt()
879 if ((aio->fsync_width > 0) && (aio->fsync_width < 256)) in cygnus_ssp_set_fmt()
881 (aio->fsync_width << I2S_OUT_CFGX_FSYNC_WIDTH); in cygnus_ssp_set_fmt()
885 aio->mode = CYGNUS_SSPMODE_TDM; in cygnus_ssp_set_fmt()
889 return -EINVAL; in cygnus_ssp_set_fmt()
896 ssp_curcfg = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_fmt()
898 writel(ssp_outcfg, aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_ssp_set_fmt()
904 ssp_curcfg = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_ssp_set_fmt()
906 writel(ssp_incfg, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_ssp_set_fmt()
908 val = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in cygnus_ssp_set_fmt()
918 mask = mask << (aio->portnum * 4); in cygnus_ssp_set_fmt()
919 if (aio->is_slave) in cygnus_ssp_set_fmt()
920 /* Set bit for tri-state */ in cygnus_ssp_set_fmt()
926 dev_dbg(aio->cygaud->dev, "%s Set OE bits 0x%x\n", __func__, val); in cygnus_ssp_set_fmt()
927 writel(val, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in cygnus_ssp_set_fmt()
938 dev_dbg(aio->cygaud->dev, in cygnus_ssp_trigger()
939 "%s cmd %d at port = %d\n", __func__, cmd, aio->portnum); in cygnus_ssp_trigger()
945 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_trigger()
949 cygaud->active_ports++; in cygnus_ssp_trigger()
956 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cygnus_ssp_trigger()
960 cygaud->active_ports--; in cygnus_ssp_trigger()
964 return -EINVAL; in cygnus_ssp_trigger()
975 int bits_per_slot = 0; /* default to 32-bits per slot */ in cygnus_set_dai_tdm_slot()
982 dev_err(aio->cygaud->dev, in cygnus_set_dai_tdm_slot()
983 "%s tx_mask must equal rx_mask\n", __func__); in cygnus_set_dai_tdm_slot()
984 return -EINVAL; in cygnus_set_dai_tdm_slot()
990 return -EINVAL; in cygnus_set_dai_tdm_slot()
994 return -EINVAL; in cygnus_set_dai_tdm_slot()
1010 dev_warn(aio->cygaud->dev, in cygnus_set_dai_tdm_slot()
1024 dev_err(aio->cygaud->dev, in cygnus_set_dai_tdm_slot()
1027 return -EINVAL; in cygnus_set_dai_tdm_slot()
1030 aio->bit_per_frame = frame_bits; in cygnus_set_dai_tdm_slot()
1032 dev_dbg(aio->cygaud->dev, "%s active_slots %u, bits per frame %d\n", in cygnus_set_dai_tdm_slot()
1036 value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_set_dai_tdm_slot()
1041 writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg); in cygnus_set_dai_tdm_slot()
1044 value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_set_dai_tdm_slot()
1049 writel(value, aio->cygaud->audio + aio->regs.i2s_cfg); in cygnus_set_dai_tdm_slot()
1062 if (!aio->is_slave) { in __cygnus_ssp_suspend()
1065 val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); in __cygnus_ssp_suspend()
1067 if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) { in __cygnus_ssp_suspend()
1068 dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n", in __cygnus_ssp_suspend()
1070 return -EINVAL; in __cygnus_ssp_suspend()
1073 if (aio->clk_trace.cap_clk_en) in __cygnus_ssp_suspend()
1074 clk_disable_unprepare(aio->cygaud->audio_clk[val]); in __cygnus_ssp_suspend()
1075 if (aio->clk_trace.play_clk_en) in __cygnus_ssp_suspend()
1076 clk_disable_unprepare(aio->cygaud->audio_clk[val]); in __cygnus_ssp_suspend()
1078 aio->pll_clk_num = val; in __cygnus_ssp_suspend()
1103 if (!aio->is_slave) { in __cygnus_ssp_resume()
1104 if (aio->clk_trace.cap_clk_en) { in __cygnus_ssp_resume()
1105 error = clk_prepare_enable(aio->cygaud-> in __cygnus_ssp_resume()
1106 audio_clk[aio->pll_clk_num]); in __cygnus_ssp_resume()
1108 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n", in __cygnus_ssp_resume()
1110 return -EINVAL; in __cygnus_ssp_resume()
1113 if (aio->clk_trace.play_clk_en) { in __cygnus_ssp_resume()
1114 error = clk_prepare_enable(aio->cygaud-> in __cygnus_ssp_resume()
1115 audio_clk[aio->pll_clk_num]); in __cygnus_ssp_resume()
1117 if (aio->clk_trace.cap_clk_en) in __cygnus_ssp_resume()
1118 clk_disable_unprepare(aio->cygaud-> in __cygnus_ssp_resume()
1119 audio_clk[aio->pll_clk_num]); in __cygnus_ssp_resume()
1120 dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n", in __cygnus_ssp_resume()
1122 return -EINVAL; in __cygnus_ssp_resume()
1165 .name = "cygnus-ssp" #num, \
1190 .name = "cygnus-spdif",
1204 .name = "cygnus-audio",
1222 int portnum = -1; in parse_ssp_child_node()
1226 dev_err(&pdev->dev, "Missing reg property\n"); in parse_ssp_child_node()
1227 return -EINVAL; in parse_ssp_child_node()
1248 dev_err(&pdev->dev, "Bad value for reg %u\n", rawval); in parse_ssp_child_node()
1249 return -EINVAL; in parse_ssp_child_node()
1252 aio = &cygaud->portinfo[portnum]; in parse_ssp_child_node()
1253 aio->cygaud = cygaud; in parse_ssp_child_node()
1254 aio->portnum = portnum; in parse_ssp_child_node()
1255 aio->port_type = port_type; in parse_ssp_child_node()
1256 aio->fsync_width = -1; in parse_ssp_child_node()
1260 aio->regs = ssp_regs[portnum]; in parse_ssp_child_node()
1262 aio->mode = CYGNUS_SSPMODE_UNKNOWN; in parse_ssp_child_node()
1266 aio->regs.bf_sourcech_cfg = BF_SRC_CFG3_OFFSET; in parse_ssp_child_node()
1267 aio->regs.bf_sourcech_ctrl = BF_SRC_CTRL3_OFFSET; in parse_ssp_child_node()
1268 aio->regs.i2s_mclk_cfg = SPDIF_MCLK_CFG_OFFSET; in parse_ssp_child_node()
1269 aio->regs.i2s_stream_cfg = SPDIF_STREAM_CFG_OFFSET; in parse_ssp_child_node()
1273 aio->mode = CYGNUS_SSPMODE_I2S; in parse_ssp_child_node()
1276 dev_err(&pdev->dev, "Bad value for port_type %d\n", port_type); in parse_ssp_child_node()
1277 return -EINVAL; in parse_ssp_child_node()
1280 dev_dbg(&pdev->dev, "%s portnum = %d\n", __func__, aio->portnum); in parse_ssp_child_node()
1281 aio->streams_on = 0; in parse_ssp_child_node()
1282 aio->cygaud->dev = &pdev->dev; in parse_ssp_child_node()
1283 aio->clk_trace.play_en = false; in parse_ssp_child_node()
1284 aio->clk_trace.cap_en = false; in parse_ssp_child_node()
1296 for (i = 0; i < ARRAY_SIZE(cygaud->audio_clk); i++) { in audio_clk_init()
1299 cygaud->audio_clk[i] = devm_clk_get(&pdev->dev, clk_name); in audio_clk_init()
1300 if (IS_ERR(cygaud->audio_clk[i])) in audio_clk_init()
1301 return PTR_ERR(cygaud->audio_clk[i]); in audio_clk_init()
1309 struct device *dev = &pdev->dev; in cygnus_ssp_probe()
1313 int err = -EINVAL; in cygnus_ssp_probe()
1319 return -ENOMEM; in cygnus_ssp_probe()
1324 cygaud->audio = devm_ioremap_resource(dev, res); in cygnus_ssp_probe()
1325 if (IS_ERR(cygaud->audio)) in cygnus_ssp_probe()
1326 return PTR_ERR(cygaud->audio); in cygnus_ssp_probe()
1329 cygaud->i2s_in = devm_ioremap_resource(dev, res); in cygnus_ssp_probe()
1330 if (IS_ERR(cygaud->i2s_in)) in cygnus_ssp_probe()
1331 return PTR_ERR(cygaud->i2s_in); in cygnus_ssp_probe()
1333 /* Tri-state all controlable pins until we know that we need them */ in cygnus_ssp_probe()
1335 cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE); in cygnus_ssp_probe()
1337 node_count = of_get_child_count(pdev->dev.of_node); in cygnus_ssp_probe()
1341 return -EINVAL; in cygnus_ssp_probe()
1346 for_each_available_child_of_node(pdev->dev.of_node, child_node) { in cygnus_ssp_probe()
1360 cygaud->dev = dev; in cygnus_ssp_probe()
1361 cygaud->active_ports = 0; in cygnus_ssp_probe()
1371 cygaud->irq_num = platform_get_irq(pdev, 0); in cygnus_ssp_probe()
1372 if (cygaud->irq_num <= 0) in cygnus_ssp_probe()
1373 return cygaud->irq_num; in cygnus_ssp_probe()
1392 cygnus_soc_platform_unregister(&pdev->dev); in cygnus_ssp_remove()
1398 { .compatible = "brcm,cygnus-audio" },
1407 .name = "cygnus-ssp",
1414 MODULE_ALIAS("platform:cygnus-ssp");