linux/sound/soc/fsl/fsl_spdif.c

// SPDX-License-Identifier: GPL-2.0
//
// Freescale S/PDIF ALSA SoC Digital Audio Interface (DAI) driver
//
// Copyright (C) 2013 Freescale Semiconductor, Inc.
//
// Based on stmp3xxx_spdif_dai.c
// Vladimir Barinov <[email protected]>
// Copyright 2008 SigmaTel, Inc
// Copyright 2008 Embedded Alley Solutions, Inc

#include <linux/bitrev.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/pm_runtime.h>

#include <sound/asoundef.h>
#include <sound/dmaengine_pcm.h>
#include <sound/soc.h>

#include "fsl_spdif.h"
#include "fsl_utils.h"
#include "imx-pcm.h"

#define FSL_SPDIF_TXFIFO_WML
#define FSL_SPDIF_RXFIFO_WML

#define INTR_FOR_PLAYBACK
#define INTR_FOR_CAPTURE

#define SIE_INTR_FOR(tx)

/* Index list for the values that has if (DPLL Locked) condition */
static u8 srpc_dpll_locked[] =;
#define SRPC_NODPLL_START1
#define SRPC_NODPLL_START2

#define DEFAULT_RXCLK_SRC

#define RX_SAMPLE_RATE_KCONTROL

/**
 * struct fsl_spdif_soc_data: soc specific data
 *
 * @imx: for imx platform
 * @shared_root_clock: flag of sharing a clock source with others;
 *                     so the driver shouldn't set root clock rate
 * @raw_capture_mode: if raw capture mode support
 * @cchannel_192b: if there are registers for 192bits C channel data
 * @interrupts: interrupt number
 * @tx_burst: tx maxburst size
 * @rx_burst: rx maxburst size
 * @tx_formats: tx supported data format
 */
struct fsl_spdif_soc_data {};

/*
 * SPDIF control structure
 * Defines channel status, subcode and Q sub
 */
struct spdif_mixer_control {};

/**
 * struct fsl_spdif_priv - Freescale SPDIF private data
 * @soc: SPDIF soc data
 * @fsl_spdif_control: SPDIF control data
 * @cpu_dai_drv: cpu dai driver
 * @snd_card: sound card pointer
 * @rxrate_kcontrol: kcontrol for RX Sample Rate
 * @pdev: platform device pointer
 * @regmap: regmap handler
 * @dpll_locked: dpll lock flag
 * @txrate: the best rates for playback
 * @txclk_df: STC_TXCLK_DF dividers value for playback
 * @sysclk_df: STC_SYSCLK_DF dividers value for playback
 * @txclk_src: STC_TXCLK_SRC values for playback
 * @rxclk_src: SRPC_CLKSRC_SEL values for capture
 * @txclk: tx clock sources for playback
 * @rxclk: rx clock sources for capture
 * @coreclk: core clock for register access via DMA
 * @sysclk: system clock for rx clock rate measurement
 * @spbaclk: SPBA clock (optional, depending on SoC design)
 * @dma_params_tx: DMA parameters for transmit channel
 * @dma_params_rx: DMA parameters for receive channel
 * @regcache_srpc: regcache for SRPC
 * @bypass: status of bypass input to output
 * @pll8k_clk: PLL clock for the rate of multiply of 8kHz
 * @pll11k_clk: PLL clock for the rate of multiply of 11kHz
 */
struct fsl_spdif_priv {};

static struct fsl_spdif_soc_data fsl_spdif_vf610 =;

static struct fsl_spdif_soc_data fsl_spdif_imx35 =;

static struct fsl_spdif_soc_data fsl_spdif_imx6sx =;

static struct fsl_spdif_soc_data fsl_spdif_imx8qm =;

static struct fsl_spdif_soc_data fsl_spdif_imx8mm =;

static struct fsl_spdif_soc_data fsl_spdif_imx8ulp =;

/* Check if clk is a root clock that does not share clock source with others */
static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif, int clk)
{}

/* DPLL locked and lock loss interrupt handler */
static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
{}

/* Receiver found illegal symbol interrupt handler */
static void spdif_irq_sym_error(struct fsl_spdif_priv *spdif_priv)
{}

/* U/Q Channel receive register full */
static void spdif_irq_uqrx_full(struct fsl_spdif_priv *spdif_priv, char name)
{}

/* U/Q Channel sync found */
static void spdif_irq_uq_sync(struct fsl_spdif_priv *spdif_priv)
{}

/* U/Q Channel framing error */
static void spdif_irq_uq_err(struct fsl_spdif_priv *spdif_priv)
{}

