brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 1484fc1 Raw
100 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Linux driver model AC97 bus interface4 *5 * Author:	Nicolas Pitre6 * Created:	Jan 14, 20057 * Copyright:	(C) MontaVista Software Inc.8 */9 10#include <linux/module.h>11#include <linux/init.h>12#include <linux/device.h>13#include <linux/string.h>14#include <sound/ac97_codec.h>15 16/*17 * snd_ac97_check_id() - Reads and checks the vendor ID of the device18 * @ac97: The AC97 device to check19 * @id: The ID to compare to20 * @id_mask: Mask that is applied to the device ID before comparing to @id21 *22 * If @id is 0 this function returns true if the read device vendor ID is23 * a valid ID. If @id is non 0 this functions returns true if @id24 * matches the read vendor ID. Otherwise the function returns false.25 */26static bool snd_ac97_check_id(struct snd_ac97 *ac97, unsigned int id,27	unsigned int id_mask)28{29	ac97->id = ac97->bus->ops->read(ac97, AC97_VENDOR_ID1) << 16;30	ac97->id |= ac97->bus->ops->read(ac97, AC97_VENDOR_ID2);31 32	if (ac97->id == 0x0 || ac97->id == 0xffffffff)33		return false;34 35	if (id != 0 && id != (ac97->id & id_mask))36		return false;37 38	return true;39}40 41/**42 * snd_ac97_reset() - Reset AC'97 device43 * @ac97: The AC'97 device to reset44 * @try_warm: Try a warm reset first45 * @id: Expected device vendor ID46 * @id_mask: Mask that is applied to the device ID before comparing to @id47 *48 * This function resets the AC'97 device. If @try_warm is true the function49 * first performs a warm reset. If the warm reset is successful the function50 * returns 1. Otherwise or if @try_warm is false the function issues cold reset51 * followed by a warm reset. If this is successful the function returns 0,52 * otherwise a negative error code. If @id is 0 any valid device ID will be53 * accepted, otherwise only the ID that matches @id and @id_mask is accepted.54 */55int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,56	unsigned int id_mask)57{58	const struct snd_ac97_bus_ops *ops = ac97->bus->ops;59 60	if (try_warm && ops->warm_reset) {61		ops->warm_reset(ac97);62		if (snd_ac97_check_id(ac97, id, id_mask))63			return 1;64	}65 66	if (ops->reset)67		ops->reset(ac97);68	if (ops->warm_reset)69		ops->warm_reset(ac97);70 71	if (snd_ac97_check_id(ac97, id, id_mask))72		return 0;73 74	return -ENODEV;75}76EXPORT_SYMBOL_GPL(snd_ac97_reset);77 78const struct bus_type ac97_bus_type = {79	.name		= "ac97",80};81 82static int __init ac97_bus_init(void)83{84	return bus_register(&ac97_bus_type);85}86 87subsys_initcall(ac97_bus_init);88 89static void __exit ac97_bus_exit(void)90{91	bus_unregister(&ac97_bus_type);92}93 94module_exit(ac97_bus_exit);95 96EXPORT_SYMBOL(ac97_bus_type);97 98MODULE_DESCRIPTION("Legacy AC97 bus interface");99MODULE_LICENSE("GPL");100