#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/moduleparam.h>
-#include <linux/mutex.h>
#include <sound/core.h>
#include "hda_codec.h"
#include <sound/asoundef.h>
unsigned int verb, unsigned int parm)
{
unsigned int res;
- mutex_lock(&codec->bus->cmd_mutex);
+ down(&codec->bus->cmd_mutex);
if (! codec->bus->ops.command(codec, nid, direct, verb, parm))
res = codec->bus->ops.get_response(codec);
else
res = (unsigned int)-1;
- mutex_unlock(&codec->bus->cmd_mutex);
+ up(&codec->bus->cmd_mutex);
return res;
}
unsigned int verb, unsigned int parm)
{
int err;
- mutex_lock(&codec->bus->cmd_mutex);
+ down(&codec->bus->cmd_mutex);
err = codec->bus->ops.command(codec, nid, direct, verb, parm);
- mutex_unlock(&codec->bus->cmd_mutex);
+ up(&codec->bus->cmd_mutex);
return err;
}
snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
return -ENOMEM;
}
- unsol->workq = create_singlethread_workqueue("hda_codec");
+ unsol->workq = create_workqueue("hda_codec");
if (! unsol->workq) {
snd_printk(KERN_ERR "hda_codec: can't create workqueue\n");
kfree(unsol);
bus->modelname = temp->modelname;
bus->ops = temp->ops;
- mutex_init(&bus->cmd_mutex);
+ init_MUTEX(&bus->cmd_mutex);
INIT_LIST_HEAD(&bus->codec_list);
if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
codec->bus = bus;
codec->addr = codec_addr;
- mutex_init(&codec->spdif_mutex);
+ init_MUTEX(&codec->spdif_mutex);
init_amp_hash(codec);
list_add_tail(&codec->list, &bus->codec_list);
bus->caddr_tbl[codec_addr] = codec;
codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID);
- if (codec->vendor_id == -1)
- /* read again, hopefully the access method was corrected
- * in the last read...
- */
- codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
- AC_PAR_VENDOR_ID);
codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
/*
* read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
*/
-int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int index)
+static int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index)
{
struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
if (! info)
/*
* update the AMP value, mask = bit mask to set, val = the value
*/
-int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
- int direction, int idx, int mask, int val)
+static int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val)
{
struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
unsigned long pval;
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ down(&codec->spdif_mutex); /* reuse spdif_mutex */
pval = kcontrol->private_value;
kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
kcontrol->private_value = pval;
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return err;
}
unsigned long pval;
int i, indices, err = 0, change = 0;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ down(&codec->spdif_mutex); /* reuse spdif_mutex */
pval = kcontrol->private_value;
indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
for (i = 0; i < indices; i++) {
change |= err;
}
kcontrol->private_value = pval;
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return err < 0 ? err : change;
}
unsigned short val;
int change;
- mutex_lock(&codec->spdif_mutex);
+ down(&codec->spdif_mutex);
codec->spdif_status = ucontrol->value.iec958.status[0] |
((unsigned int)ucontrol->value.iec958.status[1] << 8) |
((unsigned int)ucontrol->value.iec958.status[2] << 16) |
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8);
}
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return change;
}
unsigned short val;
int change;
- mutex_lock(&codec->spdif_mutex);
+ down(&codec->spdif_mutex);
val = codec->spdif_ctls & ~1;
if (ucontrol->value.integer.value[0])
val |= 1;
AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));
}
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return change;
}
unsigned int val = !!ucontrol->value.integer.value[0];
int change;
- mutex_lock(&codec->spdif_mutex);
+ down(&codec->spdif_mutex);
change = codec->spdif_in_enable != val;
if (change || codec->in_resume) {
codec->spdif_in_enable = val;
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val);
}
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return change;
}
*/
int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout)
{
- mutex_lock(&codec->spdif_mutex);
+ down(&codec->spdif_mutex);
if (mout->dig_out_used) {
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return -EBUSY; /* already being used */
}
mout->dig_out_used = HDA_DIG_EXCLUSIVE;
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return 0;
}
*/
int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout)
{
- mutex_lock(&codec->spdif_mutex);
+ down(&codec->spdif_mutex);
mout->dig_out_used = 0;
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return 0;
}
int chs = substream->runtime->channels;
int i;
- mutex_lock(&codec->spdif_mutex);
+ down(&codec->spdif_mutex);
if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
if (chs == 2 &&
snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
}
}
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
/* front */
snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
if (mout->hp_nid)
/* headphone out will just decode front left/right (stereo) */
snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
- /* extra outputs copied from front */
- for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
- if (mout->extra_out_nid[i])
- snd_hda_codec_setup_stream(codec,
- mout->extra_out_nid[i],
- stream_tag, 0, format);
-
/* surrounds */
for (i = 1; i < mout->num_dacs; i++) {
if (chs >= (i + 1) * 2) /* independent out */
snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
if (mout->hp_nid)
snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0);
- for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
- if (mout->extra_out_nid[i])
- snd_hda_codec_setup_stream(codec,
- mout->extra_out_nid[i],
- 0, 0, 0);
- mutex_lock(&codec->spdif_mutex);
+ down(&codec->spdif_mutex);
if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
mout->dig_out_used = 0;
}
- mutex_unlock(&codec->spdif_mutex);
+ up(&codec->spdif_mutex);
return 0;
}
return 0;
}
-/*
- * Parse all pin widgets and store the useful pin nids to cfg
- *
- * The number of line-outs or any primary output is stored in line_outs,
- * and the corresponding output pins are assigned to line_out_pins[],
- * in the order of front, rear, CLFE, side, ...
- *
- * If more extra outputs (speaker and headphone) are found, the pins are
- * assisnged to hp_pin and speaker_pins[], respectively. If no line-out jack
- * is detected, one of speaker of HP pins is assigned as the primary
- * output, i.e. to line_out_pins[0]. So, line_outs is always positive
- * if any analog output exists.
- *
- * The analog input pins are assigned to input_pins array.
- * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
- * respectively.
- */
+/* parse all pin widgets and store the useful pin nids to cfg */
int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
hda_nid_t *ignore_nids)
{
hda_nid_t nid, nid_start;
int i, j, nodes;
- short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)];
+ short seq, sequences[4], assoc_line_out;
memset(cfg, 0, sizeof(*cfg));
cfg->line_outs++;
break;
case AC_JACK_SPEAKER:
- if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
- continue;
- cfg->speaker_pins[cfg->speaker_outs] = nid;
- cfg->speaker_outs++;
+ cfg->speaker_pin = nid;
break;
case AC_JACK_HP_OUT:
cfg->hp_pin = nid;
break;
}
- /*
- * debug prints of the parsed results
- */
- snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
- cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
- cfg->line_out_pins[2], cfg->line_out_pins[3],
- cfg->line_out_pins[4]);
- snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
- cfg->speaker_outs, cfg->speaker_pins[0],
- cfg->speaker_pins[1], cfg->speaker_pins[2],
- cfg->speaker_pins[3], cfg->speaker_pins[4]);
- snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n",
- cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin);
- snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
- " cd=0x%x, aux=0x%x\n",
- cfg->input_pins[AUTO_PIN_MIC],
- cfg->input_pins[AUTO_PIN_FRONT_MIC],
- cfg->input_pins[AUTO_PIN_LINE],
- cfg->input_pins[AUTO_PIN_FRONT_LINE],
- cfg->input_pins[AUTO_PIN_CD],
- cfg->input_pins[AUTO_PIN_AUX]);
-
- /*
- * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
- * as a primary output
- */
- if (! cfg->line_outs) {
- if (cfg->speaker_outs) {
- cfg->line_outs = cfg->speaker_outs;
- memcpy(cfg->line_out_pins, cfg->speaker_pins,
- sizeof(cfg->speaker_pins));
- cfg->speaker_outs = 0;
- memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
- } else if (cfg->hp_pin) {
- cfg->line_outs = 1;
- cfg->line_out_pins[0] = cfg->hp_pin;
- cfg->hp_pin = 0;
- }
- }
-
return 0;
}