0001
0002
0003
0004
0005
0006 #include <linux/list.h>
0007 #include <linux/slab.h>
0008 #include <sound/ac97/codec.h>
0009 #include <sound/ac97/compat.h>
0010 #include <sound/ac97/controller.h>
0011 #include <sound/soc.h>
0012
0013 #include "ac97_core.h"
0014
0015 static void compat_ac97_release(struct device *dev)
0016 {
0017 kfree(to_ac97_t(dev));
0018 }
0019
0020 static void compat_ac97_reset(struct snd_ac97 *ac97)
0021 {
0022 struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
0023 struct ac97_controller *actrl = adev->ac97_ctrl;
0024
0025 if (actrl->ops->reset)
0026 actrl->ops->reset(actrl);
0027 }
0028
0029 static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
0030 {
0031 struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
0032 struct ac97_controller *actrl = adev->ac97_ctrl;
0033
0034 if (actrl->ops->warm_reset)
0035 actrl->ops->warm_reset(actrl);
0036 }
0037
0038 static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
0039 unsigned short val)
0040 {
0041 struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
0042 struct ac97_controller *actrl = adev->ac97_ctrl;
0043
0044 actrl->ops->write(actrl, ac97->num, reg, val);
0045 }
0046
0047 static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
0048 unsigned short reg)
0049 {
0050 struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
0051 struct ac97_controller *actrl = adev->ac97_ctrl;
0052
0053 return actrl->ops->read(actrl, ac97->num, reg);
0054 }
0055
0056 static const struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
0057 .reset = compat_ac97_reset,
0058 .warm_reset = compat_ac97_warm_reset,
0059 .write = compat_ac97_write,
0060 .read = compat_ac97_read,
0061 };
0062
0063 static struct snd_ac97_bus compat_soc_ac97_bus = {
0064 .ops = &compat_snd_ac97_bus_ops,
0065 };
0066
0067 struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev)
0068 {
0069 struct snd_ac97 *ac97;
0070 int ret;
0071
0072 ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
0073 if (ac97 == NULL)
0074 return ERR_PTR(-ENOMEM);
0075
0076 ac97->private_data = adev;
0077 ac97->bus = &compat_soc_ac97_bus;
0078
0079 ac97->dev.parent = &adev->dev;
0080 ac97->dev.release = compat_ac97_release;
0081 dev_set_name(&ac97->dev, "%s-compat", dev_name(&adev->dev));
0082 ret = device_register(&ac97->dev);
0083 if (ret) {
0084 put_device(&ac97->dev);
0085 return ERR_PTR(ret);
0086 }
0087
0088 return ac97;
0089 }
0090 EXPORT_SYMBOL_GPL(snd_ac97_compat_alloc);
0091
0092 void snd_ac97_compat_release(struct snd_ac97 *ac97)
0093 {
0094 device_unregister(&ac97->dev);
0095 }
0096 EXPORT_SYMBOL_GPL(snd_ac97_compat_release);
0097
0098 int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
0099 unsigned int id_mask)
0100 {
0101 struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
0102 struct ac97_controller *actrl = adev->ac97_ctrl;
0103 unsigned int scanned;
0104
0105 if (try_warm) {
0106 compat_ac97_warm_reset(ac97);
0107 scanned = snd_ac97_bus_scan_one(actrl, adev->num);
0108 if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
0109 return 1;
0110 }
0111
0112 compat_ac97_reset(ac97);
0113 compat_ac97_warm_reset(ac97);
0114 scanned = snd_ac97_bus_scan_one(actrl, adev->num);
0115 if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
0116 return 0;
0117
0118 return -ENODEV;
0119 }
0120 EXPORT_SYMBOL_GPL(snd_ac97_reset);