2 * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/list.h>
10 #include <linux/slab.h>
11 #include <sound/ac97/codec.h>
12 #include <sound/ac97/compat.h>
13 #include <sound/ac97/controller.h>
14 #include <sound/soc.h>
16 #include "ac97_core.h"
18 static void compat_ac97_release(struct device
*dev
)
20 kfree(to_ac97_t(dev
));
23 static void compat_ac97_reset(struct snd_ac97
*ac97
)
25 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
26 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
28 if (actrl
->ops
->reset
)
29 actrl
->ops
->reset(actrl
);
32 static void compat_ac97_warm_reset(struct snd_ac97
*ac97
)
34 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
35 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
37 if (actrl
->ops
->warm_reset
)
38 actrl
->ops
->warm_reset(actrl
);
41 static void compat_ac97_write(struct snd_ac97
*ac97
, unsigned short reg
,
44 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
45 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
47 actrl
->ops
->write(actrl
, ac97
->num
, reg
, val
);
50 static unsigned short compat_ac97_read(struct snd_ac97
*ac97
,
53 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
54 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
56 return actrl
->ops
->read(actrl
, ac97
->num
, reg
);
59 static struct snd_ac97_bus_ops compat_snd_ac97_bus_ops
= {
60 .reset
= compat_ac97_reset
,
61 .warm_reset
= compat_ac97_warm_reset
,
62 .write
= compat_ac97_write
,
63 .read
= compat_ac97_read
,
66 static struct snd_ac97_bus compat_soc_ac97_bus
= {
67 .ops
= &compat_snd_ac97_bus_ops
,
70 struct snd_ac97
*snd_ac97_compat_alloc(struct ac97_codec_device
*adev
)
72 struct snd_ac97
*ac97
;
75 ac97
= kzalloc(sizeof(struct snd_ac97
), GFP_KERNEL
);
77 return ERR_PTR(-ENOMEM
);
79 ac97
->private_data
= adev
;
80 ac97
->bus
= &compat_soc_ac97_bus
;
82 ac97
->dev
.parent
= &adev
->dev
;
83 ac97
->dev
.release
= compat_ac97_release
;
84 dev_set_name(&ac97
->dev
, "%s-compat", dev_name(&adev
->dev
));
85 ret
= device_register(&ac97
->dev
);
87 put_device(&ac97
->dev
);
93 EXPORT_SYMBOL_GPL(snd_ac97_compat_alloc
);
95 void snd_ac97_compat_release(struct snd_ac97
*ac97
)
97 device_unregister(&ac97
->dev
);
99 EXPORT_SYMBOL_GPL(snd_ac97_compat_release
);
101 int snd_ac97_reset(struct snd_ac97
*ac97
, bool try_warm
, unsigned int id
,
102 unsigned int id_mask
)
104 struct ac97_codec_device
*adev
= to_ac97_device(ac97
->private_data
);
105 struct ac97_controller
*actrl
= adev
->ac97_ctrl
;
106 unsigned int scanned
;
109 compat_ac97_warm_reset(ac97
);
110 scanned
= snd_ac97_bus_scan_one(actrl
, adev
->num
);
111 if (ac97_ids_match(scanned
, adev
->vendor_id
, id_mask
))
115 compat_ac97_reset(ac97
);
116 compat_ac97_warm_reset(ac97
);
117 scanned
= snd_ac97_bus_scan_one(actrl
, adev
->num
);
118 if (ac97_ids_match(scanned
, adev
->vendor_id
, id_mask
))
123 EXPORT_SYMBOL_GPL(snd_ac97_reset
);