aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/oxygen.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-09-28 05:18:45 -0400
committerTakashi Iwai <tiwai@suse.de>2009-09-28 05:54:29 -0400
commit6f0de3ce068e48b033b5e4d0822b47218e9d206c (patch)
tree6e4e9c054a867e5deee94df181701dedc99e4275 /sound/pci/oxygen/oxygen.c
parentdc0adf48daa81b05765d3c5ebab76321f77e9d21 (diff)
sound: oxygen: cache codec registers
Keep a cache of codec registers to avoid unnecessary writes. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
-rw-r--r--sound/pci/oxygen/oxygen.c107
1 files changed, 58 insertions, 49 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 53dff7193f31..c986c5ebf65b 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -97,8 +97,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
97#define GPIO_CLARO_HP 0x0100 97#define GPIO_CLARO_HP 0x0100
98 98
99struct generic_data { 99struct generic_data {
100 u8 ak4396_ctl2; 100 u8 ak4396_regs[4][5];
101 u16 saved_wm8785_registers[2]; 101 u16 wm8785_regs[1];
102}; 102};
103 103
104static void ak4396_write(struct oxygen *chip, unsigned int codec, 104static void ak4396_write(struct oxygen *chip, unsigned int codec,
@@ -108,12 +108,24 @@ static void ak4396_write(struct oxygen *chip, unsigned int codec,
108 static const u8 codec_spi_map[4] = { 108 static const u8 codec_spi_map[4] = {
109 0, 1, 2, 4 109 0, 1, 2, 4
110 }; 110 };
111 struct generic_data *data = chip->model_data;
112
111 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 113 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
112 OXYGEN_SPI_DATA_LENGTH_2 | 114 OXYGEN_SPI_DATA_LENGTH_2 |
113 OXYGEN_SPI_CLOCK_160 | 115 OXYGEN_SPI_CLOCK_160 |
114 (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | 116 (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
115 OXYGEN_SPI_CEN_LATCH_CLOCK_HI, 117 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
116 AK4396_WRITE | (reg << 8) | value); 118 AK4396_WRITE | (reg << 8) | value);
119 data->ak4396_regs[codec][reg] = value;
120}
121
122static void ak4396_write_cached(struct oxygen *chip, unsigned int codec,
123 u8 reg, u8 value)
124{
125 struct generic_data *data = chip->model_data;
126
127 if (value != data->ak4396_regs[codec][reg])
128 ak4396_write(chip, codec, reg, value);
117} 129}
118 130
119static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) 131static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
@@ -126,20 +138,8 @@ static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
126 (3 << OXYGEN_SPI_CODEC_SHIFT) | 138 (3 << OXYGEN_SPI_CODEC_SHIFT) |
127 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 139 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
128 (reg << 9) | value); 140 (reg << 9) | value);
129 if (reg < ARRAY_SIZE(data->saved_wm8785_registers)) 141 if (reg < ARRAY_SIZE(data->wm8785_regs))
130 data->saved_wm8785_registers[reg] = value; 142 data->wm8785_regs[reg] = value;
131}
132
133static void update_ak4396_volume(struct oxygen *chip)
134{
135 unsigned int i;
136
137 for (i = 0; i < 4; ++i) {
138 ak4396_write(chip, i,
139 AK4396_LCH_ATT, chip->dac_volume[i * 2]);
140 ak4396_write(chip, i,
141 AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
142 }
143} 143}
144 144
145static void ak4396_registers_init(struct oxygen *chip) 145static void ak4396_registers_init(struct oxygen *chip)
@@ -148,21 +148,25 @@ static void ak4396_registers_init(struct oxygen *chip)
148 unsigned int i; 148 unsigned int i;
149 149
150 for (i = 0; i < 4; ++i) { 150 for (i = 0; i < 4; ++i) {
151 ak4396_write(chip, i, 151 ak4396_write(chip, i, AK4396_CONTROL_1,
152 AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 152 AK4396_DIF_24_MSB | AK4396_RSTN);
153 ak4396_write(chip, i, 153 ak4396_write(chip, i, AK4396_CONTROL_2,
154 AK4396_CONTROL_2, data->ak4396_ctl2); 154 data->ak4396_regs[0][AK4396_CONTROL_2]);
155 ak4396_write(chip, i, 155 ak4396_write(chip, i, AK4396_CONTROL_3,
156 AK4396_CONTROL_3, AK4396_PCM); 156 AK4396_PCM);
157 ak4396_write(chip, i, AK4396_LCH_ATT,
158 chip->dac_volume[i * 2]);
159 ak4396_write(chip, i, AK4396_RCH_ATT,
160 chip->dac_volume[i * 2 + 1]);
157 } 161 }
158 update_ak4396_volume(chip);
159} 162}
160 163
161static void ak4396_init(struct oxygen *chip) 164static void ak4396_init(struct oxygen *chip)
162{ 165{
163 struct generic_data *data = chip->model_data; 166 struct generic_data *data = chip->model_data;
164 167
165 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 168 data->ak4396_regs[0][AK4396_CONTROL_2] =
169 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
166 ak4396_registers_init(chip); 170 ak4396_registers_init(chip);
167 snd_component_add(chip->card, "AK4396"); 171 snd_component_add(chip->card, "AK4396");
168} 172}
@@ -179,17 +183,15 @@ static void wm8785_registers_init(struct oxygen *chip)
179 struct generic_data *data = chip->model_data; 183 struct generic_data *data = chip->model_data;
180 184
181 wm8785_write(chip, WM8785_R7, 0); 185 wm8785_write(chip, WM8785_R7, 0);
182 wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]); 186 wm8785_write(chip, WM8785_R0, data->wm8785_regs[0]);
183 wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]);
184} 187}
185 188
186static void wm8785_init(struct oxygen *chip) 189static void wm8785_init(struct oxygen *chip)
187{ 190{
188 struct generic_data *data = chip->model_data; 191 struct generic_data *data = chip->model_data;
189 192
190 data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE | 193 data->wm8785_regs[0] =
191 WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; 194 WM8785_MCR_SLAVE | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST;
192 data->saved_wm8785_registers[1] = WM8785_WL_24;
193 wm8785_registers_init(chip); 195 wm8785_registers_init(chip);
194 snd_component_add(chip->card, "WM8785"); 196 snd_component_add(chip->card, "WM8785");
195} 197}
@@ -270,24 +272,36 @@ static void set_ak4396_params(struct oxygen *chip,
270 unsigned int i; 272 unsigned int i;
271 u8 value; 273 u8 value;
272 274
273 value = data->ak4396_ctl2 & ~AK4396_DFS_MASK; 275 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
274 if (params_rate(params) <= 54000) 276 if (params_rate(params) <= 54000)
275 value |= AK4396_DFS_NORMAL; 277 value |= AK4396_DFS_NORMAL;
276 else if (params_rate(params) <= 108000) 278 else if (params_rate(params) <= 108000)
277 value |= AK4396_DFS_DOUBLE; 279 value |= AK4396_DFS_DOUBLE;
278 else 280 else
279 value |= AK4396_DFS_QUAD; 281 value |= AK4396_DFS_QUAD;
280 data->ak4396_ctl2 = value;
281 282
282 msleep(1); /* wait for the new MCLK to become stable */ 283 msleep(1); /* wait for the new MCLK to become stable */
283 284
285 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
286 for (i = 0; i < 4; ++i) {
287 ak4396_write(chip, i, AK4396_CONTROL_1,
288 AK4396_DIF_24_MSB);
289 ak4396_write(chip, i, AK4396_CONTROL_2, value);
290 ak4396_write(chip, i, AK4396_CONTROL_1,
291 AK4396_DIF_24_MSB | AK4396_RSTN);
292 }
293 }
294}
295
296static void update_ak4396_volume(struct oxygen *chip)
297{
298 unsigned int i;
299
284 for (i = 0; i < 4; ++i) { 300 for (i = 0; i < 4; ++i) {
285 ak4396_write(chip, i, 301 ak4396_write_cached(chip, i, AK4396_LCH_ATT,
286 AK4396_CONTROL_1, AK4396_DIF_24_MSB); 302 chip->dac_volume[i * 2]);
287 ak4396_write(chip, i, 303 ak4396_write_cached(chip, i, AK4396_RCH_ATT,
288 AK4396_CONTROL_2, value); 304 chip->dac_volume[i * 2 + 1]);
289 ak4396_write(chip, i,
290 AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
291 } 305 }
292} 306}
293 307
@@ -297,21 +311,19 @@ static void update_ak4396_mute(struct oxygen *chip)
297 unsigned int i; 311 unsigned int i;
298 u8 value; 312 u8 value;
299 313
300 value = data->ak4396_ctl2 & ~AK4396_SMUTE; 314 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
301 if (chip->dac_mute) 315 if (chip->dac_mute)
302 value |= AK4396_SMUTE; 316 value |= AK4396_SMUTE;
303 data->ak4396_ctl2 = value;
304 for (i = 0; i < 4; ++i) 317 for (i = 0; i < 4; ++i)
305 ak4396_write(chip, i, AK4396_CONTROL_2, value); 318 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
306} 319}
307 320
308static void set_wm8785_params(struct oxygen *chip, 321static void set_wm8785_params(struct oxygen *chip,
309 struct snd_pcm_hw_params *params) 322 struct snd_pcm_hw_params *params)
310{ 323{
324 struct generic_data *data = chip->model_data;
311 unsigned int value; 325 unsigned int value;
312 326
313 wm8785_write(chip, WM8785_R7, 0);
314
315 value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST; 327 value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST;
316 if (params_rate(params) <= 48000) 328 if (params_rate(params) <= 48000)
317 value |= WM8785_OSR_SINGLE; 329 value |= WM8785_OSR_SINGLE;
@@ -319,13 +331,10 @@ static void set_wm8785_params(struct oxygen *chip,
319 value |= WM8785_OSR_DOUBLE; 331 value |= WM8785_OSR_DOUBLE;
320 else 332 else
321 value |= WM8785_OSR_QUAD; 333 value |= WM8785_OSR_QUAD;
322 wm8785_write(chip, WM8785_R0, value); 334 if (value != data->wm8785_regs[0]) {
323 335 wm8785_write(chip, WM8785_R7, 0);
324 if (snd_pcm_format_width(params_format(params)) <= 16) 336 wm8785_write(chip, WM8785_R0, value);
325 value = WM8785_WL_16; 337 }
326 else
327 value = WM8785_WL_24;
328 wm8785_write(chip, WM8785_R1, value);
329} 338}
330 339
331static void set_ak5385_params(struct oxygen *chip, 340static void set_ak5385_params(struct oxygen *chip,