[ALSA] oxygen: add more symbols
Add symbol definitions for the various codecs and GPIO pins. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
44fb7aae82
commit
878ac3ee76
|
@ -0,0 +1,63 @@
|
|||
#ifndef CM9780_H_INCLUDED
|
||||
#define CM9780_H_INCLUDED
|
||||
|
||||
#define CM9780_JACK 0x62
|
||||
#define CM9780_MIXER 0x64
|
||||
#define CM9780_GPIO_SETUP 0x70
|
||||
#define CM9780_GPIO_STATUS 0x72
|
||||
|
||||
/* jack control */
|
||||
#define CM9780_RSOE 0x0001
|
||||
#define CM9780_CBOE 0x0002
|
||||
#define CM9780_SSOE 0x0004
|
||||
#define CM9780_FROE 0x0008
|
||||
#define CM9780_HP2FMICOE 0x0010
|
||||
#define CM9780_CB2MICOE 0x0020
|
||||
#define CM9780_FMIC2LI 0x0040
|
||||
#define CM9780_FMIC2MIC 0x0080
|
||||
#define CM9780_HP2LI 0x0100
|
||||
#define CM9780_HP2MIC 0x0200
|
||||
#define CM9780_MIC2LI 0x0400
|
||||
#define CM9780_MIC2MIC 0x0800
|
||||
#define CM9780_LI2LI 0x1000
|
||||
#define CM9780_LI2MIC 0x2000
|
||||
#define CM9780_LO2LI 0x4000
|
||||
#define CM9780_LO2MIC 0x8000
|
||||
|
||||
/* mixer control */
|
||||
#define CM9780_BSTSEL 0x0001
|
||||
#define CM9780_STRO_MIC 0x0002
|
||||
#define CM9780_SPDI_FREX 0x0004
|
||||
#define CM9780_SPDI_SSEX 0x0008
|
||||
#define CM9780_SPDI_CBEX 0x0010
|
||||
#define CM9780_SPDI_RSEX 0x0020
|
||||
#define CM9780_MIX2FR 0x0040
|
||||
#define CM9780_MIX2SS 0x0080
|
||||
#define CM9780_MIX2CB 0x0100
|
||||
#define CM9780_MIX2RS 0x0200
|
||||
#define CM9780_MIX2FR_EX 0x0400
|
||||
#define CM9780_MIX2SS_EX 0x0800
|
||||
#define CM9780_MIX2CB_EX 0x1000
|
||||
#define CM9780_MIX2RS_EX 0x2000
|
||||
#define CM9780_P47_IO 0x4000
|
||||
#define CM9780_PCBSW 0x8000
|
||||
|
||||
/* GPIO setup */
|
||||
#define CM9780_GPI0EN 0x0001
|
||||
#define CM9780_GPI1EN 0x0002
|
||||
#define CM9780_SENSE_P 0x0004
|
||||
#define CM9780_LOCK_P 0x0008
|
||||
#define CM9780_GPIO0P 0x0010
|
||||
#define CM9780_GPIO1P 0x0020
|
||||
#define CM9780_GPIO0IO 0x0100
|
||||
#define CM9780_GPIO1IO 0x0200
|
||||
|
||||
/* GPIO status */
|
||||
#define CM9780_GPO0 0x0001
|
||||
#define CM9780_GPO1 0x0002
|
||||
#define CM9780_GPIO0S 0x0010
|
||||
#define CM9780_GPIO1S 0x0020
|
||||
#define CM9780_GPII0S 0x0100
|
||||
#define CM9780_GPII1S 0x0200
|
||||
|
||||
#endif
|
|
@ -70,30 +70,92 @@ static struct pci_device_id oxygen_ids[] __devinitdata = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(pci, oxygen_ids);
|
||||
|
||||
|
||||
#define GPIO_AK5385_DFS_MASK 0x0003
|
||||
#define GPIO_AK5385_DFS_NORMAL 0x0000
|
||||
#define GPIO_AK5385_DFS_DOUBLE 0x0001
|
||||
#define GPIO_AK5385_DFS_QUAD 0x0002
|
||||
|
||||
#define AK4396_WRITE 0x2000
|
||||
|
||||
/* register 0 */
|
||||
#define AK4396_CONTROL_1 0
|
||||
#define AK4396_CONTROL_2 1
|
||||
#define AK4396_CONTROL_3 2
|
||||
#define AK4396_LCH_ATT 3
|
||||
#define AK4396_RCH_ATT 4
|
||||
|
||||
/* control 1 */
|
||||
#define AK4396_RSTN 0x01
|
||||
#define AK4396_DIF_MASK 0x0e
|
||||
#define AK4396_DIF_16_LSB 0x00
|
||||
#define AK4396_DIF_20_LSB 0x02
|
||||
#define AK4396_DIF_24_MSB 0x04
|
||||
/* register 1 */
|
||||
#define AK4396_DIF_24_I2S 0x06
|
||||
#define AK4396_DIF_24_LSB 0x08
|
||||
#define AK4396_ACKS 0x80
|
||||
/* control 2 */
|
||||
#define AK4396_SMUTE 0x01
|
||||
#define AK4396_DEM_MASK 0x06
|
||||
#define AK4396_DEM_441 0x00
|
||||
#define AK4396_DEM_OFF 0x02
|
||||
#define AK4396_DEM_48 0x04
|
||||
#define AK4396_DEM_32 0x06
|
||||
#define AK4396_DFS_MASK 0x18
|
||||
#define AK4396_DFS_NORMAL 0x00
|
||||
#define AK4396_DFS_DOUBLE 0x08
|
||||
#define AK4396_DFS_QUAD 0x10
|
||||
#define AK4396_SLOW 0x20
|
||||
#define AK4396_DZFM 0x40
|
||||
#define AK4396_DZFE 0x80
|
||||
/* control 3 */
|
||||
#define AK4396_DZFB 0x04
|
||||
#define AK4396_DCKB 0x10
|
||||
#define AK4396_DCKS 0x20
|
||||
#define AK4396_DSDM 0x40
|
||||
#define AK4396_D_P_MASK 0x80
|
||||
#define AK4396_PCM 0x00
|
||||
#define AK4396_DSD 0x80
|
||||
|
||||
/* register 0 */
|
||||
#define WM8785_R0 0
|
||||
#define WM8785_R1 1
|
||||
#define WM8785_R2 2
|
||||
#define WM8785_R7 7
|
||||
|
||||
/* R0 */
|
||||
#define WM8785_MCR_MASK 0x007
|
||||
#define WM8785_MCR_SLAVE 0x000
|
||||
#define WM8785_MCR_MASTER_128 0x001
|
||||
#define WM8785_MCR_MASTER_192 0x002
|
||||
#define WM8785_MCR_MASTER_256 0x003
|
||||
#define WM8785_MCR_MASTER_384 0x004
|
||||
#define WM8785_MCR_MASTER_512 0x005
|
||||
#define WM8785_MCR_MASTER_768 0x006
|
||||
#define WM8785_OSR_MASK 0x018
|
||||
#define WM8785_OSR_SINGLE 0x000
|
||||
#define WM8785_OSR_DOUBLE 0x008
|
||||
#define WM8785_OSR_QUAD 0x010
|
||||
#define WM8785_FORMAT_MASK 0x060
|
||||
#define WM8785_FORMAT_RJUST 0x000
|
||||
#define WM8785_FORMAT_LJUST 0x020
|
||||
#define WM8785_FORMAT_I2S 0x040
|
||||
/* register 1 */
|
||||
#define WM8785_FORMAT_DSP 0x060
|
||||
/* R1 */
|
||||
#define WM8785_WL_MASK 0x003
|
||||
#define WM8785_WL_16 0x000
|
||||
#define WM8785_WL_20 0x001
|
||||
#define WM8785_WL_24 0x002
|
||||
#define WM8785_WL_32 0x003
|
||||
#define WM8785_LRP 0x004
|
||||
#define WM8785_BCLKINV 0x008
|
||||
#define WM8785_LRSWAP 0x010
|
||||
#define WM8785_DEVNO_MASK 0x0e0
|
||||
/* R2 */
|
||||
#define WM8785_HPFR 0x001
|
||||
#define WM8785_HPFL 0x002
|
||||
#define WM8785_SDODIS 0x004
|
||||
#define WM8785_PWRDNR 0x008
|
||||
#define WM8785_PWRDNL 0x010
|
||||
#define WM8785_TDM_MASK 0x1c0
|
||||
|
||||
static void ak4396_write(struct oxygen *chip, unsigned int codec,
|
||||
u8 reg, u8 value)
|
||||
|
@ -124,29 +186,33 @@ static void ak4396_init(struct oxygen *chip)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
chip->ak4396_reg1 = AK4396_DEM_OFF | AK4396_DFS_NORMAL;
|
||||
chip->ak4396_ctl2 = AK4396_DEM_OFF | AK4396_DFS_NORMAL;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
ak4396_write(chip, i, 0, AK4396_DIF_24_MSB | AK4396_RSTN);
|
||||
ak4396_write(chip, i, 1, chip->ak4396_reg1);
|
||||
ak4396_write(chip, i, 2, 0);
|
||||
ak4396_write(chip, i, 3, 0xff);
|
||||
ak4396_write(chip, i, 4, 0xff);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_CONTROL_2, chip->ak4396_ctl2);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_CONTROL_3, AK4396_PCM);
|
||||
ak4396_write(chip, i, AK4396_LCH_ATT, 0xff);
|
||||
ak4396_write(chip, i, AK4396_RCH_ATT, 0xff);
|
||||
}
|
||||
snd_component_add(chip->card, "AK4396");
|
||||
}
|
||||
|
||||
static void ak5385_init(struct oxygen *chip)
|
||||
{
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x0003);
|
||||
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 0x0003);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_AK5385_DFS_MASK);
|
||||
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_AK5385_DFS_MASK);
|
||||
snd_component_add(chip->card, "AK5385");
|
||||
}
|
||||
|
||||
static void wm8785_init(struct oxygen *chip)
|
||||
{
|
||||
wm8785_write(chip, 7, 0);
|
||||
wm8785_write(chip, 0, WM8785_FORMAT_LJUST | WM8785_OSR_SINGLE);
|
||||
wm8785_write(chip, 1, WM8785_WL_24);
|
||||
wm8785_write(chip, WM8785_R7, 0);
|
||||
wm8785_write(chip, WM8785_R0, WM8785_MCR_SLAVE |
|
||||
WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST);
|
||||
wm8785_write(chip, WM8785_R1, WM8785_WL_24);
|
||||
snd_component_add(chip->card, "WM8785");
|
||||
}
|
||||
|
||||
|
@ -184,18 +250,21 @@ static void set_ak4396_params(struct oxygen *chip,
|
|||
unsigned int i;
|
||||
u8 value;
|
||||
|
||||
value = chip->ak4396_reg1 & ~AK4396_DFS_MASK;
|
||||
value = chip->ak4396_ctl2 & ~AK4396_DFS_MASK;
|
||||
if (params_rate(params) <= 54000)
|
||||
value |= AK4396_DFS_NORMAL;
|
||||
else if (params_rate(params) < 120000)
|
||||
value |= AK4396_DFS_DOUBLE;
|
||||
else
|
||||
value |= AK4396_DFS_QUAD;
|
||||
chip->ak4396_reg1 = value;
|
||||
chip->ak4396_ctl2 = value;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
ak4396_write(chip, i, 0, AK4396_DIF_24_MSB);
|
||||
ak4396_write(chip, i, 1, value);
|
||||
ak4396_write(chip, i, 0, AK4396_DIF_24_MSB | AK4396_RSTN);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_CONTROL_1, AK4396_DIF_24_MSB);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_CONTROL_2, value);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,8 +273,10 @@ static void update_ak4396_volume(struct oxygen *chip)
|
|||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
ak4396_write(chip, i, 3, chip->dac_volume[i * 2]);
|
||||
ak4396_write(chip, i, 4, chip->dac_volume[i * 2 + 1]);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_LCH_ATT, chip->dac_volume[i * 2]);
|
||||
ak4396_write(chip, i,
|
||||
AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,11 +285,11 @@ static void update_ak4396_mute(struct oxygen *chip)
|
|||
unsigned int i;
|
||||
u8 value;
|
||||
|
||||
value = chip->ak4396_reg1 & ~AK4396_SMUTE;
|
||||
value = chip->ak4396_ctl2 & ~AK4396_SMUTE;
|
||||
if (chip->dac_mute)
|
||||
value |= AK4396_SMUTE;
|
||||
for (i = 0; i < 4; ++i)
|
||||
ak4396_write(chip, i, 1, value);
|
||||
ak4396_write(chip, i, AK4396_CONTROL_2, value);
|
||||
}
|
||||
|
||||
static void set_wm8785_params(struct oxygen *chip,
|
||||
|
@ -226,22 +297,22 @@ static void set_wm8785_params(struct oxygen *chip,
|
|||
{
|
||||
unsigned int value;
|
||||
|
||||
wm8785_write(chip, 7, 0);
|
||||
wm8785_write(chip, WM8785_R7, 0);
|
||||
|
||||
value = WM8785_FORMAT_LJUST;
|
||||
value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST;
|
||||
if (params_rate(params) == 96000)
|
||||
value |= WM8785_OSR_DOUBLE;
|
||||
else if (params_rate(params) == 192000)
|
||||
value |= WM8785_OSR_QUAD;
|
||||
else
|
||||
value |= WM8785_OSR_SINGLE;
|
||||
wm8785_write(chip, 0, value);
|
||||
wm8785_write(chip, WM8785_R0, value);
|
||||
|
||||
if (snd_pcm_format_width(params_format(params)) <= 16)
|
||||
value = WM8785_WL_16;
|
||||
else
|
||||
value = WM8785_WL_24;
|
||||
wm8785_write(chip, 1, value);
|
||||
wm8785_write(chip, WM8785_R1, value);
|
||||
}
|
||||
|
||||
static void set_ak5385_params(struct oxygen *chip,
|
||||
|
@ -250,12 +321,13 @@ static void set_ak5385_params(struct oxygen *chip,
|
|||
unsigned int value;
|
||||
|
||||
if (params_rate(params) <= 54000)
|
||||
value = 0;
|
||||
value = GPIO_AK5385_DFS_NORMAL;
|
||||
else if (params_rate(params) <= 108000)
|
||||
value = 1;
|
||||
value = GPIO_AK5385_DFS_DOUBLE;
|
||||
else
|
||||
value = 2;
|
||||
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, value, 0x0003);
|
||||
value = GPIO_AK5385_DFS_QUAD;
|
||||
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
|
||||
value, GPIO_AK5385_DFS_MASK);
|
||||
}
|
||||
|
||||
static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
|
||||
|
|
|
@ -56,7 +56,7 @@ struct oxygen {
|
|||
u8 pcm_running;
|
||||
u8 dac_routing;
|
||||
u8 spdif_playback_enable;
|
||||
u8 ak4396_reg1;
|
||||
u8 ak4396_ctl2;
|
||||
u8 revision;
|
||||
u8 has_ac97_0;
|
||||
u8 has_ac97_1;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <sound/mpu401.h>
|
||||
#include <sound/pcm.h>
|
||||
#include "oxygen.h"
|
||||
#include "cm9780.h"
|
||||
|
||||
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
|
||||
MODULE_DESCRIPTION("C-Media CMI8788 helper library");
|
||||
|
@ -262,9 +263,15 @@ static void __devinit oxygen_init(struct oxygen *chip)
|
|||
OXYGEN_AC97_CODEC0_LINER);
|
||||
oxygen_write_ac97(chip, 0, AC97_RESET, 0);
|
||||
msleep(1);
|
||||
oxygen_ac97_set_bits(chip, 0, 0x70, 0x0300);
|
||||
oxygen_ac97_set_bits(chip, 0, 0x64, 0x8043);
|
||||
oxygen_ac97_set_bits(chip, 0, 0x62, 0x180f);
|
||||
oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_SETUP,
|
||||
CM9780_GPIO0IO | CM9780_GPIO1IO);
|
||||
oxygen_ac97_set_bits(chip, 0, CM9780_MIXER,
|
||||
CM9780_BSTSEL | CM9780_STRO_MIC |
|
||||
CM9780_MIX2FR | CM9780_PCBSW);
|
||||
oxygen_ac97_set_bits(chip, 0, CM9780_JACK,
|
||||
CM9780_RSOE | CM9780_CBOE |
|
||||
CM9780_SSOE | CM9780_FROE |
|
||||
CM9780_MIC2MIC | CM9780_LI2LI);
|
||||
oxygen_write_ac97(chip, 0, AC97_MASTER, 0x0000);
|
||||
oxygen_write_ac97(chip, 0, AC97_PC_BEEP, 0x8000);
|
||||
oxygen_write_ac97(chip, 0, AC97_MIC, 0x8808);
|
||||
|
@ -275,7 +282,8 @@ static void __devinit oxygen_init(struct oxygen *chip)
|
|||
oxygen_write_ac97(chip, 0, AC97_REC_GAIN, 0x8000);
|
||||
oxygen_write_ac97(chip, 0, AC97_CENTER_LFE_MASTER, 0x8080);
|
||||
oxygen_write_ac97(chip, 0, AC97_SURROUND_MASTER, 0x8080);
|
||||
oxygen_ac97_clear_bits(chip, 0, 0x72, 0x0001);
|
||||
oxygen_ac97_clear_bits(chip, 0,
|
||||
CM9780_GPIO_STATUS, CM9780_GPO0);
|
||||
/* power down unused ADCs and DACs */
|
||||
oxygen_ac97_set_bits(chip, 0, AC97_POWERDOWN,
|
||||
AC97_PD_PR0 | AC97_PD_PR1);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <sound/control.h>
|
||||
#include <sound/tlv.h>
|
||||
#include "oxygen.h"
|
||||
#include "cm9780.h"
|
||||
|
||||
static int dac_volume_info(struct snd_kcontrol *ctl,
|
||||
struct snd_ctl_elem_info *info)
|
||||
|
@ -460,8 +461,9 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
|
|||
if (change) {
|
||||
oxygen_write_ac97(chip, 0, index, newreg);
|
||||
if (index == AC97_LINE) {
|
||||
oxygen_write_ac97_masked(chip, 0, 0x72,
|
||||
!!(newreg & 0x8000), 0x0001);
|
||||
oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
|
||||
newreg & 0x8000 ?
|
||||
CM9780_GPO0 : 0, CM9780_GPO0);
|
||||
if (!(newreg & 0x8000)) {
|
||||
ac97_mute_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH);
|
||||
ac97_mute_ctl(chip, CONTROL_CD_CAPTURE_SWITCH);
|
||||
|
@ -471,7 +473,8 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
|
|||
index == AC97_VIDEO || index == AC97_AUX) &&
|
||||
bitnr == 15 && !(newreg & 0x8000)) {
|
||||
ac97_mute_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH);
|
||||
oxygen_write_ac97_masked(chip, 0, 0x72, 0x0001, 0x0001);
|
||||
oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
|
||||
CM9780_GPO0, CM9780_GPO0);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&chip->mutex);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* CMI8788:
|
||||
*
|
||||
* SPI 0 -> 1st PCM1796 (front)
|
||||
* SPI 1 -> 2nd PCM1796 (surround)
|
||||
* SPI 2 -> 3rd PCM1796 (center/LFE)
|
||||
|
@ -25,9 +27,13 @@
|
|||
*
|
||||
* GPIO 2 -> M0 of CS5381
|
||||
* GPIO 3 -> M1 of CS5381
|
||||
* GPIO 5 <- ? (D2X only)
|
||||
* GPIO 5 <- external power present (D2X only)
|
||||
* GPIO 7 -> ALT
|
||||
* GPIO 8 -> ? (amps enable?)
|
||||
* GPIO 8 -> enable output to speakers
|
||||
*
|
||||
* CM9780:
|
||||
*
|
||||
* GPIO 0 -> enable AC'97 bypass (line in -> ADC)
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
@ -40,6 +46,7 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/tlv.h>
|
||||
#include "oxygen.h"
|
||||
#include "cm9780.h"
|
||||
|
||||
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
|
||||
MODULE_DESCRIPTION("Asus AV200 driver");
|
||||
|
@ -64,14 +71,68 @@ static struct pci_device_id xonar_ids[] __devinitdata = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(pci, xonar_ids);
|
||||
|
||||
/* register 0x12 */
|
||||
|
||||
#define GPIO_CS5381_M_MASK 0x000c
|
||||
#define GPIO_CS5381_M_SINGLE 0x0000
|
||||
#define GPIO_CS5381_M_DOUBLE 0x0004
|
||||
#define GPIO_CS5381_M_QUAD 0x0008
|
||||
#define GPIO_EXT_POWER 0x0020
|
||||
#define GPIO_ALT 0x0080
|
||||
#define GPIO_OUTPUT_ENABLE 0x0100
|
||||
|
||||
/* register 16 */
|
||||
#define PCM1796_ATL_MASK 0xff
|
||||
/* register 17 */
|
||||
#define PCM1796_ATR_MASK 0xff
|
||||
/* register 18 */
|
||||
#define PCM1796_MUTE 0x01
|
||||
#define PCM1796_FMT_24_MSB 0x30
|
||||
#define PCM1796_DME 0x02
|
||||
#define PCM1796_DMF_MASK 0x0c
|
||||
#define PCM1796_DMF_DISABLED 0x00
|
||||
#define PCM1796_DMF_48 0x04
|
||||
#define PCM1796_DMF_441 0x08
|
||||
#define PCM1796_DMF_32 0x0c
|
||||
#define PCM1796_FMT_MASK 0x70
|
||||
#define PCM1796_FMT_16_RJUST 0x00
|
||||
#define PCM1796_FMT_20_RJUST 0x10
|
||||
#define PCM1796_FMT_24_RJUST 0x20
|
||||
#define PCM1796_FMT_24_LJUST 0x30
|
||||
#define PCM1796_FMT_16_I2S 0x40
|
||||
#define PCM1796_FMT_24_I2S 0x50
|
||||
#define PCM1796_ATLD 0x80
|
||||
/* register 0x14 */
|
||||
/* register 19 */
|
||||
#define PCM1796_INZD 0x01
|
||||
#define PCM1796_FLT_MASK 0x02
|
||||
#define PCM1796_FLT_SHARP 0x00
|
||||
#define PCM1796_FLT_SLOW 0x02
|
||||
#define PCM1796_DFMS 0x04
|
||||
#define PCM1796_OPE 0x10
|
||||
#define PCM1796_ATS_MASK 0x60
|
||||
#define PCM1796_ATS_1 0x00
|
||||
#define PCM1796_ATS_2 0x20
|
||||
#define PCM1796_ATS_4 0x40
|
||||
#define PCM1796_ATS_8 0x60
|
||||
#define PCM1796_REV 0x80
|
||||
/* register 20 */
|
||||
#define PCM1796_OS_MASK 0x03
|
||||
#define PCM1796_OS_64 0x00
|
||||
#define PCM1796_OS_32 0x01
|
||||
#define PCM1796_OS_128 0x02
|
||||
#define PCM1796_CHSL_MASK 0x04
|
||||
#define PCM1796_CHSL_LEFT 0x00
|
||||
#define PCM1796_CHSL_RIGHT 0x04
|
||||
#define PCM1796_MONO 0x08
|
||||
#define PCM1796_DFTH 0x10
|
||||
#define PCM1796_DSD 0x20
|
||||
#define PCM1796_SRST 0x40
|
||||
/* register 21 */
|
||||
#define PCM1796_PCMZ 0x01
|
||||
#define PCM1796_DZ_MASK 0x06
|
||||
/* register 22 */
|
||||
#define PCM1796_ZFGL 0x01
|
||||
#define PCM1796_ZFGR 0x02
|
||||
/* register 23 */
|
||||
#define PCM1796_ID_MASK 0x1f
|
||||
|
||||
static void pcm1796_write(struct oxygen *chip, unsigned int codec,
|
||||
u8 reg, u8 value)
|
||||
|
@ -93,20 +154,23 @@ static void xonar_init(struct oxygen *chip)
|
|||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
pcm1796_write(chip, i, 0x12, PCM1796_FMT_24_MSB | PCM1796_ATLD);
|
||||
pcm1796_write(chip, i, 0x13, 0);
|
||||
pcm1796_write(chip, i, 0x14, PCM1796_OS_64);
|
||||
pcm1796_write(chip, i, 0x15, 0);
|
||||
pcm1796_write(chip, i, 0x10, 0xff);
|
||||
pcm1796_write(chip, i, 0x11, 0xff);
|
||||
pcm1796_write(chip, i, 18, PCM1796_FMT_24_LJUST | PCM1796_ATLD);
|
||||
pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
|
||||
pcm1796_write(chip, i, 20, PCM1796_OS_64);
|
||||
pcm1796_write(chip, i, 21, 0);
|
||||
pcm1796_write(chip, i, 16, 0xff); /* set ATL/ATR after ATLD */
|
||||
pcm1796_write(chip, i, 17, 0xff);
|
||||
}
|
||||
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x8c);
|
||||
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, 0x00, 0x8c);
|
||||
oxygen_ac97_set_bits(chip, 0, 0x62, 0x0080);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
|
||||
GPIO_CS5381_M_MASK | GPIO_ALT);
|
||||
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
|
||||
GPIO_CS5381_M_SINGLE,
|
||||
GPIO_CS5381_M_MASK | GPIO_ALT);
|
||||
oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
|
||||
msleep(300);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 0x100);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, 0x100);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_OUTPUT_ENABLE);
|
||||
oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
|
||||
|
||||
snd_component_add(chip->card, "PCM1796");
|
||||
snd_component_add(chip->card, "CS5381");
|
||||
|
@ -114,7 +178,7 @@ static void xonar_init(struct oxygen *chip)
|
|||
|
||||
static void xonar_cleanup(struct oxygen *chip)
|
||||
{
|
||||
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 0x100);
|
||||
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
|
||||
}
|
||||
|
||||
static void set_pcm1796_params(struct oxygen *chip,
|
||||
|
@ -126,7 +190,7 @@ static void set_pcm1796_params(struct oxygen *chip,
|
|||
|
||||
value = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
|
||||
for (i = 0; i < 4; ++i)
|
||||
pcm1796_write(chip, i, 0x14, value);
|
||||
pcm1796_write(chip, i, 20, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -135,8 +199,8 @@ static void update_pcm1796_volume(struct oxygen *chip)
|
|||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
pcm1796_write(chip, i, 0x10, chip->dac_volume[i * 2]);
|
||||
pcm1796_write(chip, i, 0x11, chip->dac_volume[i * 2 + 1]);
|
||||
pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
|
||||
pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,11 +209,11 @@ static void update_pcm1796_mute(struct oxygen *chip)
|
|||
unsigned int i;
|
||||
u8 value;
|
||||
|
||||
value = PCM1796_FMT_24_MSB | PCM1796_ATLD;
|
||||
value = PCM1796_FMT_24_LJUST | PCM1796_ATLD;
|
||||
if (chip->dac_mute)
|
||||
value |= PCM1796_MUTE;
|
||||
for (i = 0; i < 4; ++i)
|
||||
pcm1796_write(chip, i, 0x12, value);
|
||||
pcm1796_write(chip, i, 18, value);
|
||||
}
|
||||
|
||||
static void set_cs5381_params(struct oxygen *chip,
|
||||
|
@ -158,12 +222,13 @@ static void set_cs5381_params(struct oxygen *chip,
|
|||
unsigned int value;
|
||||
|
||||
if (params_rate(params) <= 54000)
|
||||
value = 0;
|
||||
value = GPIO_CS5381_M_SINGLE;
|
||||
else if (params_rate(params) <= 108000)
|
||||
value = 4;
|
||||
value = GPIO_CS5381_M_DOUBLE;
|
||||
else
|
||||
value = 8;
|
||||
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, value, 0x000c);
|
||||
value = GPIO_CS5381_M_QUAD;
|
||||
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
|
||||
value, GPIO_CS5381_M_MASK);
|
||||
}
|
||||
|
||||
static int pcm1796_volume_info(struct snd_kcontrol *ctl,
|
||||
|
@ -182,7 +247,7 @@ static int alt_switch_get(struct snd_kcontrol *ctl,
|
|||
struct oxygen *chip = ctl->private_data;
|
||||
|
||||
value->value.integer.value[0] =
|
||||
!!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & 0x80);
|
||||
!!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_ALT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -196,9 +261,9 @@ static int alt_switch_put(struct snd_kcontrol *ctl,
|
|||
spin_lock_irq(&chip->reg_lock);
|
||||
old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
|
||||
if (value->value.integer.value[0])
|
||||
new_bits = old_bits | 0x80;
|
||||
new_bits = old_bits | GPIO_ALT;
|
||||
else
|
||||
new_bits = old_bits & ~0x80;
|
||||
new_bits = old_bits & ~GPIO_ALT;
|
||||
changed = new_bits != old_bits;
|
||||
if (changed)
|
||||
oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
|
||||
|
|
Loading…
Reference in New Issue