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