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
pci
oxygen
oxygen_io.c
Go to the documentation of this file.
1
/*
2
* C-Media CMI8788 driver - helper functions
3
*
4
* Copyright (c) Clemens Ladisch <
[email protected]
>
5
*
6
*
7
* This driver is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License, version 2.
9
*
10
* This driver is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this driver; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
*/
19
20
#include <
linux/delay.h
>
21
#include <linux/sched.h>
22
#include <linux/export.h>
23
#include <
sound/core.h
>
24
#include <
sound/mpu401.h
>
25
#include <asm/io.h>
26
#include "
oxygen.h
"
27
28
u8
oxygen_read8
(
struct
oxygen
*
chip
,
unsigned
int
reg
)
29
{
30
return
inb
(chip->
addr
+ reg);
31
}
32
EXPORT_SYMBOL
(
oxygen_read8
);
33
34
u16
oxygen_read16
(
struct
oxygen
*
chip
,
unsigned
int
reg
)
35
{
36
return
inw
(chip->
addr
+ reg);
37
}
38
EXPORT_SYMBOL
(
oxygen_read16
);
39
40
u32
oxygen_read32
(
struct
oxygen
*
chip
,
unsigned
int
reg
)
41
{
42
return
inl
(chip->
addr
+ reg);
43
}
44
EXPORT_SYMBOL
(
oxygen_read32
);
45
46
void
oxygen_write8
(
struct
oxygen
*
chip
,
unsigned
int
reg
,
u8
value
)
47
{
48
outb
(value, chip->
addr
+ reg);
49
chip->
saved_registers
.
_8
[
reg
] =
value
;
50
}
51
EXPORT_SYMBOL
(
oxygen_write8
);
52
53
void
oxygen_write16
(
struct
oxygen
*
chip
,
unsigned
int
reg
,
u16
value
)
54
{
55
outw
(value, chip->
addr
+ reg);
56
chip->
saved_registers
.
_16
[reg / 2] =
cpu_to_le16
(value);
57
}
58
EXPORT_SYMBOL
(
oxygen_write16
);
59
60
void
oxygen_write32
(
struct
oxygen
*
chip
,
unsigned
int
reg
,
u32
value
)
61
{
62
outl
(value, chip->
addr
+ reg);
63
chip->
saved_registers
.
_32
[reg / 4] =
cpu_to_le32
(value);
64
}
65
EXPORT_SYMBOL
(
oxygen_write32
);
66
67
void
oxygen_write8_masked
(
struct
oxygen
*
chip
,
unsigned
int
reg
,
68
u8
value
,
u8
mask
)
69
{
70
u8
tmp
=
inb
(chip->
addr
+ reg);
71
tmp &= ~mask;
72
tmp |= value &
mask
;
73
outb
(tmp, chip->
addr
+ reg);
74
chip->
saved_registers
.
_8
[
reg
] =
tmp
;
75
}
76
EXPORT_SYMBOL
(
oxygen_write8_masked
);
77
78
void
oxygen_write16_masked
(
struct
oxygen
*
chip
,
unsigned
int
reg
,
79
u16
value
,
u16
mask
)
80
{
81
u16
tmp
=
inw
(chip->
addr
+ reg);
82
tmp &= ~mask;
83
tmp |= value &
mask
;
84
outw
(tmp, chip->
addr
+ reg);
85
chip->
saved_registers
.
_16
[reg / 2] =
cpu_to_le16
(tmp);
86
}
87
EXPORT_SYMBOL
(
oxygen_write16_masked
);
88
89
void
oxygen_write32_masked
(
struct
oxygen
*
chip
,
unsigned
int
reg
,
90
u32
value
,
u32
mask
)
91
{
92
u32
tmp
=
inl
(chip->
addr
+ reg);
93
tmp &= ~mask;
94
tmp |= value &
mask
;
95
outl
(tmp, chip->
addr
+ reg);
96
chip->
saved_registers
.
_32
[reg / 4] =
cpu_to_le32
(tmp);
97
}
98
EXPORT_SYMBOL
(
oxygen_write32_masked
);
99
100
static
int
oxygen_ac97_wait(
struct
oxygen
*
chip
,
unsigned
int
mask
)
101
{
102
u8
status
= 0;
103
104
/*
105
* Reading the status register also clears the bits, so we have to save
106
* the read bits in status.
107
*/
108
wait_event_timeout
(chip->
ac97_waitqueue
,
109
({ status |=
oxygen_read8
(chip,
OXYGEN_AC97_INTERRUPT_STATUS
);
110
status &
mask
; }),
111
msecs_to_jiffies
(1) + 1);
112
/*
113
* Check even after a timeout because this function should not require
114
* the AC'97 interrupt to be enabled.
115
*/
116
status |=
oxygen_read8
(chip,
OXYGEN_AC97_INTERRUPT_STATUS
);
117
return
status & mask ? 0 : -
EIO
;
118
}
119
120
/*
121
* About 10% of AC'97 register reads or writes fail to complete, but even those
122
* where the controller indicates completion aren't guaranteed to have actually
123
* happened.
124
*
125
* It's hard to assign blame to either the controller or the codec because both
126
* were made by C-Media ...
127
*/
128
129
void
oxygen_write_ac97
(
struct
oxygen
*chip,
unsigned
int
codec
,
130
unsigned
int
index
,
u16
data
)
131
{
132
unsigned
int
count
, succeeded;
133
u32
reg
;
134
135
reg =
data
;
136
reg |= index <<
OXYGEN_AC97_REG_ADDR_SHIFT
;
137
reg |=
OXYGEN_AC97_REG_DIR_WRITE
;
138
reg |= codec <<
OXYGEN_AC97_REG_CODEC_SHIFT
;
139
succeeded = 0;
140
for
(count = 5; count > 0; --
count
) {
141
udelay
(5);
142
oxygen_write32
(chip,
OXYGEN_AC97_REGS
, reg);
143
/* require two "completed" writes, just to be sure */
144
if
(oxygen_ac97_wait(chip,
OXYGEN_AC97_INT_WRITE_DONE
) >= 0 &&
145
++succeeded >= 2) {
146
chip->
saved_ac97_registers
[
codec
][index / 2] =
data
;
147
return
;
148
}
149
}
150
snd_printk
(
KERN_ERR
"AC'97 write timeout\n"
);
151
}
152
EXPORT_SYMBOL
(
oxygen_write_ac97
);
153
154
u16
oxygen_read_ac97
(
struct
oxygen
*chip,
unsigned
int
codec
,
155
unsigned
int
index
)
156
{
157
unsigned
int
count
;
158
unsigned
int
last_read =
UINT_MAX
;
159
u32
reg
;
160
161
reg = index <<
OXYGEN_AC97_REG_ADDR_SHIFT
;
162
reg |=
OXYGEN_AC97_REG_DIR_READ
;
163
reg |= codec <<
OXYGEN_AC97_REG_CODEC_SHIFT
;
164
for
(count = 5; count > 0; --
count
) {
165
udelay
(5);
166
oxygen_write32
(chip,
OXYGEN_AC97_REGS
, reg);
167
udelay
(10);
168
if
(oxygen_ac97_wait(chip,
OXYGEN_AC97_INT_READ_DONE
) >= 0) {
169
u16
value
=
oxygen_read16
(chip,
OXYGEN_AC97_REGS
);
170
/* we require two consecutive reads of the same value */
171
if
(value == last_read)
172
return
value
;
173
last_read =
value
;
174
/*
175
* Invert the register value bits to make sure that two
176
* consecutive unsuccessful reads do not return the same
177
* value.
178
*/
179
reg ^= 0xffff;
180
}
181
}
182
snd_printk
(
KERN_ERR
"AC'97 read timeout on codec %u\n"
, codec);
183
return
0;
184
}
185
EXPORT_SYMBOL
(
oxygen_read_ac97
);
186
187
void
oxygen_write_ac97_masked
(
struct
oxygen
*chip,
unsigned
int
codec
,
188
unsigned
int
index
,
u16
data
,
u16
mask)
189
{
190
u16
value
=
oxygen_read_ac97
(chip, codec, index);
191
value &= ~mask;
192
value |= data &
mask
;
193
oxygen_write_ac97
(chip, codec, index, value);
194
}
195
EXPORT_SYMBOL
(
oxygen_write_ac97_masked
);
196
197
void
oxygen_write_spi
(
struct
oxygen
*chip,
u8
control
,
unsigned
int
data
)
198
{
199
unsigned
int
count
;
200
201
/* should not need more than 30.72 us (24 * 1.28 us) */
202
count = 10;
203
while
((
oxygen_read8
(chip,
OXYGEN_SPI_CONTROL
) &
OXYGEN_SPI_BUSY
)
204
&& count > 0) {
205
udelay
(4);
206
--
count
;
207
}
208
209
oxygen_write8
(chip,
OXYGEN_SPI_DATA1
, data);
210
oxygen_write8
(chip,
OXYGEN_SPI_DATA2
, data >> 8);
211
if
(control &
OXYGEN_SPI_DATA_LENGTH_3
)
212
oxygen_write8
(chip,
OXYGEN_SPI_DATA3
, data >> 16);
213
oxygen_write8
(chip,
OXYGEN_SPI_CONTROL
, control);
214
}
215
EXPORT_SYMBOL
(
oxygen_write_spi
);
216
217
void
oxygen_write_i2c
(
struct
oxygen
*chip,
u8
device
,
u8
map
,
u8
data
)
218
{
219
/* should not need more than about 300 us */
220
msleep
(1);
221
222
oxygen_write8
(chip,
OXYGEN_2WIRE_MAP
, map);
223
oxygen_write8
(chip,
OXYGEN_2WIRE_DATA
, data);
224
oxygen_write8
(chip,
OXYGEN_2WIRE_CONTROL
,
225
device |
OXYGEN_2WIRE_DIR_WRITE
);
226
}
227
EXPORT_SYMBOL
(
oxygen_write_i2c
);
228
229
static
void
_write_uart(
struct
oxygen
*chip,
unsigned
int
port
,
u8
data
)
230
{
231
if
(
oxygen_read8
(chip,
OXYGEN_MPU401
+ 1) &
MPU401_TX_FULL
)
232
msleep
(1);
233
oxygen_write8
(chip,
OXYGEN_MPU401
+ port, data);
234
}
235
236
void
oxygen_reset_uart
(
struct
oxygen
*chip)
237
{
238
_write_uart(chip, 1,
MPU401_RESET
);
239
msleep
(1);
/* wait for ACK */
240
_write_uart(chip, 1,
MPU401_ENTER_UART
);
241
}
242
EXPORT_SYMBOL
(
oxygen_reset_uart
);
243
244
void
oxygen_write_uart
(
struct
oxygen
*chip,
u8
data)
245
{
246
_write_uart(chip, 0, data);
247
}
248
EXPORT_SYMBOL
(
oxygen_write_uart
);
249
250
u16
oxygen_read_eeprom
(
struct
oxygen
*chip,
unsigned
int
index
)
251
{
252
unsigned
int
timeout
;
253
254
oxygen_write8
(chip,
OXYGEN_EEPROM_CONTROL
,
255
index |
OXYGEN_EEPROM_DIR_READ
);
256
for
(timeout = 0; timeout < 100; ++timeout) {
257
udelay
(1);
258
if
(!(
oxygen_read8
(chip,
OXYGEN_EEPROM_STATUS
)
259
&
OXYGEN_EEPROM_BUSY
))
260
break
;
261
}
262
return
oxygen_read16
(chip,
OXYGEN_EEPROM_DATA
);
263
}
264
265
void
oxygen_write_eeprom
(
struct
oxygen
*chip,
unsigned
int
index
,
u16
value
)
266
{
267
unsigned
int
timeout
;
268
269
oxygen_write16
(chip,
OXYGEN_EEPROM_DATA
, value);
270
oxygen_write8
(chip,
OXYGEN_EEPROM_CONTROL
,
271
index |
OXYGEN_EEPROM_DIR_WRITE
);
272
for
(timeout = 0; timeout < 10; ++timeout) {
273
msleep
(1);
274
if
(!(
oxygen_read8
(chip,
OXYGEN_EEPROM_STATUS
)
275
&
OXYGEN_EEPROM_BUSY
))
276
return
;
277
}
278
snd_printk
(
KERN_ERR
"EEPROM write timeout\n"
);
279
}
Generated on Thu Jan 10 2013 15:06:57 for Linux Kernel by
1.8.2