1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
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>
13 #include "ac97_core.h"
15 static void compat_ac97_release(struct device
*dev
)
17 kfree(to_ac97_t(dev
));
20 static void compat_ac97_reset(struct snd_ac97
*ac97
)
22 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
23 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
25 if (actrl
->ops
->reset
)
26 actrl
->ops
->reset(actrl
);
29 static void compat_ac97_warm_reset(struct snd_ac97
*ac97
)
31 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
32 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
34 if (actrl
->ops
->warm_reset
)
35 actrl
->ops
->warm_reset(actrl
);
38 static void compat_ac97_write(struct snd_ac97
*ac97
, unsigned short reg
,
41 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
42 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
44 actrl
->ops
->write(actrl
, ac97
->num
, reg
, val
);
47 static unsigned short compat_ac97_read(struct snd_ac97
*ac97
,
50 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
51 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
53 return actrl
->ops
->read(actrl
, ac97
->num
, reg
);
56 static const struct snd_ac97_bus_ops compat_snd_ac97_bus_ops
= {
57 .reset
= compat_ac97_reset
,
58 .warm_reset
= compat_ac97_warm_reset
,
59 .write
= compat_ac97_write
,
60 .read
= compat_ac97_read
,
63 static struct snd_ac97_bus compat_soc_ac97_bus
= {
64 .ops
= &compat_snd_ac97_bus_ops
,
67 struct snd_ac97
*snd_ac97_compat_alloc(struct ac97_codec_device
*adev
)
69 struct snd_ac97
*ac97
;
72 ac97
= kzalloc(sizeof(struct snd_ac97
), GFP_KERNEL
);
74 return ERR_PTR(-ENOMEM
);
76 ac97
->private_data
= adev
;
77 ac97
->bus
= &compat_soc_ac97_bus
;
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
);
84 put_device(&ac97
->dev
);
90 EXPORT_SYMBOL_GPL(snd_ac97_compat_alloc
);
92 void snd_ac97_compat_release(struct snd_ac97
*ac97
)
94 device_unregister(&ac97
->dev
);
96 EXPORT_SYMBOL_GPL(snd_ac97_compat_release
);
98 int snd_ac97_reset(struct snd_ac97
*ac97
, bool try_warm
, unsigned int id
,
101 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
102 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
103 unsigned int scanned
;
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
))
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
))
120 EXPORT_SYMBOL_GPL(snd_ac97_reset
);