/* Get spdif interrupt status and clear the interrupt */
static u32 spdif_intr_status_clear(struct fsl_spdif_priv *spdif_priv)
{}

static irqreturn_t spdif_isr(int irq, void *devid)
{}

static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
{}

static void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
				u8 mask, u8 cstatus)
{}

static void spdif_write_channel_status(struct fsl_spdif_priv *spdif_priv)
{}

/* Set SPDIF PhaseConfig register for rx clock */
static int spdif_set_rx_clksrc(struct fsl_spdif_priv *spdif_priv,
				enum spdif_gainsel gainsel, int dpll_locked)
{}

static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, enum spdif_txrate index);

static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
				int sample_rate)
{}

static int fsl_spdif_startup(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *cpu_dai)
{}

static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
				struct snd_soc_dai *cpu_dai)
{}

static int spdif_reparent_rootclk(struct fsl_spdif_priv *spdif_priv, unsigned int sample_rate)
{}
static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct snd_soc_dai *dai)
{}

static int fsl_spdif_trigger(struct snd_pcm_substream *substream,
				int cmd, struct snd_soc_dai *dai)
{}

/*
 * FSL SPDIF IEC958 controller(mixer) functions
 *
 *	Channel status get/put control
 *	User bit value get/put control
 *	Valid bit value get control
 *	DPLL lock status get control
 *	User bit sync mode selection control
 */

static int fsl_spdif_info(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{}

static int fsl_spdif_pb_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *uvalue)
{}

static int fsl_spdif_pb_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *uvalue)
{}

/* Get channel status from SPDIF_RX_CCHAN register */
static int fsl_spdif_capture_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

/*
 * Get User bits (subcode) from chip value which readed out
 * in UChannel register.
 */
static int fsl_spdif_subcode_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

/* Q-subcode information. The byte size is SPDIF_UBITS_SIZE/8 */
static int fsl_spdif_qinfo(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{}

/* Get Q subcode from chip value which readed out in QChannel register */
static int fsl_spdif_qget(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

/* Get valid good bit from interrupt status register */
static int fsl_spdif_rx_vbit_get(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int fsl_spdif_tx_vbit_get(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int fsl_spdif_tx_vbit_put(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int fsl_spdif_rx_rcm_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static int fsl_spdif_rx_rcm_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static int fsl_spdif_bypass_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static int fsl_spdif_bypass_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

/* DPLL lock information */
static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{}

static u32 gainsel_multi[GAINSEL_MULTI_MAX] =;

/* Get RX data clock rate given the SPDIF bus_clk */
static int spdif_get_rxclk_rate(struct fsl_spdif_priv *spdif_priv,
				enum spdif_gainsel gainsel)
{}

/*
 * Get DPLL lock or not info from stable interrupt status register.
 * User application must use this control to get locked,
 * then can do next PCM operation
 */
static int fsl_spdif_rxrate_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

/*
 * User bit sync mode:
 * 1 CD User channel subcode
 * 0 Non-CD data
 */
static int fsl_spdif_usync_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{}

/*
 * User bit sync mode:
 * 1 CD User channel subcode
 * 0 Non-CD data
 */
static int fsl_spdif_usync_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

/* FSL SPDIF IEC958 controller defines */
static struct snd_kcontrol_new fsl_spdif_ctrls[] =;

static struct snd_kcontrol_new fsl_spdif_ctrls_rcm[] =;

static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
{}

static const struct snd_soc_dai_ops fsl_spdif_dai_ops =;

static struct snd_soc_dai_driver fsl_spdif_dai =;

static const struct snd_soc_component_driver fsl_spdif_component =;

/* FSL SPDIF REGMAP */
static const struct reg_default fsl_spdif_reg_defaults[] =;

static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
{}

static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg)
{}

static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
{}

static const struct regmap_config fsl_spdif_regmap_config =;

static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
				struct clk *clk, u64 savesub,
				enum spdif_txrate index, bool round)
{}

static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
				enum spdif_txrate index)
{}

static int fsl_spdif_probe(struct platform_device *pdev)
{}

static void fsl_spdif_remove(struct platform_device *pdev)
{}

#ifdef CONFIG_PM
static int fsl_spdif_runtime_suspend(struct device *dev)
{}

static int fsl_spdif_runtime_resume(struct device *dev)
{}
#endif /* CONFIG_PM */

static const struct dev_pm_ops fsl_spdif_pm =;

static const struct of_device_id fsl_spdif_dt_ids[] =;
MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);

static struct platform_driver fsl_spdif_driver =;

module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS();