* [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).