162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci#ifndef __SOUND_WM8776_H 362306a36Sopenharmony_ci#define __SOUND_WM8776_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * ALSA driver for ICEnsemble VT17xx 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Lowlevel functions for WM8776 codec 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org> 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define WM8776_REG_HPLVOL 0x00 1462306a36Sopenharmony_ci#define WM8776_REG_HPRVOL 0x01 1562306a36Sopenharmony_ci#define WM8776_REG_HPMASTER 0x02 1662306a36Sopenharmony_ci#define WM8776_HPVOL_MASK 0x17f /* incl. update bit */ 1762306a36Sopenharmony_ci#define WM8776_VOL_HPZCEN (1 << 7) /* zero cross detect */ 1862306a36Sopenharmony_ci#define WM8776_VOL_UPDATE (1 << 8) /* update volume */ 1962306a36Sopenharmony_ci#define WM8776_REG_DACLVOL 0x03 2062306a36Sopenharmony_ci#define WM8776_REG_DACRVOL 0x04 2162306a36Sopenharmony_ci#define WM8776_REG_DACMASTER 0x05 2262306a36Sopenharmony_ci#define WM8776_DACVOL_MASK 0x1ff /* incl. update bit */ 2362306a36Sopenharmony_ci#define WM8776_REG_PHASESWAP 0x06 2462306a36Sopenharmony_ci#define WM8776_PHASE_INVERTL (1 << 0) 2562306a36Sopenharmony_ci#define WM8776_PHASE_INVERTR (1 << 1) 2662306a36Sopenharmony_ci#define WM8776_REG_DACCTRL1 0x07 2762306a36Sopenharmony_ci#define WM8776_DAC_DZCEN (1 << 0) 2862306a36Sopenharmony_ci#define WM8776_DAC_ATC (1 << 1) 2962306a36Sopenharmony_ci#define WM8776_DAC_IZD (1 << 2) 3062306a36Sopenharmony_ci#define WM8776_DAC_TOD (1 << 3) 3162306a36Sopenharmony_ci#define WM8776_DAC_PL_MASK 0xf0 3262306a36Sopenharmony_ci#define WM8776_DAC_PL_LL (1 << 4) /* L chan: L signal */ 3362306a36Sopenharmony_ci#define WM8776_DAC_PL_LR (2 << 4) /* L chan: R signal */ 3462306a36Sopenharmony_ci#define WM8776_DAC_PL_LB (3 << 4) /* L chan: both */ 3562306a36Sopenharmony_ci#define WM8776_DAC_PL_RL (1 << 6) /* R chan: L signal */ 3662306a36Sopenharmony_ci#define WM8776_DAC_PL_RR (2 << 6) /* R chan: R signal */ 3762306a36Sopenharmony_ci#define WM8776_DAC_PL_RB (3 << 6) /* R chan: both */ 3862306a36Sopenharmony_ci#define WM8776_REG_DACMUTE 0x08 3962306a36Sopenharmony_ci#define WM8776_DACMUTE (1 << 0) 4062306a36Sopenharmony_ci#define WM8776_REG_DACCTRL2 0x09 4162306a36Sopenharmony_ci#define WM8776_DAC2_DEEMPH (1 << 0) 4262306a36Sopenharmony_ci#define WM8776_DAC2_ZFLAG_DISABLE (0 << 1) 4362306a36Sopenharmony_ci#define WM8776_DAC2_ZFLAG_OWN (1 << 1) 4462306a36Sopenharmony_ci#define WM8776_DAC2_ZFLAG_BOTH (2 << 1) 4562306a36Sopenharmony_ci#define WM8776_DAC2_ZFLAG_EITHER (3 << 1) 4662306a36Sopenharmony_ci#define WM8776_REG_DACIFCTRL 0x0a 4762306a36Sopenharmony_ci#define WM8776_FMT_RIGHTJ (0 << 0) 4862306a36Sopenharmony_ci#define WM8776_FMT_LEFTJ (1 << 0) 4962306a36Sopenharmony_ci#define WM8776_FMT_I2S (2 << 0) 5062306a36Sopenharmony_ci#define WM8776_FMT_DSP (3 << 0) 5162306a36Sopenharmony_ci#define WM8776_FMT_DSP_LATE (1 << 2) /* in DSP mode */ 5262306a36Sopenharmony_ci#define WM8776_FMT_LRC_INVERTED (1 << 2) /* in other modes */ 5362306a36Sopenharmony_ci#define WM8776_FMT_BCLK_INVERTED (1 << 3) 5462306a36Sopenharmony_ci#define WM8776_FMT_16BIT (0 << 4) 5562306a36Sopenharmony_ci#define WM8776_FMT_20BIT (1 << 4) 5662306a36Sopenharmony_ci#define WM8776_FMT_24BIT (2 << 4) 5762306a36Sopenharmony_ci#define WM8776_FMT_32BIT (3 << 4) 5862306a36Sopenharmony_ci#define WM8776_REG_ADCIFCTRL 0x0b 5962306a36Sopenharmony_ci#define WM8776_FMT_ADCMCLK_INVERTED (1 << 6) 6062306a36Sopenharmony_ci#define WM8776_FMT_ADCHPD (1 << 8) 6162306a36Sopenharmony_ci#define WM8776_REG_MSTRCTRL 0x0c 6262306a36Sopenharmony_ci#define WM8776_IF_ADC256FS (2 << 0) 6362306a36Sopenharmony_ci#define WM8776_IF_ADC384FS (3 << 0) 6462306a36Sopenharmony_ci#define WM8776_IF_ADC512FS (4 << 0) 6562306a36Sopenharmony_ci#define WM8776_IF_ADC768FS (5 << 0) 6662306a36Sopenharmony_ci#define WM8776_IF_OVERSAMP64 (1 << 3) 6762306a36Sopenharmony_ci#define WM8776_IF_DAC128FS (0 << 4) 6862306a36Sopenharmony_ci#define WM8776_IF_DAC192FS (1 << 4) 6962306a36Sopenharmony_ci#define WM8776_IF_DAC256FS (2 << 4) 7062306a36Sopenharmony_ci#define WM8776_IF_DAC384FS (3 << 4) 7162306a36Sopenharmony_ci#define WM8776_IF_DAC512FS (4 << 4) 7262306a36Sopenharmony_ci#define WM8776_IF_DAC768FS (5 << 4) 7362306a36Sopenharmony_ci#define WM8776_IF_DAC_MASTER (1 << 7) 7462306a36Sopenharmony_ci#define WM8776_IF_ADC_MASTER (1 << 8) 7562306a36Sopenharmony_ci#define WM8776_REG_PWRDOWN 0x0d 7662306a36Sopenharmony_ci#define WM8776_PWR_PDWN (1 << 0) 7762306a36Sopenharmony_ci#define WM8776_PWR_ADCPD (1 << 1) 7862306a36Sopenharmony_ci#define WM8776_PWR_DACPD (1 << 2) 7962306a36Sopenharmony_ci#define WM8776_PWR_HPPD (1 << 3) 8062306a36Sopenharmony_ci#define WM8776_PWR_AINPD (1 << 6) 8162306a36Sopenharmony_ci#define WM8776_REG_ADCLVOL 0x0e 8262306a36Sopenharmony_ci#define WM8776_REG_ADCRVOL 0x0f 8362306a36Sopenharmony_ci#define WM8776_ADC_GAIN_MASK 0xff 8462306a36Sopenharmony_ci#define WM8776_ADC_ZCEN (1 << 8) 8562306a36Sopenharmony_ci#define WM8776_REG_ALCCTRL1 0x10 8662306a36Sopenharmony_ci#define WM8776_ALC1_LCT_MASK 0x0f /* 0=-16dB, 1=-15dB..15=-1dB */ 8762306a36Sopenharmony_ci#define WM8776_ALC1_MAXGAIN_MASK 0x70 /* 0,1=0dB, 2=+4dB...7=+24dB */ 8862306a36Sopenharmony_ci#define WM8776_ALC1_LCSEL_MASK 0x180 8962306a36Sopenharmony_ci#define WM8776_ALC1_LCSEL_LIMITER (0 << 7) 9062306a36Sopenharmony_ci#define WM8776_ALC1_LCSEL_ALCR (1 << 7) 9162306a36Sopenharmony_ci#define WM8776_ALC1_LCSEL_ALCL (2 << 7) 9262306a36Sopenharmony_ci#define WM8776_ALC1_LCSEL_ALCSTEREO (3 << 7) 9362306a36Sopenharmony_ci#define WM8776_REG_ALCCTRL2 0x11 9462306a36Sopenharmony_ci#define WM8776_ALC2_HOLD_MASK 0x0f /*0=0ms, 1=2.67ms, 2=5.33ms.. */ 9562306a36Sopenharmony_ci#define WM8776_ALC2_ZCEN (1 << 7) 9662306a36Sopenharmony_ci#define WM8776_ALC2_LCEN (1 << 8) 9762306a36Sopenharmony_ci#define WM8776_REG_ALCCTRL3 0x12 9862306a36Sopenharmony_ci#define WM8776_ALC3_ATK_MASK 0x0f 9962306a36Sopenharmony_ci#define WM8776_ALC3_DCY_MASK 0xf0 10062306a36Sopenharmony_ci#define WM8776_ALC3_FDECAY (1 << 8) 10162306a36Sopenharmony_ci#define WM8776_REG_NOISEGATE 0x13 10262306a36Sopenharmony_ci#define WM8776_NGAT_ENABLE (1 << 0) 10362306a36Sopenharmony_ci#define WM8776_NGAT_THR_MASK 0x1c /*0=-78dB, 1=-72dB...7=-36dB */ 10462306a36Sopenharmony_ci#define WM8776_REG_LIMITER 0x14 10562306a36Sopenharmony_ci#define WM8776_LIM_MAXATTEN_MASK 0x0f 10662306a36Sopenharmony_ci#define WM8776_LIM_TRANWIN_MASK 0x70 /*0=0us, 1=62.5us, 2=125us.. */ 10762306a36Sopenharmony_ci#define WM8776_REG_ADCMUX 0x15 10862306a36Sopenharmony_ci#define WM8776_ADC_MUX_AIN1 (1 << 0) 10962306a36Sopenharmony_ci#define WM8776_ADC_MUX_AIN2 (1 << 1) 11062306a36Sopenharmony_ci#define WM8776_ADC_MUX_AIN3 (1 << 2) 11162306a36Sopenharmony_ci#define WM8776_ADC_MUX_AIN4 (1 << 3) 11262306a36Sopenharmony_ci#define WM8776_ADC_MUX_AIN5 (1 << 4) 11362306a36Sopenharmony_ci#define WM8776_ADC_MUTER (1 << 6) 11462306a36Sopenharmony_ci#define WM8776_ADC_MUTEL (1 << 7) 11562306a36Sopenharmony_ci#define WM8776_ADC_LRBOTH (1 << 8) 11662306a36Sopenharmony_ci#define WM8776_REG_OUTMUX 0x16 11762306a36Sopenharmony_ci#define WM8776_OUTMUX_DAC (1 << 0) 11862306a36Sopenharmony_ci#define WM8776_OUTMUX_AUX (1 << 1) 11962306a36Sopenharmony_ci#define WM8776_OUTMUX_BYPASS (1 << 2) 12062306a36Sopenharmony_ci#define WM8776_REG_RESET 0x17 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci#define WM8776_REG_COUNT 0x17 /* don't cache the RESET register */ 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistruct snd_wm8776; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistruct snd_wm8776_ops { 12762306a36Sopenharmony_ci void (*write)(struct snd_wm8776 *wm, u8 addr, u8 data); 12862306a36Sopenharmony_ci}; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cienum snd_wm8776_ctl_id { 13162306a36Sopenharmony_ci WM8776_CTL_DAC_VOL, 13262306a36Sopenharmony_ci WM8776_CTL_DAC_SW, 13362306a36Sopenharmony_ci WM8776_CTL_DAC_ZC_SW, 13462306a36Sopenharmony_ci WM8776_CTL_HP_VOL, 13562306a36Sopenharmony_ci WM8776_CTL_HP_SW, 13662306a36Sopenharmony_ci WM8776_CTL_HP_ZC_SW, 13762306a36Sopenharmony_ci WM8776_CTL_AUX_SW, 13862306a36Sopenharmony_ci WM8776_CTL_BYPASS_SW, 13962306a36Sopenharmony_ci WM8776_CTL_DAC_IZD_SW, 14062306a36Sopenharmony_ci WM8776_CTL_PHASE_SW, 14162306a36Sopenharmony_ci WM8776_CTL_DEEMPH_SW, 14262306a36Sopenharmony_ci WM8776_CTL_ADC_VOL, 14362306a36Sopenharmony_ci WM8776_CTL_ADC_SW, 14462306a36Sopenharmony_ci WM8776_CTL_INPUT1_SW, 14562306a36Sopenharmony_ci WM8776_CTL_INPUT2_SW, 14662306a36Sopenharmony_ci WM8776_CTL_INPUT3_SW, 14762306a36Sopenharmony_ci WM8776_CTL_INPUT4_SW, 14862306a36Sopenharmony_ci WM8776_CTL_INPUT5_SW, 14962306a36Sopenharmony_ci WM8776_CTL_AGC_SEL, 15062306a36Sopenharmony_ci WM8776_CTL_LIM_THR, 15162306a36Sopenharmony_ci WM8776_CTL_LIM_ATK, 15262306a36Sopenharmony_ci WM8776_CTL_LIM_DCY, 15362306a36Sopenharmony_ci WM8776_CTL_LIM_TRANWIN, 15462306a36Sopenharmony_ci WM8776_CTL_LIM_MAXATTN, 15562306a36Sopenharmony_ci WM8776_CTL_ALC_TGT, 15662306a36Sopenharmony_ci WM8776_CTL_ALC_ATK, 15762306a36Sopenharmony_ci WM8776_CTL_ALC_DCY, 15862306a36Sopenharmony_ci WM8776_CTL_ALC_MAXGAIN, 15962306a36Sopenharmony_ci WM8776_CTL_ALC_MAXATTN, 16062306a36Sopenharmony_ci WM8776_CTL_ALC_HLD, 16162306a36Sopenharmony_ci WM8776_CTL_NGT_SW, 16262306a36Sopenharmony_ci WM8776_CTL_NGT_THR, 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci WM8776_CTL_COUNT, 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci#define WM8776_ENUM_MAX 16 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci#define WM8776_FLAG_STEREO (1 << 0) 17062306a36Sopenharmony_ci#define WM8776_FLAG_VOL_UPDATE (1 << 1) 17162306a36Sopenharmony_ci#define WM8776_FLAG_INVERT (1 << 2) 17262306a36Sopenharmony_ci#define WM8776_FLAG_LIM (1 << 3) 17362306a36Sopenharmony_ci#define WM8776_FLAG_ALC (1 << 4) 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cistruct snd_wm8776_ctl { 17662306a36Sopenharmony_ci const char *name; 17762306a36Sopenharmony_ci snd_ctl_elem_type_t type; 17862306a36Sopenharmony_ci const char *const enum_names[WM8776_ENUM_MAX]; 17962306a36Sopenharmony_ci const unsigned int *tlv; 18062306a36Sopenharmony_ci u16 reg1, reg2, mask1, mask2, min, max, flags; 18162306a36Sopenharmony_ci void (*set)(struct snd_wm8776 *wm, u16 ch1, u16 ch2); 18262306a36Sopenharmony_ci void (*get)(struct snd_wm8776 *wm, u16 *ch1, u16 *ch2); 18362306a36Sopenharmony_ci}; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cienum snd_wm8776_agc_mode { 18662306a36Sopenharmony_ci WM8776_AGC_OFF, 18762306a36Sopenharmony_ci WM8776_AGC_LIM, 18862306a36Sopenharmony_ci WM8776_AGC_ALC_R, 18962306a36Sopenharmony_ci WM8776_AGC_ALC_L, 19062306a36Sopenharmony_ci WM8776_AGC_ALC_STEREO 19162306a36Sopenharmony_ci}; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistruct snd_wm8776 { 19462306a36Sopenharmony_ci struct snd_card *card; 19562306a36Sopenharmony_ci struct snd_wm8776_ctl ctl[WM8776_CTL_COUNT]; 19662306a36Sopenharmony_ci enum snd_wm8776_agc_mode agc_mode; 19762306a36Sopenharmony_ci struct snd_wm8776_ops ops; 19862306a36Sopenharmony_ci u16 regs[WM8776_REG_COUNT]; /* 9-bit registers */ 19962306a36Sopenharmony_ci}; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_civoid snd_wm8776_init(struct snd_wm8776 *wm); 20462306a36Sopenharmony_civoid snd_wm8776_resume(struct snd_wm8776 *wm); 20562306a36Sopenharmony_civoid snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power); 20662306a36Sopenharmony_civoid snd_wm8776_volume_restore(struct snd_wm8776 *wm); 20762306a36Sopenharmony_ciint snd_wm8776_build_controls(struct snd_wm8776 *wm); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#endif /* __SOUND_WM8776_H */ 210