[alsa-devel] [PATCH] ALSA: virtuoso: add partial Xonar Xense support

Takashi Iwai tiwai at suse.de
Mon Sep 22 09:01:34 CEST 2014


At Sun, 21 Sep 2014 22:49:12 +0200,
Clemens Ladisch wrote:
> 
> Sorry for the delay.
> 
> Harley Griggs wrote:
> > This patch adds partial support for the Xonar Xense.
> >
> > Signed-off-by: Harley Griggs <hgriggs at posteo.co.uk>
> 
> Acked-by: Clemens Ladisch <clemens at ladisch.de>

Applied now, but I had to correct a trivial few coding-style issues.
At the next time, please check via checkpatch.pl before submission.


thanks,

Takashi

> 
> > ---
> >  sound/pci/oxygen/virtuoso.c      |   1 +
> >  sound/pci/oxygen/xonar_pcm179x.c | 133 +++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 134 insertions(+)
> >
> > diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
> > index 7b317a2..83de6fb 100644
> > --- a/sound/pci/oxygen/virtuoso.c
> > +++ b/sound/pci/oxygen/virtuoso.c
> > @@ -52,6 +52,7 @@ static const struct pci_device_id xonar_ids[] = {
> >  	{ OXYGEN_PCI_SUBID(0x1043, 0x835d) },
> >  	{ OXYGEN_PCI_SUBID(0x1043, 0x835e) },
> >  	{ OXYGEN_PCI_SUBID(0x1043, 0x838e) },
> > +	{ OXYGEN_PCI_SUBID(0x1043, 0x8428) },
> >  	{ OXYGEN_PCI_SUBID(0x1043, 0x8522) },
> >  	{ OXYGEN_PCI_SUBID(0x1043, 0x85f4) },
> >  	{ OXYGEN_PCI_SUBID_BROKEN_EEPROM },
> > diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
> > index e026059..ddf1717 100644
> > --- a/sound/pci/oxygen/xonar_pcm179x.c
> > +++ b/sound/pci/oxygen/xonar_pcm179x.c
> > @@ -212,6 +212,9 @@
> >  #define GPIO_ST_MAGIC		0x0040
> >  #define GPIO_ST_HP		0x0080
> >
> > +#define GPIO_XENSE_OUTPUT_ENABLE	(0x0001 | 0x0010 | 0x0020)
> > +#define GPIO_XENSE_SPEAKERS		0x0080
> > +
> >  #define I2C_DEVICE_PCM1796(i)	(0x98 + ((i) << 1))	/* 10011, ii, /W=0 */
> >  #define I2C_DEVICE_CS2000	0x9c			/* 100111, 0, /W=0 */
> >
> > @@ -499,6 +502,51 @@ static void xonar_stx_init(struct oxygen *chip)
> >  	xonar_st_init_common(chip);
> >  }
> >
> > +static void xonar_xense_init(struct oxygen *chip)
> > +{
> > +	struct xonar_pcm179x *data = chip->model_data;
> > +
> > +	data->generic.ext_power_reg = OXYGEN_GPI_DATA;
> > +	data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
> > +	data->generic.ext_power_bit = GPI_EXT_POWER;
> > +	xonar_init_ext_power(chip);
> > +
> > +	data->generic.anti_pop_delay = 100;
> > +	data->has_cs2000 = 1;
> > +	data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
> > +
> > +	oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
> > +		OXYGEN_RATE_48000 |
> > +		OXYGEN_I2S_FORMAT_I2S |
> > +		OXYGEN_I2S_MCLK(MCLK_512) |
> > +		OXYGEN_I2S_BITS_16 |
> > +		OXYGEN_I2S_MASTER |
> > +		OXYGEN_I2S_BCLK_64);
> > +
> > +	xonar_st_init_i2c(chip);
> > +	cs2000_registers_init(chip);
> > +
> > +	data->generic.output_enable_bit = GPIO_XENSE_OUTPUT_ENABLE;
> > +	data->dacs = 1;
> > +	data->hp_gain_offset = 2*-18;
> > +
> > +	pcm1796_init(chip);
> > +
> > +	oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
> > +		GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
> > +		GPIO_ST_MAGIC | GPIO_XENSE_SPEAKERS);
> > +	oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
> > +		GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
> > +		GPIO_XENSE_SPEAKERS);
> > +
> > +	xonar_init_cs53x1(chip);
> > +	xonar_enable_output(chip);
> > +
> > +	snd_component_add(chip->card, "PCM1796");
> > +	snd_component_add(chip->card, "CS5381");
> > +	snd_component_add(chip->card, "CS2000");
> > +}
> > +
> >  static void xonar_d2_cleanup(struct oxygen *chip)
> >  {
> >  	xonar_disable_output(chip);
> > @@ -859,6 +907,67 @@ static const struct snd_kcontrol_new st_controls[] = {
> >  	},
> >  };
> >
> > +static int xense_output_switch_get(struct snd_kcontrol *ctl,
> > +               struct snd_ctl_elem_value *value)
> > +{
> > +	struct oxygen *chip = ctl->private_data;
> > +	u16 gpio;
> > +
> > +	gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA);
> > +	if (gpio & GPIO_XENSE_SPEAKERS)
> > +		value->value.enumerated.item[0] = 0;
> > +	else if (!(gpio & GPIO_XENSE_SPEAKERS) && (gpio & GPIO_ST_HP_REAR))
> > +		value->value.enumerated.item[0] = 1;
> > +	else
> > +		value->value.enumerated.item[0] = 2;
> > +	return 0;
> > +}
> > +
> > +static int xense_output_switch_put(struct snd_kcontrol *ctl,
> > +               struct snd_ctl_elem_value *value)
> > +{
> > +	struct oxygen *chip = ctl->private_data;
> > +	struct xonar_pcm179x *data = chip->model_data;
> > +	u16 gpio_old, gpio;
> > +
> > +	mutex_lock(&chip->mutex);
> > +	gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
> > +	gpio = gpio_old;
> > +	switch (value->value.enumerated.item[0]) {
> > +	case 0:
> > +		gpio |= GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR;
> > +		break;
> > +	case 1:
> > +		gpio = (gpio | GPIO_ST_HP_REAR) & ~GPIO_XENSE_SPEAKERS;
> > +		break;
> > +	case 2:
> > +		gpio &= ~(GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR);
> > +		break;
> > +	}
> > +	oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
> > +	data->hp_active = !(gpio & GPIO_XENSE_SPEAKERS);
> > +	update_pcm1796_volume(chip);
> > +	mutex_unlock(&chip->mutex);
> > +	return gpio != gpio_old;
> > +}
> > +
> > +static const struct snd_kcontrol_new xense_controls[] = {
> > +	{
> > +		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> > +		.name = "Analog Output",
> > +		.info = st_output_switch_info,
> > +		.get = xense_output_switch_get,
> > +		.put = xense_output_switch_put,
> > +	},
> > +	{
> > +		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> > +		.name = "Headphones Impedance Playback Enum",
> > +		.info = st_hp_volume_offset_info,
> > +		.get = st_hp_volume_offset_get,
> > +		.put = st_hp_volume_offset_put,
> > +	},
> > +};
> > +
> >  static void xonar_line_mic_ac97_switch(struct oxygen *chip,
> >  				       unsigned int reg, unsigned int mute)
> >  {
> > @@ -946,6 +1055,23 @@ static int xonar_st_mixer_init(struct oxygen *chip)
> >  	return 0;
> >  }
> >
> > +static int xonar_xense_mixer_init(struct oxygen *chip)
> > +{
> > +	unsigned int i;
> > +	int err;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(xense_controls); ++i) {
> > +		err = snd_ctl_add(chip->card,
> > +		snd_ctl_new1(&xense_controls[i], chip));
> > +		if (err < 0)
> > +			return err;
> > +	}
> > +	err = add_pcm1796_controls(chip);
> > +	if (err < 0)
> > +		return err;
> > +	return 0;
> > +}
> > +
> >  static void dump_pcm1796_registers(struct oxygen *chip,
> >  				   struct snd_info_buffer *buffer)
> >  {
> > @@ -1146,6 +1272,13 @@ int get_xonar_pcm179x_model(struct oxygen *chip,
> >  		chip->model.resume = xonar_stx_resume;
> >  		chip->model.set_dac_params = set_pcm1796_params;
> >  		break;
> > +	case 0x8428:
> > +		chip->model = model_xonar_st;
> > +		chip->model.shortname = "Xonar Xense";
> > +		chip->model.chip = "AV100";
> > +		chip->model.init = xonar_xense_init;
> > +		chip->model.mixer_init = xonar_xense_mixer_init;
> > +		break;
> >  	default:
> >  		return -EINVAL;
> >  	}
> 


More information about the Alsa-devel mailing list