1/*
2 * Register map access API - AC'97 support
3 *
4 * Copyright 2013 Linaro Ltd.  All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/init.h>
22#include <linux/io.h>
23#include <linux/module.h>
24#include <linux/regmap.h>
25#include <linux/slab.h>
26
27#include <sound/ac97_codec.h>
28
29bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg)
30{
31	switch (reg) {
32	case AC97_RESET:
33	case AC97_POWERDOWN:
34	case AC97_INT_PAGING:
35	case AC97_EXTENDED_ID:
36	case AC97_EXTENDED_STATUS:
37	case AC97_EXTENDED_MID:
38	case AC97_EXTENDED_MSTATUS:
39	case AC97_GPIO_STATUS:
40	case AC97_MISC_AFE:
41	case AC97_VENDOR_ID1:
42	case AC97_VENDOR_ID2:
43	case AC97_CODEC_CLASS_REV:
44	case AC97_PCI_SVID:
45	case AC97_PCI_SID:
46	case AC97_FUNC_SELECT:
47	case AC97_FUNC_INFO:
48	case AC97_SENSE_INFO:
49		return true;
50	default:
51		return false;
52	}
53}
54EXPORT_SYMBOL_GPL(regmap_ac97_default_volatile);
55
56static int regmap_ac97_reg_read(void *context, unsigned int reg,
57	unsigned int *val)
58{
59	struct snd_ac97 *ac97 = context;
60
61	*val = ac97->bus->ops->read(ac97, reg);
62
63	return 0;
64}
65
66static int regmap_ac97_reg_write(void *context, unsigned int reg,
67	unsigned int val)
68{
69	struct snd_ac97 *ac97 = context;
70
71	ac97->bus->ops->write(ac97, reg, val);
72
73	return 0;
74}
75
76static const struct regmap_bus ac97_regmap_bus = {
77	.reg_write = regmap_ac97_reg_write,
78	.reg_read = regmap_ac97_reg_read,
79};
80
81/**
82 * regmap_init_ac97(): Initialise AC'97 register map
83 *
84 * @ac97: Device that will be interacted with
85 * @config: Configuration for register map
86 *
87 * The return value will be an ERR_PTR() on error or a valid pointer to
88 * a struct regmap.
89 */
90struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
91				const struct regmap_config *config)
92{
93	return regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
94}
95EXPORT_SYMBOL_GPL(regmap_init_ac97);
96
97/**
98 * devm_regmap_init_ac97(): Initialise AC'97 register map
99 *
100 * @ac97: Device that will be interacted with
101 * @config: Configuration for register map
102 *
103 * The return value will be an ERR_PTR() on error or a valid pointer
104 * to a struct regmap.  The regmap will be automatically freed by the
105 * device management code.
106 */
107struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
108				     const struct regmap_config *config)
109{
110	return devm_regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
111}
112EXPORT_SYMBOL_GPL(devm_regmap_init_ac97);
113
114MODULE_LICENSE("GPL v2");
115