aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
authorHarley Griggs <hgriggs@posteo.co.uk>2014-09-10 14:58:25 -0400
committerTakashi Iwai <tiwai@suse.de>2014-09-22 02:55:15 -0400
commit5ae0095d00d48be60b2e3cbdb79a35a7d796d96b (patch)
tree85275e4d3d778f47a8dd7aa3b2f499f567aa7292 /sound/pci/oxygen
parent8bb1ffdf76276c040a065c4df173dfce98b5ffa3 (diff)
ALSA: virtuoso: add partial Xonar Xense support
This patch adds partial support for the Xonar Xense. [trivial coding style fixes by tiwai] Signed-off-by: Harley Griggs <hgriggs@posteo.co.uk> Acked-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r--sound/pci/oxygen/virtuoso.c1
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c133
2 files changed, 134 insertions, 0 deletions
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 7b317a28a19c..83de6fb01021 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[] = {
52 { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, 52 { OXYGEN_PCI_SUBID(0x1043, 0x835d) },
53 { OXYGEN_PCI_SUBID(0x1043, 0x835e) }, 53 { OXYGEN_PCI_SUBID(0x1043, 0x835e) },
54 { OXYGEN_PCI_SUBID(0x1043, 0x838e) }, 54 { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
55 { OXYGEN_PCI_SUBID(0x1043, 0x8428) },
55 { OXYGEN_PCI_SUBID(0x1043, 0x8522) }, 56 { OXYGEN_PCI_SUBID(0x1043, 0x8522) },
56 { OXYGEN_PCI_SUBID(0x1043, 0x85f4) }, 57 { OXYGEN_PCI_SUBID(0x1043, 0x85f4) },
57 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 58 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 0d6a805e8b62..24109d37ca09 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -212,6 +212,9 @@
212#define GPIO_ST_MAGIC 0x0040 212#define GPIO_ST_MAGIC 0x0040
213#define GPIO_ST_HP 0x0080 213#define GPIO_ST_HP 0x0080
214 214
215#define GPIO_XENSE_OUTPUT_ENABLE (0x0001 | 0x0010 | 0x0020)
216#define GPIO_XENSE_SPEAKERS 0x0080
217
215#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ 218#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
216#define I2C_DEVICE_CS2000 0x9c /* 100111, 0, /W=0 */ 219#define I2C_DEVICE_CS2000 0x9c /* 100111, 0, /W=0 */
217 220
@@ -500,6 +503,51 @@ static void xonar_stx_init(struct oxygen *chip)
500 xonar_st_init_common(chip); 503 xonar_st_init_common(chip);
501} 504}
502 505
506static void xonar_xense_init(struct oxygen *chip)
507{
508 struct xonar_pcm179x *data = chip->model_data;
509
510 data->generic.ext_power_reg = OXYGEN_GPI_DATA;
511 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
512 data->generic.ext_power_bit = GPI_EXT_POWER;
513 xonar_init_ext_power(chip);
514
515 data->generic.anti_pop_delay = 100;
516 data->has_cs2000 = 1;
517 data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
518
519 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
520 OXYGEN_RATE_48000 |
521 OXYGEN_I2S_FORMAT_I2S |
522 OXYGEN_I2S_MCLK(MCLK_512) |
523 OXYGEN_I2S_BITS_16 |
524 OXYGEN_I2S_MASTER |
525 OXYGEN_I2S_BCLK_64);
526
527 xonar_st_init_i2c(chip);
528 cs2000_registers_init(chip);
529
530 data->generic.output_enable_bit = GPIO_XENSE_OUTPUT_ENABLE;
531 data->dacs = 1;
532 data->hp_gain_offset = 2*-18;
533
534 pcm1796_init(chip);
535
536 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
537 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
538 GPIO_ST_MAGIC | GPIO_XENSE_SPEAKERS);
539 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
540 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
541 GPIO_XENSE_SPEAKERS);
542
543 xonar_init_cs53x1(chip);
544 xonar_enable_output(chip);
545
546 snd_component_add(chip->card, "PCM1796");
547 snd_component_add(chip->card, "CS5381");
548 snd_component_add(chip->card, "CS2000");
549}
550
503static void xonar_d2_cleanup(struct oxygen *chip) 551static void xonar_d2_cleanup(struct oxygen *chip)
504{ 552{
505 xonar_disable_output(chip); 553 xonar_disable_output(chip);
@@ -862,6 +910,67 @@ static const struct snd_kcontrol_new st_controls[] = {
862 }, 910 },
863}; 911};
864 912
913static int xense_output_switch_get(struct snd_kcontrol *ctl,
914 struct snd_ctl_elem_value *value)
915{
916 struct oxygen *chip = ctl->private_data;
917 u16 gpio;
918
919 gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA);
920 if (gpio & GPIO_XENSE_SPEAKERS)
921 value->value.enumerated.item[0] = 0;
922 else if (!(gpio & GPIO_XENSE_SPEAKERS) && (gpio & GPIO_ST_HP_REAR))
923 value->value.enumerated.item[0] = 1;
924 else
925 value->value.enumerated.item[0] = 2;
926 return 0;
927}
928
929static int xense_output_switch_put(struct snd_kcontrol *ctl,
930 struct snd_ctl_elem_value *value)
931{
932 struct oxygen *chip = ctl->private_data;
933 struct xonar_pcm179x *data = chip->model_data;
934 u16 gpio_old, gpio;
935
936 mutex_lock(&chip->mutex);
937 gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
938 gpio = gpio_old;
939 switch (value->value.enumerated.item[0]) {
940 case 0:
941 gpio |= GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR;
942 break;
943 case 1:
944 gpio = (gpio | GPIO_ST_HP_REAR) & ~GPIO_XENSE_SPEAKERS;
945 break;
946 case 2:
947 gpio &= ~(GPIO_XENSE_SPEAKERS | GPIO_ST_HP_REAR);
948 break;
949 }
950 oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
951 data->hp_active = !(gpio & GPIO_XENSE_SPEAKERS);
952 update_pcm1796_volume(chip);
953 mutex_unlock(&chip->mutex);
954 return gpio != gpio_old;
955}
956
957static const struct snd_kcontrol_new xense_controls[] = {
958 {
959 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
960 .name = "Analog Output",
961 .info = st_output_switch_info,
962 .get = xense_output_switch_get,
963 .put = xense_output_switch_put,
964 },
965 {
966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
967 .name = "Headphones Impedance Playback Enum",
968 .info = st_hp_volume_offset_info,
969 .get = st_hp_volume_offset_get,
970 .put = st_hp_volume_offset_put,
971 },
972};
973
865static void xonar_line_mic_ac97_switch(struct oxygen *chip, 974static void xonar_line_mic_ac97_switch(struct oxygen *chip,
866 unsigned int reg, unsigned int mute) 975 unsigned int reg, unsigned int mute)
867{ 976{
@@ -949,6 +1058,23 @@ static int xonar_st_mixer_init(struct oxygen *chip)
949 return 0; 1058 return 0;
950} 1059}
951 1060
1061static int xonar_xense_mixer_init(struct oxygen *chip)
1062{
1063 unsigned int i;
1064 int err;
1065
1066 for (i = 0; i < ARRAY_SIZE(xense_controls); ++i) {
1067 err = snd_ctl_add(chip->card,
1068 snd_ctl_new1(&xense_controls[i], chip));
1069 if (err < 0)
1070 return err;
1071 }
1072 err = add_pcm1796_controls(chip);
1073 if (err < 0)
1074 return err;
1075 return 0;
1076}
1077
952static void dump_pcm1796_registers(struct oxygen *chip, 1078static void dump_pcm1796_registers(struct oxygen *chip,
953 struct snd_info_buffer *buffer) 1079 struct snd_info_buffer *buffer)
954{ 1080{
@@ -1159,6 +1285,13 @@ int get_xonar_pcm179x_model(struct oxygen *chip,
1159 chip->model.resume = xonar_stx_resume; 1285 chip->model.resume = xonar_stx_resume;
1160 chip->model.set_dac_params = set_pcm1796_params; 1286 chip->model.set_dac_params = set_pcm1796_params;
1161 break; 1287 break;
1288 case 0x8428:
1289 chip->model = model_xonar_st;
1290 chip->model.shortname = "Xonar Xense";
1291 chip->model.chip = "AV100";
1292 chip->model.init = xonar_xense_init;
1293 chip->model.mixer_init = xonar_xense_mixer_init;
1294 break;
1162 default: 1295 default:
1163 return -EINVAL; 1296 return -EINVAL;
1164 } 1297 }