alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ALSA: virtuoso: add Xonar Xense support
@ 2014-09-10 14:18 Harley Griggs
  2014-09-10 15:38 ` Clemens Ladisch
  0 siblings, 1 reply; 11+ messages in thread
From: Harley Griggs @ 2014-09-10 14:18 UTC (permalink / raw)
  To: alsa-devel

This patch adds support for the Xonar Xense card. Has been working fine
for over a year and with the latest Xonar patches.

I have not touched the CS4362A (surround), nor am I sure how to go about
it without more code duplication or refactoring.


Signed-off-by: Harley Griggs <hgriggs@posteo.co.uk>
---
 sound/pci/oxygen/virtuoso.c      |   1 +
 sound/pci/oxygen/xonar_pcm179x.c | 135 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 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..e06acfc 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,52 @@ 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;
+	data->broken_i2c = true;
+
+	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 = chip->model.dac_channels_mixer / 2;
+	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 +908,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 +1056,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 +1273,14 @@ 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;
 	}
-- 
1.8.5.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add Xonar Xense support
  2014-09-10 14:18 [PATCH] ALSA: virtuoso: add Xonar Xense support Harley Griggs
@ 2014-09-10 15:38 ` Clemens Ladisch
  2014-09-10 16:04   ` Harley Griggs
  0 siblings, 1 reply; 11+ messages in thread
From: Clemens Ladisch @ 2014-09-10 15:38 UTC (permalink / raw)
  To: Harley Griggs, alsa-devel

Harley Griggs wrote:
> This patch adds support for the Xonar Xense card.

The title is misleading.  This is "partial support" or "stereo-only support".

> +++ b/sound/pci/oxygen/xonar_pcm179x.c

> +	data->broken_i2c = true;

It's not.  (There is no other chip at address 1001110.)

> +	data->dacs = chip->model.dac_channels_mixer / 2;

This variable counts PCM1796 chips.

> +static int xense_output_switch_put(struct snd_kcontrol *ctl,
> +               struct snd_ctl_elem_value *value)
> +{
> +...
> +	case 2:
> +		gpio &= ~(GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR);
> +	break;

Indent.

> +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;
> +	}

Same here.

> @@ -1146,6 +1273,14 @@ int get_xonar_pcm179x_model(struct oxygen *chip,
> +	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;
> +

Why the empty line?


Regards,
Clemens

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add Xonar Xense support
  2014-09-10 15:38 ` Clemens Ladisch
@ 2014-09-10 16:04   ` Harley Griggs
  2014-09-10 18:15     ` Clemens Ladisch
  0 siblings, 1 reply; 11+ messages in thread
From: Harley Griggs @ 2014-09-10 16:04 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

On Wed, 10 Sep 2014 17:38:31 +0200
Clemens Ladisch <clemens@ladisch.de> wrote:

>Harley Griggs wrote:
>> This patch adds support for the Xonar Xense card.
>
>The title is misleading.  This is "partial support" or "stereo-only
>support".

Apologies. Should I resubmit with a new title or just use this thread?

>
>> +++ b/sound/pci/oxygen/xonar_pcm179x.c
>
>> +	data->broken_i2c = true;
>
>It's not.  (There is no other chip at address 1001110.)

I'll remove this. I tried to use the ST as a template as much as
possible. Is there a reason the ST uses this ?

>
>> +	data->dacs = chip->model.dac_channels_mixer / 2;
>
>This variable counts PCM1796 chips.

I overlooked this, will set to 1.

>
>> +static int xense_output_switch_put(struct snd_kcontrol *ctl,
>> +               struct snd_ctl_elem_value *value)
>> +{
>> +...
>> +	case 2:
>> +		gpio &= ~(GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR);
>> +	break;
>
>Indent.
>
>> +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;
>> +	}
>
>Same here.
>
>> @@ -1146,6 +1273,14 @@ int get_xonar_pcm179x_model(struct oxygen
>> *chip,
>> +	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;
>> +
>
>Why the empty line?

I'll fix the incorrect formatting.

>
>
>Regards,
>Clemens
>_______________________________________________
>Alsa-devel mailing list
>Alsa-devel@alsa-project.org
>http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add Xonar Xense support
  2014-09-10 16:04   ` Harley Griggs
@ 2014-09-10 18:15     ` Clemens Ladisch
  2014-09-10 18:19       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
                         ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Clemens Ladisch @ 2014-09-10 18:15 UTC (permalink / raw)
  To: Harley Griggs; +Cc: alsa-devel

Harley Griggs wrote:
> Clemens Ladisch <clemens@ladisch.de> wrote:
>> Harley Griggs wrote:
>>> This patch adds support for the Xonar Xense card.
>>
>> The title is misleading.  This is "partial support" or "stereo-only
>> support".
>
> Apologies. Should I resubmit with a new title or just use this thread?

Resubmit with a new title in this thread.

>>> +	data->broken_i2c = true;
>>
>> It's not.  (There is no other chip at address 1001110.)
>
> I'll remove this. I tried to use the ST as a template as much as
> possible. Is there a reason the ST uses this ?

On the ST, there are two chips with address 1001110.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add partial Xonar Xense support
  2014-09-10 18:15     ` Clemens Ladisch
@ 2014-09-10 18:19       ` Harley Griggs
  2014-09-10 18:43         ` Harley Griggs
  2014-09-10 18:44       ` [PATCH] ALSA: virtuoso: add " Harley Griggs
  2014-09-10 18:58       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
  2 siblings, 1 reply; 11+ messages in thread
From: Harley Griggs @ 2014-09-10 18:19 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

This patch adds partial support for the Xonar Xense.


Signed-off-by: Harley Griggs <hgriggs@posteo.co.uk>
---
 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;
 	}
