linux/sound/soc/codecs/wm8580.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * wm8580.c  --  WM8580 and WM8581 ALSA Soc Audio driver
 *
 * Copyright 2008-12 Wolfson Microelectronics PLC.
 *
 * Notes:
 *  The WM8580 is a multichannel codec with S/PDIF support, featuring six
 *  DAC channels and two ADC channels.
 *
 *  The WM8581 is a multichannel codec with S/PDIF support, featuring eight
 *  DAC channels and two ADC channels.
 *
 *  Currently only the primary audio interface is supported - S/PDIF and
 *  the secondary audio interfaces are not.
 */

#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <sound/initval.h>
#include <asm/div64.h>

#include "wm8580.h"

/* WM8580 register space */
#define WM8580_PLLA1
#define WM8580_PLLA2
#define WM8580_PLLA3
#define WM8580_PLLA4
#define WM8580_PLLB1
#define WM8580_PLLB2
#define WM8580_PLLB3
#define WM8580_PLLB4
#define WM8580_CLKSEL
#define WM8580_PAIF1
#define WM8580_PAIF2
#define WM8580_SAIF1
#define WM8580_PAIF3
#define WM8580_PAIF4
#define WM8580_SAIF2
#define WM8580_DAC_CONTROL1
#define WM8580_DAC_CONTROL2
#define WM8580_DAC_CONTROL3
#define WM8580_DAC_CONTROL4
#define WM8580_DAC_CONTROL5
#define WM8580_DIGITAL_ATTENUATION_DACL1
#define WM8580_DIGITAL_ATTENUATION_DACR1
#define WM8580_DIGITAL_ATTENUATION_DACL2
#define WM8580_DIGITAL_ATTENUATION_DACR2
#define WM8580_DIGITAL_ATTENUATION_DACL3
#define WM8580_DIGITAL_ATTENUATION_DACR3
#define WM8581_DIGITAL_ATTENUATION_DACL4
#define WM8581_DIGITAL_ATTENUATION_DACR4
#define WM8580_MASTER_DIGITAL_ATTENUATION
#define WM8580_ADC_CONTROL1
#define WM8580_SPDTXCHAN0
#define WM8580_SPDTXCHAN1
#define WM8580_SPDTXCHAN2
#define WM8580_SPDTXCHAN3
#define WM8580_SPDTXCHAN4
#define WM8580_SPDTXCHAN5
#define WM8580_SPDMODE
#define WM8580_INTMASK
#define WM8580_GPO1
#define WM8580_GPO2
#define WM8580_GPO3
#define WM8580_GPO4
#define WM8580_GPO5
#define WM8580_INTSTAT
#define WM8580_SPDRXCHAN1
#define WM8580_SPDRXCHAN2
#define WM8580_SPDRXCHAN3
#define WM8580_SPDRXCHAN4
#define WM8580_SPDRXCHAN5
#define WM8580_SPDSTAT
#define WM8580_PWRDN1
#define WM8580_PWRDN2
#define WM8580_READBACK
#define WM8580_RESET

#define WM8580_MAX_REGISTER

#define WM8580_DACOSR

/* PLLB4 (register 7h) */
#define WM8580_PLLB4_MCLKOUTSRC_MASK
#define WM8580_PLLB4_MCLKOUTSRC_PLLA
#define WM8580_PLLB4_MCLKOUTSRC_PLLB
#define WM8580_PLLB4_MCLKOUTSRC_OSC

#define WM8580_PLLB4_CLKOUTSRC_MASK
#define WM8580_PLLB4_CLKOUTSRC_PLLACLK
#define WM8580_PLLB4_CLKOUTSRC_PLLBCLK
#define WM8580_PLLB4_CLKOUTSRC_OSCCLK

/* CLKSEL (register 8h) */
#define WM8580_CLKSEL_DAC_CLKSEL_MASK
#define WM8580_CLKSEL_DAC_CLKSEL_PLLA
#define WM8580_CLKSEL_DAC_CLKSEL_PLLB

/* AIF control 1 (registers 9h-bh) */
#define WM8580_AIF_RATE_MASK
#define WM8580_AIF_BCLKSEL_MASK

