]>
Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
74426fbf RJ |
2 | /* |
3 | * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr> | |
74426fbf RJ |
4 | */ |
5 | ||
6 | #include <linux/list.h> | |
7 | #include <linux/slab.h> | |
8 | #include <sound/ac97/codec.h> | |
9 | #include <sound/ac97/compat.h> | |
10 | #include <sound/ac97/controller.h> | |
11 | #include <sound/soc.h> | |
12 | ||
13 | #include "ac97_core.h" | |
14 | ||
c7b81707 LY |
15 | static void compat_ac97_release(struct device *dev) |
16 | { | |
17 | kfree(to_ac97_t(dev)); | |
18 | } | |
19 | ||
74426fbf RJ |
20 | static void compat_ac97_reset(struct snd_ac97 *ac97) |
21 | { | |
22 | struct ac97_codec_device *adev = to_ac97_device(ac97->private_data); | |
23 | struct ac97_controller *actrl = adev->ac97_ctrl; | |
24 | ||
25 | if (actrl->ops->reset) | |
26 | actrl->ops->reset(actrl); | |
27 | } | |
28 | ||
29 | static void compat_ac97_warm_reset(struct snd_ac97 *ac97) | |
30 | { | |
31 | struct ac97_codec_device *adev = to_ac97_device(ac97->private_data); | |
32 | struct ac97_controller *actrl = adev->ac97_ctrl; | |
33 | ||
34 | if (actrl->ops->warm_reset) | |
35 | actrl->ops->warm_reset(actrl); | |
36 | } | |
37 | ||
38 | static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |
39 | unsigned short val) | |
40 | { | |
41 | struct ac97_codec_device *adev = to_ac97_device(ac97->private_data); | |
42 | struct ac97_controller *actrl = adev->ac97_ctrl; | |
43 | ||
44 | actrl->ops->write(actrl, ac97->num, reg, val); | |
45 | } | |
46 | ||
47 | static unsigned short compat_ac97_read(struct snd_ac97 *ac97, | |
48 | unsigned short reg) | |
49 | { | |
50 | struct ac97_codec_device *adev = to_ac97_device(ac97->private_data); | |
51 | struct ac97_controller *actrl = adev->ac97_ctrl; | |
52 | ||
53 | return actrl->ops->read(actrl, ac97->num, reg); | |
54 | } | |
55 | ||
33c83aaf | 56 | static const struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = { |
74426fbf RJ |
57 | .reset = compat_ac97_reset, |
58 | .warm_reset = compat_ac97_warm_reset, | |
59 | .write = compat_ac97_write, | |
60 | .read = compat_ac97_read, | |
61 | }; | |
62 | ||
63 | static struct snd_ac97_bus compat_soc_ac97_bus = { | |
64 | .ops = &compat_snd_ac97_bus_ops, | |
65 | }; | |
66 | ||
67 | struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev) | |
68 | { | |
69 | struct snd_ac97 *ac97; | |
c7b81707 | 70 | int ret; |
74426fbf RJ |
71 | |
72 | ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); | |
73 | if (ac97 == NULL) | |
74 | return ERR_PTR(-ENOMEM); | |
75 | ||
74426fbf RJ |
76 | ac97->private_data = adev; |
77 | ac97->bus = &compat_soc_ac97_bus; | |
c7b81707 LY |
78 | |
79 | ac97->dev.parent = &adev->dev; | |
80 | ac97->dev.release = compat_ac97_release; | |
81 | dev_set_name(&ac97->dev, "%s-compat", dev_name(&adev->dev)); | |
82 | ret = device_register(&ac97->dev); | |
83 | if (ret) { | |
84 | put_device(&ac97->dev); | |
85 | return ERR_PTR(ret); | |
86 | } | |
87 | ||
74426fbf RJ |
88 | return ac97; |
89 | } | |
90 | EXPORT_SYMBOL_GPL(snd_ac97_compat_alloc); | |
91 | ||
92 | void snd_ac97_compat_release(struct snd_ac97 *ac97) | |
93 | { | |
c7b81707 | 94 | device_unregister(&ac97->dev); |
74426fbf RJ |
95 | } |
96 | EXPORT_SYMBOL_GPL(snd_ac97_compat_release); | |
97 | ||
98 | int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id, | |
99 | unsigned int id_mask) | |
100 | { | |
101 | struct ac97_codec_device *adev = to_ac97_device(ac97->private_data); | |
102 | struct ac97_controller *actrl = adev->ac97_ctrl; | |
103 | unsigned int scanned; | |
104 | ||
105 | if (try_warm) { | |
106 | compat_ac97_warm_reset(ac97); | |
107 | scanned = snd_ac97_bus_scan_one(actrl, adev->num); | |
108 | if (ac97_ids_match(scanned, adev->vendor_id, id_mask)) | |
109 | return 1; | |
110 | } | |
111 | ||
112 | compat_ac97_reset(ac97); | |
113 | compat_ac97_warm_reset(ac97); | |
114 | scanned = snd_ac97_bus_scan_one(actrl, adev->num); | |
115 | if (ac97_ids_match(scanned, adev->vendor_id, id_mask)) | |
116 | return 0; | |
117 | ||
118 | return -ENODEV; | |
119 | } | |
120 | EXPORT_SYMBOL_GPL(snd_ac97_reset); |