diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 6ed2b421e29e..675614dc2b88 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 1470ecc354db..aaece36247e7 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 b162fc40348f..36483f7dd3ce 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;