-- 
1.8.5.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add partial Xonar Xense support
  2014-09-10 18:19       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
@ 2014-09-10 18:43         ` Harley Griggs
  0 siblings, 0 replies; 11+ messages in thread
From: Harley Griggs @ 2014-09-10 18:43 UTC (permalink / raw)
  To: Harley Griggs; +Cc: alsa-devel, Clemens Ladisch

Please ignore this - client broke the formatting.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add Xonar Xense support
  2014-09-10 18:15     ` Clemens Ladisch
  2014-09-10 18:19       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
@ 2014-09-10 18:44       ` Harley Griggs
  2014-09-10 18:59         ` Harley Griggs
  2014-09-10 18:58       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
  2 siblings, 1 reply; 11+ messages in thread
From: Harley Griggs @ 2014-09-10 18:44 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

This patch adds partial support for the Xonar Xense.


Signed-off-by: Harley Griggs <hgriggs@posteo.co.uk>
---
 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;
 	}
-- 
1.8.5.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add partial Xonar Xense support
  2014-09-10 18:15     ` Clemens Ladisch
  2014-09-10 18:19       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
  2014-09-10 18:44       ` [PATCH] ALSA: virtuoso: add " Harley Griggs
@ 2014-09-10 18:58       ` Harley Griggs
  2014-09-21 20:49         ` Clemens Ladisch
  2 siblings, 1 reply; 11+ messages in thread
From: Harley Griggs @ 2014-09-10 18:58 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

This patch adds partial support for the Xonar Xense.


Signed-off-by: Harley Griggs <hgriggs@posteo.co.uk>
---
 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;
 	}
-- 
1.8.5.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add Xonar Xense support
  2014-09-10 18:44       ` [PATCH] ALSA: virtuoso: add " Harley Griggs
@ 2014-09-10 18:59         ` Harley Griggs
  0 siblings, 0 replies; 11+ messages in thread
From: Harley Griggs @ 2014-09-10 18:59 UTC (permalink / raw)
  To: Harley Griggs; +Cc: alsa-devel, Clemens Ladisch

Please also ignore - forgot to adjust the title when resubmitting.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add partial Xonar Xense support
  2014-09-10 18:58       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
@ 2014-09-21 20:49         ` Clemens Ladisch
  2014-09-22  7:01           ` Takashi Iwai
  0 siblings, 1 reply; 11+ messages in thread
From: Clemens Ladisch @ 2014-09-21 20:49 UTC (permalink / raw)
  To: Harley Griggs, Takashi Iwai; +Cc: alsa-devel

Sorry for the delay.

Harley Griggs wrote:
> This patch adds partial support for the Xonar Xense.
>
> Signed-off-by: Harley Griggs <hgriggs@posteo.co.uk>

Acked-by: Clemens Ladisch <clemens@ladisch.de>

> ---
>  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;
>  	}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] ALSA: virtuoso: add partial Xonar Xense support
  2014-09-21 20:49         ` Clemens Ladisch
@ 2014-09-22  7:01           ` Takashi Iwai
  0 siblings, 0 replies; 11+ messages in thread
From: Takashi Iwai @ 2014-09-22  7:01 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel, Harley Griggs

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@posteo.co.uk>
> 
> Acked-by: Clemens Ladisch <clemens@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;
> >  	}
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-09-22  7:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-10 14:18 [PATCH] ALSA: virtuoso: add Xonar Xense support Harley Griggs
2014-09-10 15:38 ` Clemens Ladisch
2014-09-10 16:04   ` Harley Griggs
2014-09-10 18:15     ` Clemens Ladisch
2014-09-10 18:19       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
2014-09-10 18:43         ` Harley Griggs
2014-09-10 18:44       ` [PATCH] ALSA: virtuoso: add " Harley Griggs
2014-09-10 18:59         ` Harley Griggs
2014-09-10 18:58       ` [PATCH] ALSA: virtuoso: add partial " Harley Griggs
2014-09-21 20:49         ` Clemens Ladisch
2014-09-22  7:01           ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).