Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
sound
soc
soc-io.c
Go to the documentation of this file.
1
/*
2
* soc-io.c -- ASoC register I/O helpers
3
*
4
* Copyright 2009-2011 Wolfson Microelectronics PLC.
5
*
6
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7
*
8
* This program is free software; you can redistribute it and/or modify it
9
* under the terms of the GNU General Public License as published by the
10
* Free Software Foundation; either version 2 of the License, or (at your
11
* option) any later version.
12
*/
13
14
#include <linux/i2c.h>
15
#include <
linux/spi/spi.h
>
16
#include <
linux/regmap.h
>
17
#include <linux/export.h>
18
#include <
sound/soc.h
>
19
20
#include <
trace/events/asoc.h
>
21
22
#ifdef CONFIG_REGMAP
23
static
int
hw_write(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
,
24
unsigned
int
value
)
25
{
26
int
ret
;
27
28
if
(!
snd_soc_codec_volatile_register
(codec, reg) &&
29
reg < codec->
driver
->reg_cache_size &&
30
!codec->
cache_bypass
) {
31
ret =
snd_soc_cache_write
(codec, reg, value);
32
if
(ret < 0)
33
return
-1;
34
}
35
36
if
(codec->
cache_only
) {
37
codec->
cache_sync
= 1;
38
return
0;
39
}
40
41
return
regmap_write
(codec->
control_data
, reg, value);
42
}
43
44
static
unsigned
int
hw_read(
struct
snd_soc_codec
*codec,
unsigned
int
reg)
45
{
46
int
ret
;
47
unsigned
int
val
;
48
49
if
(reg >= codec->
driver
->reg_cache_size ||
50
snd_soc_codec_volatile_register
(codec, reg) ||
51
codec->
cache_bypass
) {
52
if
(codec->
cache_only
)
53
return
-1;
54
55
ret =
regmap_read
(codec->
control_data
, reg, &val);
56
if
(ret == 0)
57
return
val
;
58
else
59
return
-1;
60
}
61
62
ret =
snd_soc_cache_read
(codec, reg, &val);
63
if
(ret < 0)
64
return
-1;
65
return
val
;
66
}
67
68
/* Primitive bulk write support for soc-cache. The data pointed to by
69
* `data' needs to already be in the form the hardware expects. Any
70
* data written through this function will not go through the cache as
71
* it only handles writing to volatile or out of bounds registers.
72
*
73
* This is currently only supported for devices using the regmap API
74
* wrappers.
75
*/
76
static
int
snd_soc_hw_bulk_write_raw(
struct
snd_soc_codec
*codec,
77
unsigned
int
reg,
78
const
void
*
data
,
size_t
len)
79
{
80
/* To ensure that we don't get out of sync with the cache, check
81
* whether the base register is volatile or if we've directly asked
82
* to bypass the cache. Out of bounds registers are considered
83
* volatile.
84
*/
85
if
(!codec->
cache_bypass
86
&& !
snd_soc_codec_volatile_register
(codec, reg)
87
&&
reg < codec->
driver
->reg_cache_size)
88
return
-
EINVAL
;
89
90
return
regmap_raw_write
(codec->
control_data
, reg, data, len);
91
}
92
112
int
snd_soc_codec_set_cache_io
(
struct
snd_soc_codec
*codec,
113
int
addr_bits,
int
data_bits,
114
enum
snd_soc_control_type
control
)
115
{
116
struct
regmap_config
config
;
117
int
ret
;
118
119
memset
(&
config
, 0,
sizeof
(
config
));
120
codec->
write
= hw_write;
121
codec->
read
= hw_read;
122
codec->
bulk_write_raw
= snd_soc_hw_bulk_write_raw;
123
124
config
.reg_bits = addr_bits;
125
config
.val_bits = data_bits;
126
127
switch
(control) {
128
#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
129
case
SND_SOC_I2C
:
130
codec->
control_data
=
regmap_init_i2c
(
to_i2c_client
(codec->
dev
),
131
&
config
);
132
break
;
133
#endif
134
135
#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
136
case
SND_SOC_SPI
:
137
codec->
control_data
=
regmap_init_spi
(to_spi_device(codec->
dev
),
138
&
config
);
139
break
;
140
#endif
141
142
case
SND_SOC_REGMAP
:
143
/* Device has made its own regmap arrangements */
144
codec->
using_regmap
=
true
;
145
if
(!codec->
control_data
)
146
codec->
control_data
=
dev_get_regmap
(codec->
dev
,
NULL
);
147
148
if
(codec->
control_data
) {
149
ret =
regmap_get_val_bytes
(codec->
control_data
);
150
/* Errors are legitimate for non-integer byte
151
* multiples */
152
if
(ret > 0)
153
codec->
val_bytes
=
ret
;
154
}
155
break
;
156
157
default
:
158
return
-
EINVAL
;
159
}
160
161
if
(IS_ERR(codec->
control_data
))
162
return
PTR_ERR(codec->
control_data
);
163
164
return
0;
165
}
166
EXPORT_SYMBOL_GPL
(
snd_soc_codec_set_cache_io
);
167
#else
168
int
snd_soc_codec_set_cache_io
(
struct
snd_soc_codec
*codec,
169
int
addr_bits,
int
data_bits,
170
enum
snd_soc_control_type
control)
171
{
172
return
-
ENOTSUPP
;
173
}
174
EXPORT_SYMBOL_GPL
(
snd_soc_codec_set_cache_io
);
175
#endif
Generated on Thu Jan 10 2013 15:08:33 for Linux Kernel by
1.8.2