diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 6ed2b421e29ebfd87128576eec7a1de2076b3b19..675614dc2b8803ec0a2f76b3099bbdc2afa19f8d 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -48,6 +48,10 @@ struct hdac_device { const char *vendor_name; /* codec vendor name */ const char *chip_name; /* codec chip name */ + /* verb exec op override */ + int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, + unsigned int flags, unsigned int *res); + /* widgets */ unsigned int num_nodes; hda_nid_t start_nid, end_nid; @@ -82,6 +86,8 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec); unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid, unsigned int verb, unsigned int parm); +int snd_hdac_exec_verb(struct hdac_device *codec, unsigned int cmd, + unsigned int flags, unsigned int *res); int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid, unsigned int verb, unsigned int parm, unsigned int *res); int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm); diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 1470ecc354dbc11d37a281cb3954cc489dd060b3..aaece36247e772f126a86d7dae89c6eae4c6612b 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -193,6 +193,28 @@ unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid, } EXPORT_SYMBOL_GPL(snd_hdac_make_cmd); +/** + * snd_hdac_exec_verb - execute an encoded verb + * @codec: the codec object + * @cmd: encoded verb to execute + * @flags: optional flags, pass zero for default + * @res: the pointer to store the result, NULL if running async + * + * Returns zero if successful, or a negative error code. + * + * This calls the exec_verb op when set in hdac_codec. If not, + * call the default snd_hdac_bus_exec_verb(). + */ +int snd_hdac_exec_verb(struct hdac_device *codec, unsigned int cmd, + unsigned int flags, unsigned int *res) +{ + if (codec->exec_verb) + return codec->exec_verb(codec, cmd, flags, res); + return snd_hdac_bus_exec_verb(codec->bus, codec->addr, cmd, res); +} +EXPORT_SYMBOL_GPL(snd_hdac_exec_verb); + + /** * snd_hdac_read - execute a verb * @codec: the codec object @@ -208,7 +230,7 @@ int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid, { unsigned int cmd = snd_hdac_make_cmd(codec, nid, verb, parm); - return snd_hdac_bus_exec_verb(codec->bus, codec->addr, cmd, res); + return snd_hdac_exec_verb(codec, cmd, 0, res); } EXPORT_SYMBOL_GPL(snd_hdac_read); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b162fc40348f4aa8d02136be328a011508b1fc87..36483f7dd3ce7ed7cbfabc05202ca344fa8aedc7 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -124,11 +124,12 @@ const char *snd_hda_get_jack_type(u32 cfg) EXPORT_SYMBOL_GPL(snd_hda_get_jack_type); /* - * Send and receive a verb + * Send and receive a verb - passed to exec_verb override for hdac_device */ -static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, - int flags, unsigned int *res) +static int codec_exec_verb(struct hdac_device *dev, unsigned int cmd, + unsigned int flags, unsigned int *res) { + struct hda_codec *codec = container_of(dev, struct hda_codec, core); struct hda_bus *bus = codec->bus; int err; @@ -177,7 +178,7 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, { unsigned int cmd = snd_hdac_make_cmd(&codec->core, nid, verb, parm); unsigned int res; - if (codec_exec_verb(codec, cmd, flags, &res)) + if (snd_hdac_exec_verb(&codec->core, cmd, flags, &res)) return -1; return res; } @@ -199,7 +200,7 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags, unsigned int verb, unsigned int parm) { unsigned int cmd = snd_hdac_make_cmd(&codec->core, nid, verb, parm); - return codec_exec_verb(codec, cmd, flags, NULL); + return snd_hdac_exec_verb(&codec->core, cmd, flags, NULL); } EXPORT_SYMBOL_GPL(snd_hda_codec_write); @@ -1026,6 +1027,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, codec->core.dev.release = snd_hda_codec_dev_release; codec->core.type = HDA_DEV_LEGACY; + codec->core.exec_verb = codec_exec_verb; codec->bus = bus; codec->card = card;