X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=sound%2Fpci%2Fhda%2Fhda_codec.c;h=8820faf6c9d82cd556c7de92ec55cb11efa56ebd;hp=77385de01744fe96fd1b062ee4343106e2a179d0;hb=b5025c50b5e817b3e509ad7e569f131b80d7c223;hpb=20e91c575088337cb94f2ed48380efc305dcb81d diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 77385de01744..263d124de611 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -158,6 +158,39 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, return val; } +/* + * Send and receive a verb + */ +static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, + unsigned int *res) +{ + struct hda_bus *bus = codec->bus; + int err; + + if (res) + *res = -1; + again: + snd_hda_power_up(codec); + mutex_lock(&bus->cmd_mutex); + err = bus->ops.command(bus, cmd); + if (!err && res) + *res = bus->ops.get_response(bus); + mutex_unlock(&bus->cmd_mutex); + snd_hda_power_down(codec); + if (res && *res == -1 && bus->rirb_error) { + if (bus->response_reset) { + snd_printd("hda_codec: resetting BUS due to " + "fatal communication error\n"); + bus->ops.bus_reset(bus); + } + goto again; + } + /* clear reset-flag when the communication gets recovered */ + if (!err) + bus->response_reset = 0; + return err; +} + /** * snd_hda_codec_read - send a command and get the response * @codec: the HDA codec @@ -174,27 +207,9 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm) { - struct hda_bus *bus = codec->bus; - unsigned int cmd, res; - int repeated = 0; - - cmd = make_codec_cmd(codec, nid, direct, verb, parm); - snd_hda_power_up(codec); - mutex_lock(&bus->cmd_mutex); - again: - if (!bus->ops.command(bus, cmd)) { - res = bus->ops.get_response(bus); - if (res == -1 && bus->rirb_error) { - if (repeated++ < 1) { - snd_printd(KERN_WARNING "hda_codec: " - "Trying verb 0x%08x again\n", cmd); - goto again; - } - } - } else - res = (unsigned int)-1; - mutex_unlock(&bus->cmd_mutex); - snd_hda_power_down(codec); + unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm); + unsigned int res; + codec_exec_verb(codec, cmd, &res); return res; } EXPORT_SYMBOL_HDA(snd_hda_codec_read); @@ -214,17 +229,10 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_read); int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm) { - struct hda_bus *bus = codec->bus; + unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm); unsigned int res; - int err; - - res = make_codec_cmd(codec, nid, direct, verb, parm); - snd_hda_power_up(codec); - mutex_lock(&bus->cmd_mutex); - err = bus->ops.command(bus, res); - mutex_unlock(&bus->cmd_mutex); - snd_hda_power_down(codec); - return err; + return codec_exec_verb(codec, cmd, + codec->bus->sync_write ? &res : NULL); } EXPORT_SYMBOL_HDA(snd_hda_codec_write); @@ -877,7 +885,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, * Returns 0 if successful, or a negative error code. */ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, - int do_init, struct hda_codec **codecp) + struct hda_codec **codecp) { struct hda_codec *codec; char component[31]; @@ -964,19 +972,12 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_SUBSYSTEM_ID, 0); } - if (bus->modelname) - codec->modelname = kstrdup(bus->modelname, GFP_KERNEL); /* power-up all before initialization */ hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); - if (do_init) { - err = snd_hda_codec_configure(codec); - if (err < 0) - goto error; - } snd_hda_codec_proc_new(codec); snd_hda_create_hwdep(codec); @@ -1030,6 +1031,7 @@ int snd_hda_codec_configure(struct hda_codec *codec) err = init_unsol_queue(codec->bus); return err; } +EXPORT_SYMBOL_HDA(snd_hda_codec_configure); /** * snd_hda_codec_setup_stream - set up the codec for streaming @@ -2281,28 +2283,22 @@ EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, int direct, unsigned int verb, unsigned int parm) { - struct hda_bus *bus = codec->bus; - unsigned int res; - int err; + int err = snd_hda_codec_write(codec, nid, direct, verb, parm); + struct hda_cache_head *c; + u32 key; - res = make_codec_cmd(codec, nid, direct, verb, parm); - snd_hda_power_up(codec); - mutex_lock(&bus->cmd_mutex); - err = bus->ops.command(bus, res); - if (!err) { - struct hda_cache_head *c; - u32 key; - /* parm may contain the verb stuff for get/set amp */ - verb = verb | (parm >> 8); - parm &= 0xff; - key = build_cmd_cache_key(nid, verb); - c = get_alloc_hash(&codec->cmd_cache, key); - if (c) - c->val = parm; - } - mutex_unlock(&bus->cmd_mutex); - snd_hda_power_down(codec); - return err; + if (err < 0) + return err; + /* parm may contain the verb stuff for get/set amp */ + verb = verb | (parm >> 8); + parm &= 0xff; + key = build_cmd_cache_key(nid, verb); + mutex_lock(&codec->bus->cmd_mutex); + c = get_alloc_hash(&codec->cmd_cache, key); + if (c) + c->val = parm; + mutex_unlock(&codec->bus->cmd_mutex); + return 0; } EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); @@ -2694,11 +2690,11 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, bps = 20; } } - else if (streams == AC_SUPFMT_FLOAT32) { - /* should be exclusive */ + if (streams & AC_SUPFMT_FLOAT32) { formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; bps = 32; - } else if (streams == AC_SUPFMT_AC3) { + } + if (streams == AC_SUPFMT_AC3) { /* should be exclusive */ /* temporary hack: we have still no proper support * for the direct AC3 stream... @@ -3885,11 +3881,10 @@ EXPORT_SYMBOL_HDA(auto_pin_cfg_labels); /** * snd_hda_suspend - suspend the codecs * @bus: the HDA bus - * @state: suspsend state * * Returns 0 if successful. */ -int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) +int snd_hda_suspend(struct hda_bus *bus) { struct hda_codec *codec;