xref: /openbmc/linux/sound/ac97/snd_ac97_compat.c (revision 8dd06ef34b6e2f41b29fbf5fc1663780f2524285)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
274426fbfSRobert Jarzmik /*
374426fbfSRobert Jarzmik  *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
474426fbfSRobert Jarzmik  */
574426fbfSRobert Jarzmik 
674426fbfSRobert Jarzmik #include <linux/list.h>
774426fbfSRobert Jarzmik #include <linux/slab.h>
874426fbfSRobert Jarzmik #include <sound/ac97/codec.h>
974426fbfSRobert Jarzmik #include <sound/ac97/compat.h>
1074426fbfSRobert Jarzmik #include <sound/ac97/controller.h>
1174426fbfSRobert Jarzmik #include <sound/soc.h>
1274426fbfSRobert Jarzmik 
1374426fbfSRobert Jarzmik #include "ac97_core.h"
1474426fbfSRobert Jarzmik 
compat_ac97_release(struct device * dev)15c7b81707SLihua Yao static void compat_ac97_release(struct device *dev)
16c7b81707SLihua Yao {
17c7b81707SLihua Yao 	kfree(to_ac97_t(dev));
18c7b81707SLihua Yao }
19c7b81707SLihua Yao 
compat_ac97_reset(struct snd_ac97 * ac97)2074426fbfSRobert Jarzmik static void compat_ac97_reset(struct snd_ac97 *ac97)
2174426fbfSRobert Jarzmik {
2274426fbfSRobert Jarzmik 	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
2374426fbfSRobert Jarzmik 	struct ac97_controller *actrl = adev->ac97_ctrl;
2474426fbfSRobert Jarzmik 
2574426fbfSRobert Jarzmik 	if (actrl->ops->reset)
2674426fbfSRobert Jarzmik 		actrl->ops->reset(actrl);
2774426fbfSRobert Jarzmik }
2874426fbfSRobert Jarzmik 
compat_ac97_warm_reset(struct snd_ac97 * ac97)2974426fbfSRobert Jarzmik static void compat_ac97_warm_reset(struct snd_ac97 *ac97)
3074426fbfSRobert Jarzmik {
3174426fbfSRobert Jarzmik 	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
3274426fbfSRobert Jarzmik 	struct ac97_controller *actrl = adev->ac97_ctrl;
3374426fbfSRobert Jarzmik 
3474426fbfSRobert Jarzmik 	if (actrl->ops->warm_reset)
3574426fbfSRobert Jarzmik 		actrl->ops->warm_reset(actrl);
3674426fbfSRobert Jarzmik }
3774426fbfSRobert Jarzmik 
compat_ac97_write(struct snd_ac97 * ac97,unsigned short reg,unsigned short val)3874426fbfSRobert Jarzmik static void compat_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
3974426fbfSRobert Jarzmik 			      unsigned short val)
4074426fbfSRobert Jarzmik {
4174426fbfSRobert Jarzmik 	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
4274426fbfSRobert Jarzmik 	struct ac97_controller *actrl = adev->ac97_ctrl;
4374426fbfSRobert Jarzmik 
4474426fbfSRobert Jarzmik 	actrl->ops->write(actrl, ac97->num, reg, val);
4574426fbfSRobert Jarzmik }
4674426fbfSRobert Jarzmik 
compat_ac97_read(struct snd_ac97 * ac97,unsigned short reg)4774426fbfSRobert Jarzmik static unsigned short compat_ac97_read(struct snd_ac97 *ac97,
4874426fbfSRobert Jarzmik 				       unsigned short reg)
4974426fbfSRobert Jarzmik {
5074426fbfSRobert Jarzmik 	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
5174426fbfSRobert Jarzmik 	struct ac97_controller *actrl = adev->ac97_ctrl;
5274426fbfSRobert Jarzmik 
5374426fbfSRobert Jarzmik 	return actrl->ops->read(actrl, ac97->num, reg);
5474426fbfSRobert Jarzmik }
5574426fbfSRobert Jarzmik 
56*33c83aafSTakashi Iwai static const struct snd_ac97_bus_ops compat_snd_ac97_bus_ops = {
5774426fbfSRobert Jarzmik 	.reset = compat_ac97_reset,
5874426fbfSRobert Jarzmik 	.warm_reset = compat_ac97_warm_reset,
5974426fbfSRobert Jarzmik 	.write = compat_ac97_write,
6074426fbfSRobert Jarzmik 	.read = compat_ac97_read,
6174426fbfSRobert Jarzmik };
6274426fbfSRobert Jarzmik 
6374426fbfSRobert Jarzmik static struct snd_ac97_bus compat_soc_ac97_bus = {
6474426fbfSRobert Jarzmik 	.ops = &compat_snd_ac97_bus_ops,
6574426fbfSRobert Jarzmik };
6674426fbfSRobert Jarzmik 
snd_ac97_compat_alloc(struct ac97_codec_device * adev)6774426fbfSRobert Jarzmik struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev)
6874426fbfSRobert Jarzmik {
6974426fbfSRobert Jarzmik 	struct snd_ac97 *ac97;
70c7b81707SLihua Yao 	int ret;
7174426fbfSRobert Jarzmik 
7274426fbfSRobert Jarzmik 	ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
7374426fbfSRobert Jarzmik 	if (ac97 == NULL)
7474426fbfSRobert Jarzmik 		return ERR_PTR(-ENOMEM);
7574426fbfSRobert Jarzmik 
7674426fbfSRobert Jarzmik 	ac97->private_data = adev;
7774426fbfSRobert Jarzmik 	ac97->bus = &compat_soc_ac97_bus;
78c7b81707SLihua Yao 
79c7b81707SLihua Yao 	ac97->dev.parent = &adev->dev;
80c7b81707SLihua Yao 	ac97->dev.release = compat_ac97_release;
81c7b81707SLihua Yao 	dev_set_name(&ac97->dev, "%s-compat", dev_name(&adev->dev));
82c7b81707SLihua Yao 	ret = device_register(&ac97->dev);
83c7b81707SLihua Yao 	if (ret) {
84c7b81707SLihua Yao 		put_device(&ac97->dev);
85c7b81707SLihua Yao 		return ERR_PTR(ret);
86c7b81707SLihua Yao 	}
87c7b81707SLihua Yao 
8874426fbfSRobert Jarzmik 	return ac97;
8974426fbfSRobert Jarzmik }
9074426fbfSRobert Jarzmik EXPORT_SYMBOL_GPL(snd_ac97_compat_alloc);
9174426fbfSRobert Jarzmik 
snd_ac97_compat_release(struct snd_ac97 * ac97)9274426fbfSRobert Jarzmik void snd_ac97_compat_release(struct snd_ac97 *ac97)
9374426fbfSRobert Jarzmik {
94c7b81707SLihua Yao 	device_unregister(&ac97->dev);
9574426fbfSRobert Jarzmik }
9674426fbfSRobert Jarzmik EXPORT_SYMBOL_GPL(snd_ac97_compat_release);
9774426fbfSRobert Jarzmik 
snd_ac97_reset(struct snd_ac97 * ac97,bool try_warm,unsigned int id,unsigned int id_mask)9874426fbfSRobert Jarzmik int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
9974426fbfSRobert Jarzmik 	unsigned int id_mask)
10074426fbfSRobert Jarzmik {
10174426fbfSRobert Jarzmik 	struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
10274426fbfSRobert Jarzmik 	struct ac97_controller *actrl = adev->ac97_ctrl;
10374426fbfSRobert Jarzmik 	unsigned int scanned;
10474426fbfSRobert Jarzmik 
10574426fbfSRobert Jarzmik 	if (try_warm) {
10674426fbfSRobert Jarzmik 		compat_ac97_warm_reset(ac97);
10774426fbfSRobert Jarzmik 		scanned = snd_ac97_bus_scan_one(actrl, adev->num);
10874426fbfSRobert Jarzmik 		if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
10974426fbfSRobert Jarzmik 			return 1;
11074426fbfSRobert Jarzmik 	}
11174426fbfSRobert Jarzmik 
11274426fbfSRobert Jarzmik 	compat_ac97_reset(ac97);
11374426fbfSRobert Jarzmik 	compat_ac97_warm_reset(ac97);
11474426fbfSRobert Jarzmik 	scanned = snd_ac97_bus_scan_one(actrl, adev->num);
11574426fbfSRobert Jarzmik 	if (ac97_ids_match(scanned, adev->vendor_id, id_mask))
11674426fbfSRobert Jarzmik 		return 0;
11774426fbfSRobert Jarzmik 
11874426fbfSRobert Jarzmik 	return -ENODEV;
11974426fbfSRobert Jarzmik }
12074426fbfSRobert Jarzmik EXPORT_SYMBOL_GPL(snd_ac97_reset);
121