#define WM8580_AIF_MS

#define WM8580_AIF_CLKSRC_MASK
#define WM8580_AIF_CLKSRC_PLLA
#define WM8580_AIF_CLKSRC_PLLB
#define WM8580_AIF_CLKSRC_MCLK

/* AIF control 2 (registers ch-eh) */
#define WM8580_AIF_FMT_MASK
#define WM8580_AIF_FMT_RIGHTJ
#define WM8580_AIF_FMT_LEFTJ
#define WM8580_AIF_FMT_I2S
#define WM8580_AIF_FMT_DSP

#define WM8580_AIF_LENGTH_MASK
#define WM8580_AIF_LENGTH_16
#define WM8580_AIF_LENGTH_20
#define WM8580_AIF_LENGTH_24
#define WM8580_AIF_LENGTH_32

#define WM8580_AIF_LRP
#define WM8580_AIF_BCP

/* Powerdown Register 1 (register 32h) */
#define WM8580_PWRDN1_PWDN
#define WM8580_PWRDN1_ALLDACPD

/* Powerdown Register 2 (register 33h) */
#define WM8580_PWRDN2_OSSCPD
#define WM8580_PWRDN2_PLLAPD
#define WM8580_PWRDN2_PLLBPD
#define WM8580_PWRDN2_SPDIFPD
#define WM8580_PWRDN2_SPDIFTXD
#define WM8580_PWRDN2_SPDIFRXD

#define WM8580_DAC_CONTROL5_MUTEALL

/*
 * wm8580 register cache
 * We can't read the WM8580 register space when we
 * are using 2 wire for device control, so we cache them instead.
 */
static const struct reg_default wm8580_reg_defaults[] =;

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

struct pll_state {};

#define WM8580_NUM_SUPPLIES
static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] =;

struct wm8580_driver_data {};

/* codec private data */
struct wm8580_priv {};

static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);

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

static const struct snd_kcontrol_new wm8580_snd_controls[] =;

static const struct snd_kcontrol_new wm8581_snd_controls[] =;

static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] =;

static const struct snd_soc_dapm_widget wm8581_dapm_widgets[] =;

static const struct snd_soc_dapm_route wm8580_dapm_routes[] =;

static const struct snd_soc_dapm_route wm8581_dapm_routes[] =;

/* PLL divisors */
struct _pll_div {};

/* The size in bits of the pll divide */
#define FIXED_PLL_SIZE

/* PLL rate to output rate divisions */
static struct {} post_table[] =;

static int pll_factors(struct _pll_div *pll_div, unsigned int target,
		       unsigned int source)
{}

static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
		int source, unsigned int freq_in, unsigned int freq_out)
{}

static const int wm8580_sysclk_ratios[] =;

/*
 * Set PCM DAI bit size and sample rate.
 */
static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *params,
				 struct snd_soc_dai *dai)
{}

static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
				      unsigned int fmt)
{}

static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
				 int div_id, int div)
{}

static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
			     unsigned int freq, int dir)
{}

static int wm8580_mute(struct snd_soc_dai *codec_dai, int mute, int direction)
{}

static int wm8580_set_bias_level(struct snd_soc_component *component,
	enum snd_soc_bias_level level)
{}

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

#define WM8580_FORMATS

static const struct snd_soc_dai_ops wm8580_dai_ops_playback =;

static const struct snd_soc_dai_ops wm8580_dai_ops_capture =;

static struct snd_soc_dai_driver wm8580_dai[] =;

static int wm8580_probe(struct snd_soc_component *component)
{}

/* power down chip */
static void wm8580_remove(struct snd_soc_component *component)
{}

static const struct snd_soc_component_driver soc_component_dev_wm8580 =;

static const struct regmap_config wm8580_regmap =;

static const struct wm8580_driver_data wm8580_data =;

static const struct wm8580_driver_data wm8581_data =;

static int wm8580_i2c_probe(struct i2c_client *i2c)
{}

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

static const struct i2c_device_id wm8580_i2c_id[] =;
MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);

static struct i2c_driver wm8580_i2c_driver =;

module_i2c_driver();

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