/*
* codec preset
- *
- * Known codecs have the patch to build and set up the controls/PCMs
- * better than the generic parser.
*/
-typedef int (*hda_codec_patch_t)(struct hda_codec *);
-
+
#define HDA_CODEC_ID_SKIP_PROBE 0x00000001
#define HDA_CODEC_ID_GENERIC_HDMI 0x00000101
#define HDA_CODEC_ID_GENERIC 0x00000201
#define HDA_CODEC_ID(_vid, _name) \
HDA_CODEC_ID_REV(_vid, 0, _name)
-/* old macros for patch_ops -- to be deprecated */
-#define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \
- { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
- .api_version = HDA_DEV_LEGACY, \
- .driver_data = (unsigned long)(_patch) }
-#define HDA_CODEC_ENTRY(_vid, _name, _patch) \
- HDA_CODEC_REV_ENTRY(_vid, 0, _name, _patch)
-
struct hda_codec_driver {
struct hdac_driver core;
const struct hda_device_id *id;
module_driver(drv, hda_codec_driver_register, \
hda_codec_driver_unregister)
-/* ops set by the preset patch */
+/* ops for hda codec driver */
struct hda_codec_ops {
int (*probe)(struct hda_codec *codec, const struct hda_device_id *id);
void (*remove)(struct hda_codec *codec);
int (*build_controls)(struct hda_codec *codec);
int (*build_pcms)(struct hda_codec *codec);
int (*init)(struct hda_codec *codec);
- void (*free)(struct hda_codec *codec);
void (*unsol_event)(struct hda_codec *codec, unsigned int res);
void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
unsigned int power_state);
const struct hda_device_id *preset;
const char *modelname; /* model name for preset */
- /* set by patch */
- struct hda_codec_ops patch_ops;
-
/* PCM to create, set by hda_codec_ops.build_pcms callback */
struct list_head pcm_list_head;
refcount_t pcm_ref;
if (driver->ops && driver->ops->check_power_status)
return driver->ops->check_power_status(codec, nid);
- else if (codec->patch_ops.check_power_status)
- return codec->patch_ops.check_power_status(codec, nid);
return 0;
}
obj-$(CONFIG_SND_HDA) += common/
obj-$(CONFIG_SND_HDA) += codecs/
# this must be the last entry after codec drivers;
-# otherwise the codec patches won't be hooked before the PCI probe
+# otherwise the codec drivers won't be hooked before the PCI probe
# when built in kernel
obj-$(CONFIG_SND_HDA) += controllers/
if (spec->power_down_unused || codec->power_save_node) {
if (!codec->power_filter)
codec->power_filter = snd_hda_gen_path_power_filter;
- if (!codec->patch_ops.stream_pm)
- codec->patch_ops.stream_pm = snd_hda_gen_stream_pm;
}
if (!spec->no_analog && spec->beep_nid) {
* the generic codec support
*/
-static const struct hda_codec_ops generic_patch_ops = {
- .build_controls = snd_hda_gen_build_controls,
- .build_pcms = snd_hda_gen_build_pcms,
- .init = snd_hda_gen_init,
- .free = snd_hda_gen_free,
- .unsol_event = snd_hda_jack_unsol_event,
- .check_power_status = snd_hda_gen_check_power_status,
-};
-
static int snd_hda_gen_probe(struct hda_codec *codec,
const struct hda_device_id *id)
{
if (err < 0)
goto error;
- codec->patch_ops = generic_patch_ops;
return 0;
error:
int snd_hda_gen_init(struct hda_codec *codec);
void snd_hda_gen_remove(struct hda_codec *codec);
-#define snd_hda_gen_free snd_hda_gen_remove
int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path);
struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx);
#endif
};
-/* operations used by generic code that can be overridden by patches */
+/* operations used by generic code that can be overridden by codec drivers */
struct hdmi_ops {
int (*pin_get_eld)(struct hda_codec *codec, hda_nid_t pin_nid,
int dev_id, unsigned char *buf, int *eld_size);
if (driver->ops && driver->ops->unsol_event)
driver->ops->unsol_event(codec, ev);
- else if (codec->patch_ops.unsol_event)
- codec->patch_ops.unsol_event(codec, ev);
}
/**
struct hda_codec *codec = dev_to_hda_codec(dev);
struct module *owner = dev->driver->owner;
struct hda_codec_driver *driver = hda_codec_to_driver(codec);
- hda_codec_patch_t patch;
int err;
if (codec->bus->core.ext_ops) {
goto error;
}
- if (driver->ops && driver->ops->probe) {
- err = driver->ops->probe(codec, codec->preset);
- if (err < 0)
- goto error_module_put;
- } else {
- patch = (hda_codec_patch_t)codec->preset->driver_data;
- if (patch) {
- err = patch(codec);
- if (err < 0)
- goto error_module_put;
- }
+ if (WARN_ON(!(driver->ops && driver->ops->probe))) {
+ err = -EINVAL;
+ goto error_module_put;
}
+ err = driver->ops->probe(codec, codec->preset);
+ if (err < 0)
+ goto error_module_put;
err = snd_hda_codec_build_pcms(codec);
if (err < 0)
goto error_module;
error_module:
if (driver->ops && driver->ops->remove)
driver->ops->remove(codec);
- else if (codec->patch_ops.free)
- codec->patch_ops.free(codec);
error_module_put:
module_put(owner);
if (driver->ops && driver->ops->remove)
driver->ops->remove(codec);
- else if (codec->patch_ops.free)
- codec->patch_ops.free(codec);
snd_hda_codec_cleanup_for_unbind(codec);
codec->preset = NULL;
module_put(dev->driver->owner);
* @codec: the HDA codec
*
* Start parsing of the given codec tree and (re-)initialize the whole
- * patch instance.
+ * codec driver binding.
*
* Returns 0 if successful or a negative error code.
*/
snd_hda_ctls_clear(codec);
codec_release_pcms(codec);
snd_hda_detach_beep_device(codec);
- memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
snd_hda_jack_tbl_clear(codec);
codec->proc_widget_hook = NULL;
codec->spec = NULL;
if (driver->ops && driver->ops->stream_pm)
driver->ops->stream_pm(codec, nid, true);
- else if (codec->patch_ops.stream_pm)
- codec->patch_ops.stream_pm(codec, nid, true);
if (codec->pcm_format_first)
update_pcm_format(codec, p, nid, format);
update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
q->nid = nid;
if (driver->ops && driver->ops->stream_pm)
driver->ops->stream_pm(codec, nid, false);
- else if (codec->patch_ops.stream_pm)
- codec->patch_ops.stream_pm(codec, nid, false);
}
/* clean up the all conflicting obsolete streams */
* @cvt_nid: converter NID
* @type: HDA_PCM_TYPE_*
* Creates controls related with the digital output.
- * Called from each patch supporting the digital out.
+ * Called from each codec driver supporting the digital out.
*
* Returns 0 if successful, or a negative error code.
*/
* @nid: audio in widget NID
*
* Creates controls related with the SPDIF input.
- * Called from each patch supporting the SPDIF in.
+ * Called from each codec driver supporting the SPDIF in.
*
* Returns 0 if successful, or a negative error code.
*/
/* might be called before binding to driver, too */
if (driver && driver->ops && driver->ops->set_power_state)
driver->ops->set_power_state(codec, fg, power_state);
- else if (codec->patch_ops.set_power_state)
- codec->patch_ops.set_power_state(codec, fg,
- power_state);
else {
state = power_state;
if (codec->power_filter)
snd_hdac_enter_pm(&codec->core);
if (driver->ops && driver->ops->suspend)
driver->ops->suspend(codec);
- else if (codec->patch_ops.suspend)
- codec->patch_ops.suspend(codec);
if (!codec->no_stream_clean_at_suspend)
hda_cleanup_all_streams(codec);
state = hda_set_power_state(codec, AC_PWRST_D3);
snd_hda_jack_set_dirty_all(codec);
if (driver->ops && driver->ops->resume)
driver->ops->resume(codec);
- else if (codec->patch_ops.resume)
- codec->patch_ops.resume(codec);
else {
snd_hda_codec_init(codec);
snd_hda_regmap_sync(codec);
if (!err) {
if (driver->ops && driver->ops->build_controls)
err = driver->ops->build_controls(codec);
- else if (codec->patch_ops.build_controls)
- err = codec->patch_ops.build_controls(codec);
if (err < 0)
return err;
}
if (driver->ops && driver->ops->build_pcms)
err = driver->ops->build_pcms(codec);
- else if (codec->patch_ops.build_pcms)
- err = codec->patch_ops.build_pcms(codec);
else
return 0;
if (driver->ops && driver->ops->init)
return driver->ops->init(codec);
- else if (codec->patch_ops.init)
- return codec->patch_ops.init(codec);
return 0;
}
struct hdac_device *hdev = &codec->core;
struct hdac_bus *bus = hdev->bus;
struct hdac_ext_link *hlink;
- hda_codec_patch_t patch;
int ret;
#ifdef CONFIG_PM
goto err;
}
- if (driver->ops && driver->ops->probe) {
- ret = driver->ops->probe(codec, codec->preset);
- } else {
- patch = (hda_codec_patch_t)codec->preset->driver_data;
- if (!patch) {
- dev_err(&hdev->dev, "no patch specified\n");
- ret = -EINVAL;
- goto err;
- }
-
- ret = patch(codec);
+ if (WARN_ON(!(driver->ops && driver->ops->probe))) {
+ ret = -EINVAL;
+ goto err;
}
+ ret = driver->ops->probe(codec, codec->preset);
if (ret < 0) {
dev_err(&hdev->dev, "codec init failed: %d\n", ret);
goto err;
parse_pcms_err:
if (driver->ops && driver->ops->remove)
driver->ops->remove(codec);
- else if (codec->patch_ops.free)
- codec->patch_ops.free(codec);
err:
snd_hda_codec_cleanup_for_unbind(codec);
device_new_err:
if (driver->ops && driver->ops->remove)
driver->ops->remove(codec);
- else if (codec->patch_ops.free)
- codec->patch_ops.free(codec);
snd_hda_codec_cleanup_for_unbind(codec);
pm_runtime_put_noidle(&hdev->dev);
struct hda_codec *hcodec = hda_pvt->codec;
struct hda_codec_driver *driver = hda_codec_to_driver(hcodec);
struct hdac_ext_link *hlink;
- hda_codec_patch_t patch;
int ret;
hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));
goto error_pm;
}
- if (driver->ops && driver->ops->probe) {
- ret = driver->ops->probe(hcodec, hcodec->preset);
- if (ret < 0) {
- dev_err(&hdev->dev, "%s: probe failed %d\n", __func__, ret);
- goto error_regmap;
- }
- } else {
- patch = (hda_codec_patch_t)hcodec->preset->driver_data;
- if (patch) {
- ret = patch(hcodec);
- if (ret < 0) {
- dev_err(&hdev->dev, "%s: patch failed %d\n", __func__, ret);
- goto error_regmap;
- }
- } else {
- dev_dbg(&hdev->dev, "%s: no patch file found\n", __func__);
- }
+ if (WARN_ON(!(driver->ops && driver->ops->probe))) {
+ ret = -EINVAL;
+ goto error_regmap;
+ }
+
+ ret = driver->ops->probe(hcodec, hcodec->preset);
+ if (ret < 0) {
+ dev_err(&hdev->dev, "%s: probe failed %d\n", __func__, ret);
+ goto error_regmap;
}
ret = snd_hda_codec_parse_pcms(hcodec);
error_patch:
if (driver->ops && driver->ops->remove)
driver->ops->remove(hcodec);
- else if (hcodec->patch_ops.free)
- hcodec->patch_ops.free(hcodec);
error_regmap:
snd_hdac_regmap_exit(hdev);
error_pm:
if (driver->ops && driver->ops->remove)
driver->ops->remove(codec);
- else if (codec->patch_ops.free)
- codec->patch_ops.free(codec);
snd_hda_codec_cleanup_for_unbind(codec);
}