Commit ed42e71a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-4.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Most of changes in this pull request are about the fixes of crash of
  FireWire drivers at hot-unplugging.  In addition, there are a few
  HD-audio fixes (removal of wrong static, a pin quirk for an ASUS mobo,
  a regression fix for runtime PM on Panther Point) and a long-standing
  (but fairly minor) bug of PCM core"

* tag 'sound-4.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Disable runtime PM for Panther Point again
  ALSA: hda: controller code - do not export static functions
  ALSA: pcm: Don't leave PREPARED state after draining
  ALSA: fireworks/bebob/dice/oxfw: make it possible to shutdown safely
  ALSA: fireworks/bebob/dice/oxfw: allow stream destructor after releasing runtime
  ALSA: firewire-lib: remove reference counting
  ALSA: fireworks/bebob/dice/oxfw: add reference-counting for FireWire unit
  ALSA: hda - Add pin configs for ASUS mobo with IDT 92HD73XX codec
  ALSA: firewire-lib: fix an unexpected byte sequence for micro sign
parents 7dac5cb1 de5d0ad5
...@@ -1552,6 +1552,8 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state) ...@@ -1552,6 +1552,8 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
if (! snd_pcm_playback_empty(substream)) { if (! snd_pcm_playback_empty(substream)) {
snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING); snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING); snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
} else {
runtime->status->state = SNDRV_PCM_STATE_SETUP;
} }
break; break;
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
*/ */
#define MAX_MIDI_RX_BLOCKS 8 #define MAX_MIDI_RX_BLOCKS 8
#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */ #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */
/* isochronous header parameters */ /* isochronous header parameters */
#define ISO_DATA_LENGTH_SHIFT 16 #define ISO_DATA_LENGTH_SHIFT 16
...@@ -78,7 +78,7 @@ static void pcm_period_tasklet(unsigned long data); ...@@ -78,7 +78,7 @@ static void pcm_period_tasklet(unsigned long data);
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
enum amdtp_stream_direction dir, enum cip_flags flags) enum amdtp_stream_direction dir, enum cip_flags flags)
{ {
s->unit = fw_unit_get(unit); s->unit = unit;
s->direction = dir; s->direction = dir;
s->flags = flags; s->flags = flags;
s->context = ERR_PTR(-1); s->context = ERR_PTR(-1);
...@@ -102,7 +102,6 @@ void amdtp_stream_destroy(struct amdtp_stream *s) ...@@ -102,7 +102,6 @@ void amdtp_stream_destroy(struct amdtp_stream *s)
{ {
WARN_ON(amdtp_stream_running(s)); WARN_ON(amdtp_stream_running(s));
mutex_destroy(&s->mutex); mutex_destroy(&s->mutex);
fw_unit_put(s->unit);
} }
EXPORT_SYMBOL(amdtp_stream_destroy); EXPORT_SYMBOL(amdtp_stream_destroy);
......
...@@ -116,11 +116,22 @@ name_device(struct snd_bebob *bebob, unsigned int vendor_id) ...@@ -116,11 +116,22 @@ name_device(struct snd_bebob *bebob, unsigned int vendor_id)
return err; return err;
} }
/*
* This module releases the FireWire unit data after all ALSA character devices
* are released by applications. This is for releasing stream data or finishing
* transactions safely. Thus at returning from .remove(), this module still keep
* references for the unit.
*/
static void static void
bebob_card_free(struct snd_card *card) bebob_card_free(struct snd_card *card)
{ {
struct snd_bebob *bebob = card->private_data; struct snd_bebob *bebob = card->private_data;
snd_bebob_stream_destroy_duplex(bebob);
fw_unit_put(bebob->unit);
kfree(bebob->maudio_special_quirk);
if (bebob->card_index >= 0) { if (bebob->card_index >= 0) {
mutex_lock(&devices_mutex); mutex_lock(&devices_mutex);
clear_bit(bebob->card_index, devices_used); clear_bit(bebob->card_index, devices_used);
...@@ -205,7 +216,7 @@ bebob_probe(struct fw_unit *unit, ...@@ -205,7 +216,7 @@ bebob_probe(struct fw_unit *unit,
card->private_free = bebob_card_free; card->private_free = bebob_card_free;
bebob->card = card; bebob->card = card;
bebob->unit = unit; bebob->unit = fw_unit_get(unit);
bebob->spec = spec; bebob->spec = spec;
mutex_init(&bebob->mutex); mutex_init(&bebob->mutex);
spin_lock_init(&bebob->lock); spin_lock_init(&bebob->lock);
...@@ -306,10 +317,11 @@ static void bebob_remove(struct fw_unit *unit) ...@@ -306,10 +317,11 @@ static void bebob_remove(struct fw_unit *unit)
if (bebob == NULL) if (bebob == NULL)
return; return;
kfree(bebob->maudio_special_quirk); /* Awake bus-reset waiters. */
if (!completion_done(&bebob->bus_reset))
complete_all(&bebob->bus_reset);
snd_bebob_stream_destroy_duplex(bebob); /* No need to wait for releasing card object in this context. */
snd_card_disconnect(bebob->card);
snd_card_free_when_closed(bebob->card); snd_card_free_when_closed(bebob->card);
} }
......
...@@ -410,8 +410,6 @@ break_both_connections(struct snd_bebob *bebob) ...@@ -410,8 +410,6 @@ break_both_connections(struct snd_bebob *bebob)
static void static void
destroy_both_connections(struct snd_bebob *bebob) destroy_both_connections(struct snd_bebob *bebob)
{ {
break_both_connections(bebob);
cmp_connection_destroy(&bebob->in_conn); cmp_connection_destroy(&bebob->in_conn);
cmp_connection_destroy(&bebob->out_conn); cmp_connection_destroy(&bebob->out_conn);
} }
...@@ -712,22 +710,16 @@ void snd_bebob_stream_update_duplex(struct snd_bebob *bebob) ...@@ -712,22 +710,16 @@ void snd_bebob_stream_update_duplex(struct snd_bebob *bebob)
mutex_unlock(&bebob->mutex); mutex_unlock(&bebob->mutex);
} }
/*
* This function should be called before starting streams or after stopping
* streams.
*/
void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob) void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
{ {
mutex_lock(&bebob->mutex);
amdtp_stream_pcm_abort(&bebob->rx_stream);
amdtp_stream_pcm_abort(&bebob->tx_stream);
amdtp_stream_stop(&bebob->rx_stream);
amdtp_stream_stop(&bebob->tx_stream);
amdtp_stream_destroy(&bebob->rx_stream); amdtp_stream_destroy(&bebob->rx_stream);
amdtp_stream_destroy(&bebob->tx_stream); amdtp_stream_destroy(&bebob->tx_stream);
destroy_both_connections(bebob); destroy_both_connections(bebob);
mutex_unlock(&bebob->mutex);
} }
/* /*
......
...@@ -311,14 +311,21 @@ static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream) ...@@ -311,14 +311,21 @@ static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
return err; return err;
} }
/*
* This function should be called before starting streams or after stopping
* streams.
*/
static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream) static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)
{ {
amdtp_stream_destroy(stream); struct fw_iso_resources *resources;
if (stream == &dice->tx_stream) if (stream == &dice->tx_stream)
fw_iso_resources_destroy(&dice->tx_resources); resources = &dice->tx_resources;
else else
fw_iso_resources_destroy(&dice->rx_resources); resources = &dice->rx_resources;
amdtp_stream_destroy(stream);
fw_iso_resources_destroy(resources);
} }
int snd_dice_stream_init_duplex(struct snd_dice *dice) int snd_dice_stream_init_duplex(struct snd_dice *dice)
...@@ -332,6 +339,8 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice) ...@@ -332,6 +339,8 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
goto end; goto end;
err = init_stream(dice, &dice->rx_stream); err = init_stream(dice, &dice->rx_stream);
if (err < 0)
destroy_stream(dice, &dice->tx_stream);
end: end:
return err; return err;
} }
...@@ -340,10 +349,7 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice) ...@@ -340,10 +349,7 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
{ {
snd_dice_transaction_clear_enable(dice); snd_dice_transaction_clear_enable(dice);
stop_stream(dice, &dice->tx_stream);
destroy_stream(dice, &dice->tx_stream); destroy_stream(dice, &dice->tx_stream);
stop_stream(dice, &dice->rx_stream);
destroy_stream(dice, &dice->rx_stream); destroy_stream(dice, &dice->rx_stream);
dice->substreams_counter = 0; dice->substreams_counter = 0;
......
...@@ -226,11 +226,20 @@ static void dice_card_strings(struct snd_dice *dice) ...@@ -226,11 +226,20 @@ static void dice_card_strings(struct snd_dice *dice)
strcpy(card->mixername, "DICE"); strcpy(card->mixername, "DICE");
} }
/*
* This module releases the FireWire unit data after all ALSA character devices
* are released by applications. This is for releasing stream data or finishing
* transactions safely. Thus at returning from .remove(), this module still keep
* references for the unit.
*/
static void dice_card_free(struct snd_card *card) static void dice_card_free(struct snd_card *card)
{ {
struct snd_dice *dice = card->private_data; struct snd_dice *dice = card->private_data;
snd_dice_stream_destroy_duplex(dice);
snd_dice_transaction_destroy(dice); snd_dice_transaction_destroy(dice);
fw_unit_put(dice->unit);
mutex_destroy(&dice->mutex); mutex_destroy(&dice->mutex);
} }
...@@ -251,7 +260,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) ...@@ -251,7 +260,7 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
dice = card->private_data; dice = card->private_data;
dice->card = card; dice->card = card;
dice->unit = unit; dice->unit = fw_unit_get(unit);
card->private_free = dice_card_free; card->private_free = dice_card_free;
spin_lock_init(&dice->lock); spin_lock_init(&dice->lock);
...@@ -305,10 +314,7 @@ static void dice_remove(struct fw_unit *unit) ...@@ -305,10 +314,7 @@ static void dice_remove(struct fw_unit *unit)
{ {
struct snd_dice *dice = dev_get_drvdata(&unit->device); struct snd_dice *dice = dev_get_drvdata(&unit->device);
snd_card_disconnect(dice->card); /* No need to wait for releasing card object in this context. */
snd_dice_stream_destroy_duplex(dice);
snd_card_free_when_closed(dice->card); snd_card_free_when_closed(dice->card);
} }
......
...@@ -173,11 +173,23 @@ get_hardware_info(struct snd_efw *efw) ...@@ -173,11 +173,23 @@ get_hardware_info(struct snd_efw *efw)
return err; return err;
} }
/*
* This module releases the FireWire unit data after all ALSA character devices
* are released by applications. This is for releasing stream data or finishing
* transactions safely. Thus at returning from .remove(), this module still keep
* references for the unit.
*/
static void static void
efw_card_free(struct snd_card *card) efw_card_free(struct snd_card *card)
{ {
struct snd_efw *efw = card->private_data; struct snd_efw *efw = card->private_data;
snd_efw_stream_destroy_duplex(efw);
snd_efw_transaction_remove_instance(efw);
fw_unit_put(efw->unit);
kfree(efw->resp_buf);
if (efw->card_index >= 0) { if (efw->card_index >= 0) {
mutex_lock(&devices_mutex); mutex_lock(&devices_mutex);
clear_bit(efw->card_index, devices_used); clear_bit(efw->card_index, devices_used);
...@@ -185,7 +197,6 @@ efw_card_free(struct snd_card *card) ...@@ -185,7 +197,6 @@ efw_card_free(struct snd_card *card)
} }
mutex_destroy(&efw->mutex); mutex_destroy(&efw->mutex);
kfree(efw->resp_buf);
} }
static int static int
...@@ -218,7 +229,7 @@ efw_probe(struct fw_unit *unit, ...@@ -218,7 +229,7 @@ efw_probe(struct fw_unit *unit,
card->private_free = efw_card_free; card->private_free = efw_card_free;
efw->card = card; efw->card = card;
efw->unit = unit; efw->unit = fw_unit_get(unit);
mutex_init(&efw->mutex); mutex_init(&efw->mutex);
spin_lock_init(&efw->lock); spin_lock_init(&efw->lock);
init_waitqueue_head(&efw->hwdep_wait); init_waitqueue_head(&efw->hwdep_wait);
...@@ -289,10 +300,7 @@ static void efw_remove(struct fw_unit *unit) ...@@ -289,10 +300,7 @@ static void efw_remove(struct fw_unit *unit)
{ {
struct snd_efw *efw = dev_get_drvdata(&unit->device); struct snd_efw *efw = dev_get_drvdata(&unit->device);
snd_efw_stream_destroy_duplex(efw); /* No need to wait for releasing card object in this context. */
snd_efw_transaction_remove_instance(efw);
snd_card_disconnect(efw->card);
snd_card_free_when_closed(efw->card); snd_card_free_when_closed(efw->card);
} }
......
...@@ -100,17 +100,22 @@ start_stream(struct snd_efw *efw, struct amdtp_stream *stream, ...@@ -100,17 +100,22 @@ start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
return err; return err;
} }
/*
* This function should be called before starting the stream or after stopping
* the streams.
*/
static void static void
destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream) destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream)
{ {
stop_stream(efw, stream); struct cmp_connection *conn;
amdtp_stream_destroy(stream);
if (stream == &efw->tx_stream) if (stream == &efw->tx_stream)
cmp_connection_destroy(&efw->out_conn); conn = &efw->out_conn;
else else
cmp_connection_destroy(&efw->in_conn); conn = &efw->in_conn;
amdtp_stream_destroy(stream);
cmp_connection_destroy(&efw->out_conn);
} }
static int static int
...@@ -319,12 +324,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw) ...@@ -319,12 +324,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw)
void snd_efw_stream_destroy_duplex(struct snd_efw *efw) void snd_efw_stream_destroy_duplex(struct snd_efw *efw)
{ {
mutex_lock(&efw->mutex);
destroy_stream(efw, &efw->rx_stream); destroy_stream(efw, &efw->rx_stream);
destroy_stream(efw, &efw->tx_stream); destroy_stream(efw, &efw->tx_stream);
mutex_unlock(&efw->mutex);
} }
void snd_efw_stream_lock_changed(struct snd_efw *efw) void snd_efw_stream_lock_changed(struct snd_efw *efw)
......
...@@ -337,6 +337,10 @@ void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw, ...@@ -337,6 +337,10 @@ void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw,
stop_stream(oxfw, stream); stop_stream(oxfw, stream);
} }
/*
* This function should be called before starting the stream or after stopping
* the streams.
*/
void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw,
struct amdtp_stream *stream) struct amdtp_stream *stream)
{ {
...@@ -347,8 +351,6 @@ void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, ...@@ -347,8 +351,6 @@ void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw,
else else
conn = &oxfw->in_conn; conn = &oxfw->in_conn;
stop_stream(oxfw, stream);
amdtp_stream_destroy(stream); amdtp_stream_destroy(stream);
cmp_connection_destroy(conn); cmp_connection_destroy(conn);
} }
......
...@@ -104,11 +104,23 @@ static int name_card(struct snd_oxfw *oxfw) ...@@ -104,11 +104,23 @@ static int name_card(struct snd_oxfw *oxfw)
return err; return err;
} }
/*
* This module releases the FireWire unit data after all ALSA character devices
* are released by applications. This is for releasing stream data or finishing
* transactions safely. Thus at returning from .remove(), this module still keep
* references for the unit.
*/
static void oxfw_card_free(struct snd_card *card) static void oxfw_card_free(struct snd_card *card)
{ {
struct snd_oxfw *oxfw = card->private_data; struct snd_oxfw *oxfw = card->private_data;
unsigned int i; unsigned int i;
snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
if (oxfw->has_output)
snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
fw_unit_put(oxfw->unit);
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
kfree(oxfw->tx_stream_formats[i]); kfree(oxfw->tx_stream_formats[i]);
kfree(oxfw->rx_stream_formats[i]); kfree(oxfw->rx_stream_formats[i]);
...@@ -136,7 +148,7 @@ static int oxfw_probe(struct fw_unit *unit, ...@@ -136,7 +148,7 @@ static int oxfw_probe(struct fw_unit *unit,
oxfw = card->private_data; oxfw = card->private_data;
oxfw->card = card; oxfw->card = card;
mutex_init(&oxfw->mutex); mutex_init(&oxfw->mutex);
oxfw->unit = unit; oxfw->unit = fw_unit_get(unit);
oxfw->device_info = (const struct device_info *)id->driver_data; oxfw->device_info = (const struct device_info *)id->driver_data;
spin_lock_init(&oxfw->lock); spin_lock_init(&oxfw->lock);
init_waitqueue_head(&oxfw->hwdep_wait); init_waitqueue_head(&oxfw->hwdep_wait);
...@@ -212,12 +224,7 @@ static void oxfw_remove(struct fw_unit *unit) ...@@ -212,12 +224,7 @@ static void oxfw_remove(struct fw_unit *unit)
{ {
struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
snd_card_disconnect(oxfw->card); /* No need to wait for releasing card object in this context. */
snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream);
if (oxfw->has_output)
snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream);
snd_card_free_when_closed(oxfw->card); snd_card_free_when_closed(oxfw->card);
} }
......
...@@ -961,7 +961,6 @@ static int azx_alloc_cmd_io(struct azx *chip) ...@@ -961,7 +961,6 @@ static int azx_alloc_cmd_io(struct azx *chip)
dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n");
return err; return err;
} }
EXPORT_SYMBOL_GPL(azx_alloc_cmd_io);
static void azx_init_cmd_io(struct azx *chip) static void azx_init_cmd_io(struct azx *chip)
{ {
...@@ -1026,7 +1025,6 @@ static void azx_init_cmd_io(struct azx *chip) ...@@ -1026,7 +1025,6 @@ static void azx_init_cmd_io(struct azx *chip)
azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
spin_unlock_irq(&chip->reg_lock); spin_unlock_irq(&chip->reg_lock);
} }
EXPORT_SYMBOL_GPL(azx_init_cmd_io);
static void azx_free_cmd_io(struct azx *chip) static void azx_free_cmd_io(struct azx *chip)
{ {
...@@ -1036,7 +1034,6 @@ static void azx_free_cmd_io(struct azx *chip) ...@@ -1036,7 +1034,6 @@ static void azx_free_cmd_io(struct azx *chip)
azx_writeb(chip, CORBCTL, 0); azx_writeb(chip, CORBCTL, 0);
spin_unlock_irq(&chip->reg_lock); spin_unlock_irq(&chip->reg_lock);
} }
EXPORT_SYMBOL_GPL(azx_free_cmd_io);
static unsigned int azx_command_addr(u32 cmd) static unsigned int azx_command_addr(u32 cmd)
{ {
...@@ -1316,7 +1313,6 @@ static int azx_send_cmd(struct hda_bus *bus, unsigned int val) ...@@ -1316,7 +1313,6 @@ static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
else else
return azx_corb_send_cmd(bus, val); return azx_corb_send_cmd(bus, val);
} }
EXPORT_SYMBOL_GPL(azx_send_cmd);
/* get a response */ /* get a response */
static unsigned int azx_get_response(struct hda_bus *bus, static unsigned int azx_get_response(struct hda_bus *bus,
...@@ -1330,7 +1326,6 @@ static unsigned int azx_get_response(struct hda_bus *bus, ...@@ -1330,7 +1326,6 @@ static unsigned int azx_get_response(struct hda_bus *bus,
else else
return azx_rirb_get_response(bus, addr); return azx_rirb_get_response(bus, addr);
} }
EXPORT_SYMBOL_GPL(azx_get_response);
#ifdef CONFIG_SND_HDA_DSP_LOADER #ifdef CONFIG_SND_HDA_DSP_LOADER
/* /*
......
...@@ -1966,7 +1966,7 @@ static const struct pci_device_id azx_ids[] = { ...@@ -1966,7 +1966,7 @@ static const struct pci_device_id azx_ids[] = {
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
/* Panther Point */ /* Panther Point */
{ PCI_DEVICE(0x8086, 0x1e20), { PCI_DEVICE(0x8086, 0x1e20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
/* Lynx Point */ /* Lynx Point */
{ PCI_DEVICE(0x8086, 0x8c20), { PCI_DEVICE(0x8086, 0x8c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
......
...@@ -79,6 +79,7 @@ enum { ...@@ -79,6 +79,7 @@ enum {
STAC_ALIENWARE_M17X, STAC_ALIENWARE_M17X,
STAC_92HD89XX_HP_FRONT_JACK, STAC_92HD89XX_HP_FRONT_JACK,
STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK, STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK,
STAC_92HD73XX_ASUS_MOBO,
STAC_92HD73XX_MODELS STAC_92HD73XX_MODELS
}; };
...@@ -1911,7 +1912,18 @@ static const struct hda_fixup stac92hd73xx_fixups[] = { ...@@ -1911,7 +1912,18 @@ static const struct hda_fixup stac92hd73xx_fixups[] = {
[STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = { [STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = {
.type = HDA_FIXUP_PINS, .type = HDA_FIXUP_PINS,
.v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs, .v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs,
} },
[STAC_92HD73XX_ASUS_MOBO] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
/* enable 5.1 and SPDIF out */
{ 0x0c, 0x01014411 },
{ 0x0d, 0x01014410 },
{ 0x0e, 0x01014412 },
{ 0x22, 0x014b1180 },
{ }
}
},
}; };
static const struct hda_model_fixup stac92hd73xx_models[] = { static const struct hda_model_fixup stac92hd73xx_models[] = {
...@@ -1923,6 +1935,7 @@ static const struct hda_model_fixup stac92hd73xx_models[] = { ...@@ -1923,6 +1935,7 @@ static const struct hda_model_fixup stac92hd73xx_models[] = {
{ .id = STAC_DELL_M6_BOTH, .name = "dell-m6" }, { .id = STAC_DELL_M6_BOTH, .name = "dell-m6" },
{ .id = STAC_DELL_EQ, .name = "dell-eq" }, { .id = STAC_DELL_EQ, .name = "dell-eq" },
{ .id = STAC_ALIENWARE_M17X, .name = "alienware" }, { .id = STAC_ALIENWARE_M17X, .name = "alienware" },
{ .id = STAC_92HD73XX_ASUS_MOBO, .name = "asus-mobo" },
{} {}
}; };
...@@ -1975,6 +1988,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = { ...@@ -1975,6 +1988,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
"HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK), "HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK),
SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17, SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
"unknown HP", STAC_92HD89XX_HP_FRONT_JACK), "unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
SND_PCI_QUIRK(PCI_VENDOR_ID_ASUSTEK, 0x83f8, "ASUS AT4NM10",
STAC_92HD73XX_ASUS_MOBO),
{} /* terminator */ {} /* terminator */
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment