aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--sound/pci/oxygen/hifier.c46
-rw-r--r--sound/pci/oxygen/oxygen.c107
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c140
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c109
4 files changed, 250 insertions, 152 deletions
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 19e9e0123304..2079c100aabc 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -57,23 +57,28 @@ static struct pci_device_id hifier_ids[] __devinitdata = {
57MODULE_DEVICE_TABLE(pci, hifier_ids); 57MODULE_DEVICE_TABLE(pci, hifier_ids);
58 58
59struct hifier_data { 59struct hifier_data {
60 u8 ak4396_ctl2; 60 u8 ak4396_regs[5];
61}; 61};
62 62
63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value) 63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
64{ 64{
65 struct hifier_data *data = chip->model_data;
66
65 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 67 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
66 OXYGEN_SPI_DATA_LENGTH_2 | 68 OXYGEN_SPI_DATA_LENGTH_2 |
67 OXYGEN_SPI_CLOCK_160 | 69 OXYGEN_SPI_CLOCK_160 |
68 (0 << OXYGEN_SPI_CODEC_SHIFT) | 70 (0 << OXYGEN_SPI_CODEC_SHIFT) |
69 OXYGEN_SPI_CEN_LATCH_CLOCK_HI, 71 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
70 AK4396_WRITE | (reg << 8) | value); 72 AK4396_WRITE | (reg << 8) | value);
73 data->ak4396_regs[reg] = value;
71} 74}
72 75
73static void update_ak4396_volume(struct oxygen *chip) 76static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
74{ 77{
75 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]); 78 struct hifier_data *data = chip->model_data;
76 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); 79
80 if (value != data->ak4396_regs[reg])
81 ak4396_write(chip, reg, value);
77} 82}
78 83
79static void hifier_registers_init(struct oxygen *chip) 84static void hifier_registers_init(struct oxygen *chip)
@@ -81,16 +86,19 @@ static void hifier_registers_init(struct oxygen *chip)
81 struct hifier_data *data = chip->model_data; 86 struct hifier_data *data = chip->model_data;
82 87
83 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 88 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
84 ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2); 89 ak4396_write(chip, AK4396_CONTROL_2,
90 data->ak4396_regs[AK4396_CONTROL_2]);
85 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); 91 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
86 update_ak4396_volume(chip); 92 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
93 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
87} 94}
88 95
89static void hifier_init(struct oxygen *chip) 96static void hifier_init(struct oxygen *chip)
90{ 97{
91 struct hifier_data *data = chip->model_data; 98 struct hifier_data *data = chip->model_data;
92 99
93 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 100 data->ak4396_regs[AK4396_CONTROL_2] =
101 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
94 hifier_registers_init(chip); 102 hifier_registers_init(chip);
95 103
96 snd_component_add(chip->card, "AK4396"); 104 snd_component_add(chip->card, "AK4396");
@@ -112,20 +120,29 @@ static void set_ak4396_params(struct oxygen *chip,
112 struct hifier_data *data = chip->model_data; 120 struct hifier_data *data = chip->model_data;
113 u8 value; 121 u8 value;
114 122
115 value = data->ak4396_ctl2 & ~AK4396_DFS_MASK; 123 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
116 if (params_rate(params) <= 54000) 124 if (params_rate(params) <= 54000)
117 value |= AK4396_DFS_NORMAL; 125 value |= AK4396_DFS_NORMAL;
118 else if (params_rate(params) <= 108000) 126 else if (params_rate(params) <= 108000)
119 value |= AK4396_DFS_DOUBLE; 127 value |= AK4396_DFS_DOUBLE;
120 else 128 else
121 value |= AK4396_DFS_QUAD; 129 value |= AK4396_DFS_QUAD;
122 data->ak4396_ctl2 = value;
123 130
124 msleep(1); /* wait for the new MCLK to become stable */ 131 msleep(1); /* wait for the new MCLK to become stable */
125 132
126 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB); 133 if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
127 ak4396_write(chip, AK4396_CONTROL_2, value); 134 ak4396_write(chip, AK4396_CONTROL_1,
128 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 135 AK4396_DIF_24_MSB);
136 ak4396_write(chip, AK4396_CONTROL_2, value);
137 ak4396_write(chip, AK4396_CONTROL_1,
138 AK4396_DIF_24_MSB | AK4396_RSTN);
139 }
140}
141
142static void update_ak4396_volume(struct oxygen *chip)
143{
144 ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
145 ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
129} 146}
130 147
131static void update_ak4396_mute(struct oxygen *chip) 148static void update_ak4396_mute(struct oxygen *chip)
@@ -133,11 +150,10 @@ static void update_ak4396_mute(struct oxygen *chip)
133 struct hifier_data *data = chip->model_data; 150 struct hifier_data *data = chip->model_data;
134 u8 value; 151 u8 value;
135 152
136 value = data->ak4396_ctl2 & ~AK4396_SMUTE; 153 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
137 if (chip->dac_mute) 154 if (chip->dac_mute)
138 value |= AK4396_SMUTE; 155 value |= AK4396_SMUTE;
139 data->ak4396_ctl2 = value; 156 ak4396_write_cached(chip, AK4396_CONTROL_2, value);
140 ak4396_write(chip, AK4396_CONTROL_2, value);
141} 157}
142 158
143static void set_cs5340_params(struct oxygen *chip, 159static void set_cs5340_params(struct oxygen *chip,
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,
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index a8ec4e8271a4..330c5e755917 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -69,62 +69,58 @@
69 69
70struct xonar_cs43xx { 70struct xonar_cs43xx {
71 struct xonar_generic generic; 71 struct xonar_generic generic;
72 u8 cs4398_fm; 72 u8 cs4398_regs[7];
73 u8 cs4362a_fm; 73 u8 cs4362a_regs[15];
74 u8 cs4362a_fm_c;
75}; 74};
76 75
77static void cs4398_write(struct oxygen *chip, u8 reg, u8 value) 76static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
78{ 77{
79 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value); 78 struct xonar_cs43xx *data = chip->model_data;
80}
81 79
82static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value) 80 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
83{ 81 if (reg < ARRAY_SIZE(data->cs4398_regs))
84 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value); 82 data->cs4398_regs[reg] = value;
85} 83}
86 84
87static void update_cs4362a_volumes(struct oxygen *chip) 85static void cs4398_write_cached(struct oxygen *chip, u8 reg, u8 value)
88{ 86{
89 u8 mute; 87 struct xonar_cs43xx *data = chip->model_data;
90 88
91 mute = chip->dac_mute ? CS4362A_MUTE : 0; 89 if (value != data->cs4398_regs[reg])
92 cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute); 90 cs4398_write(chip, reg, value);
93 cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
94 cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
95 cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
96 cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
97 cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
98} 91}
99 92
100static void update_cs43xx_volume(struct oxygen *chip) 93static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
101{ 94{
102 cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2); 95 struct xonar_cs43xx *data = chip->model_data;
103 cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2); 96
104 update_cs4362a_volumes(chip); 97 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
98 if (reg < ARRAY_SIZE(data->cs4362a_regs))
99 data->cs4362a_regs[reg] = value;
105} 100}
106 101
107static void update_cs43xx_mute(struct oxygen *chip) 102static void cs4362a_write_cached(struct oxygen *chip, u8 reg, u8 value)
108{ 103{
109 u8 reg; 104 struct xonar_cs43xx *data = chip->model_data;
110 105
111 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE; 106 if (value != data->cs4362a_regs[reg])
112 if (chip->dac_mute) 107 cs4362a_write(chip, reg, value);
113 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
114 cs4398_write(chip, 4, reg);
115 update_cs4362a_volumes(chip);
116} 108}
117 109
118static void cs43xx_init(struct oxygen *chip) 110static void cs43xx_registers_init(struct oxygen *chip)
119{ 111{
120 struct xonar_cs43xx *data = chip->model_data; 112 struct xonar_cs43xx *data = chip->model_data;
113 unsigned int i;
121 114
122 /* set CPEN (control port mode) and power down */ 115 /* set CPEN (control port mode) and power down */
123 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN); 116 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
124 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); 117 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
125 /* configure */ 118 /* configure */
126 cs4398_write(chip, 2, data->cs4398_fm); 119 cs4398_write(chip, 2, data->cs4398_regs[2]);
127 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L); 120 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
121 cs4398_write(chip, 4, data->cs4398_regs[4]);
122 cs4398_write(chip, 5, data->cs4398_regs[5]);
123 cs4398_write(chip, 6, data->cs4398_regs[6]);
128 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP | 124 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
129 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP); 125 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
130 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST); 126 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
@@ -132,11 +128,8 @@ static void cs43xx_init(struct oxygen *chip)
132 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP); 128 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
133 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE); 129 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
134 cs4362a_write(chip, 0x05, 0); 130 cs4362a_write(chip, 0x05, 0);
135 cs4362a_write(chip, 0x06, data->cs4362a_fm); 131 for (i = 6; i <= 14; ++i)
136 cs4362a_write(chip, 0x09, data->cs4362a_fm_c); 132 cs4362a_write(chip, i, data->cs4362a_regs[i]);
137 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
138 update_cs43xx_volume(chip);
139 update_cs43xx_mute(chip);
140 /* clear power down */ 133 /* clear power down */
141 cs4398_write(chip, 8, CS4398_CPEN); 134 cs4398_write(chip, 8, CS4398_CPEN);
142 cs4362a_write(chip, 0x01, CS4362A_CPEN); 135 cs4362a_write(chip, 0x01, CS4362A_CPEN);
@@ -148,17 +141,29 @@ static void xonar_d1_init(struct oxygen *chip)
148 141
149 data->generic.anti_pop_delay = 800; 142 data->generic.anti_pop_delay = 800;
150 data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE; 143 data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
151 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; 144 data->cs4398_regs[2] =
152 data->cs4362a_fm = CS4362A_FM_SINGLE | 145 CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
146 data->cs4398_regs[4] = CS4398_MUTEP_LOW |
147 CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE;
148 data->cs4398_regs[5] = 60 * 2;
149 data->cs4398_regs[6] = 60 * 2;
150 data->cs4362a_regs[6] = CS4362A_FM_SINGLE |
153 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 151 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
154 data->cs4362a_fm_c = data->cs4362a_fm; 152 data->cs4362a_regs[7] = 60 | CS4362A_MUTE;
153 data->cs4362a_regs[8] = 60 | CS4362A_MUTE;
154 data->cs4362a_regs[9] = data->cs4362a_regs[6];
155 data->cs4362a_regs[10] = 60 | CS4362A_MUTE;
156 data->cs4362a_regs[11] = 60 | CS4362A_MUTE;
157 data->cs4362a_regs[12] = data->cs4362a_regs[6];
158 data->cs4362a_regs[13] = 60 | CS4362A_MUTE;
159 data->cs4362a_regs[14] = 60 | CS4362A_MUTE;
155 160
156 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 161 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
157 OXYGEN_2WIRE_LENGTH_8 | 162 OXYGEN_2WIRE_LENGTH_8 |
158 OXYGEN_2WIRE_INTERRUPT_MASK | 163 OXYGEN_2WIRE_INTERRUPT_MASK |
159 OXYGEN_2WIRE_SPEED_FAST); 164 OXYGEN_2WIRE_SPEED_FAST);
160 165
161 cs43xx_init(chip); 166 cs43xx_registers_init(chip);
162 167
163 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 168 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
164 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 169 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
@@ -200,7 +205,7 @@ static void xonar_d1_resume(struct oxygen *chip)
200{ 205{
201 oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC); 206 oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
202 msleep(1); 207 msleep(1);
203 cs43xx_init(chip); 208 cs43xx_registers_init(chip);
204 xonar_enable_output(chip); 209 xonar_enable_output(chip);
205} 210}
206 211
@@ -220,27 +225,56 @@ static void set_cs43xx_params(struct oxygen *chip,
220 cs4398_fm = CS4398_FM_QUAD; 225 cs4398_fm = CS4398_FM_QUAD;
221 cs4362a_fm = CS4362A_FM_QUAD; 226 cs4362a_fm = CS4362A_FM_QUAD;
222 } 227 }
223 data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST | cs4398_fm; 228 cs4398_fm |= CS4398_DEM_NONE | CS4398_DIF_LJUST;
224 data->cs4362a_fm = 229 cs4398_write_cached(chip, 2, cs4398_fm);
225 (data->cs4362a_fm & ~CS4362A_FM_MASK) | cs4362a_fm; 230 cs4362a_fm |= data->cs4362a_regs[6] & ~CS4362A_FM_MASK;
226 data->cs4362a_fm_c = 231 cs4362a_write_cached(chip, 6, cs4362a_fm);
227 (data->cs4362a_fm_c & ~CS4362A_FM_MASK) | cs4362a_fm; 232 cs4362a_write_cached(chip, 12, cs4362a_fm);
228 cs4398_write(chip, 2, data->cs4398_fm); 233 cs4362a_fm &= CS4362A_FM_MASK;
229 cs4362a_write(chip, 0x06, data->cs4362a_fm); 234 cs4362a_fm |= data->cs4362a_regs[9] & ~CS4362A_FM_MASK;
230 cs4362a_write(chip, 0x09, data->cs4362a_fm_c); 235 cs4362a_write_cached(chip, 9, cs4362a_fm);
231 cs4362a_write(chip, 0x0c, data->cs4362a_fm); 236}
237
238static void update_cs4362a_volumes(struct oxygen *chip)
239{
240 unsigned int i;
241 u8 mute;
242
243 mute = chip->dac_mute ? CS4362A_MUTE : 0;
244 for (i = 0; i < 6; ++i)
245 cs4362a_write_cached(chip, 7 + i + i / 2,
246 (127 - chip->dac_volume[2 + i]) | mute);
247}
248
249static void update_cs43xx_volume(struct oxygen *chip)
250{
251 cs4398_write_cached(chip, 5, (127 - chip->dac_volume[0]) * 2);
252 cs4398_write_cached(chip, 6, (127 - chip->dac_volume[1]) * 2);
253 update_cs4362a_volumes(chip);
254}
255
256static void update_cs43xx_mute(struct oxygen *chip)
257{
258 u8 reg;
259
260 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
261 if (chip->dac_mute)
262 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
263 cs4398_write_cached(chip, 4, reg);
264 update_cs4362a_volumes(chip);
232} 265}
233 266
234static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed) 267static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
235{ 268{
236 struct xonar_cs43xx *data = chip->model_data; 269 struct xonar_cs43xx *data = chip->model_data;
270 u8 reg;
237 271
238 data->cs4362a_fm_c &= ~CS4362A_ATAPI_MASK; 272 reg = data->cs4362a_regs[9] & ~CS4362A_ATAPI_MASK;
239 if (mixed) 273 if (mixed)
240 data->cs4362a_fm_c |= CS4362A_ATAPI_B_LR | CS4362A_ATAPI_A_LR; 274 reg |= CS4362A_ATAPI_B_LR | CS4362A_ATAPI_A_LR;
241 else 275 else
242 data->cs4362a_fm_c |= CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; 276 reg |= CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
243 cs4362a_write(chip, 0x09, data->cs4362a_fm_c); 277 cs4362a_write_cached(chip, 9, reg);
244} 278}
245 279
246static const struct snd_kcontrol_new front_panel_switch = { 280static const struct snd_kcontrol_new front_panel_switch = {
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 97574dbec2b6..e17ee5e8e510 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -166,11 +166,13 @@
166#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ 166#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
167#define I2C_DEVICE_CS2000 0x9c /* 100111, 0, /W=0 */ 167#define I2C_DEVICE_CS2000 0x9c /* 100111, 0, /W=0 */
168 168
169#define PCM1796_REG_BASE 16
170
169 171
170struct xonar_pcm179x { 172struct xonar_pcm179x {
171 struct xonar_generic generic; 173 struct xonar_generic generic;
172 unsigned int dacs; 174 unsigned int dacs;
173 u8 oversampling; 175 u8 pcm1796_regs[4][5];
174 u8 cs2000_fun_cfg_1; 176 u8 cs2000_fun_cfg_1;
175}; 177};
176 178
@@ -204,54 +206,71 @@ static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
204static void pcm1796_write(struct oxygen *chip, unsigned int codec, 206static void pcm1796_write(struct oxygen *chip, unsigned int codec,
205 u8 reg, u8 value) 207 u8 reg, u8 value)
206{ 208{
209 struct xonar_pcm179x *data = chip->model_data;
210
207 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) == 211 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
208 OXYGEN_FUNCTION_SPI) 212 OXYGEN_FUNCTION_SPI)
209 pcm1796_write_spi(chip, codec, reg, value); 213 pcm1796_write_spi(chip, codec, reg, value);
210 else 214 else
211 pcm1796_write_i2c(chip, codec, reg, value); 215 pcm1796_write_i2c(chip, codec, reg, value);
216 if ((unsigned int)(reg - PCM1796_REG_BASE)
217 < ARRAY_SIZE(data->pcm1796_regs[codec]))
218 data->pcm1796_regs[codec][reg - PCM1796_REG_BASE] = value;
212} 219}
213 220
214static void cs2000_write(struct oxygen *chip, u8 reg, u8 value) 221static void pcm1796_write_cached(struct oxygen *chip, unsigned int codec,
222 u8 reg, u8 value)
215{ 223{
216 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value); 224 struct xonar_pcm179x *data = chip->model_data;
225
226 if (value != data->pcm1796_regs[codec][reg - PCM1796_REG_BASE])
227 pcm1796_write(chip, codec, reg, value);
217} 228}
218 229
219static void update_pcm1796_volume(struct oxygen *chip) 230static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
220{ 231{
221 struct xonar_pcm179x *data = chip->model_data; 232 struct xonar_pcm179x *data = chip->model_data;
222 unsigned int i;
223 233
224 for (i = 0; i < data->dacs; ++i) { 234 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
225 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]); 235 if (reg == CS2000_FUN_CFG_1)
226 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]); 236 data->cs2000_fun_cfg_1 = value;
227 }
228} 237}
229 238
230static void update_pcm1796_mute(struct oxygen *chip) 239static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
231{ 240{
232 struct xonar_pcm179x *data = chip->model_data; 241 struct xonar_pcm179x *data = chip->model_data;
233 unsigned int i;
234 u8 value;
235 242
236 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 243 if (reg != CS2000_FUN_CFG_1 ||
237 if (chip->dac_mute) 244 value != data->cs2000_fun_cfg_1)
238 value |= PCM1796_MUTE; 245 cs2000_write(chip, reg, value);
239 for (i = 0; i < data->dacs; ++i)
240 pcm1796_write(chip, i, 18, value);
241} 246}
242 247
243static void pcm1796_init(struct oxygen *chip) 248static void pcm1796_registers_init(struct oxygen *chip)
244{ 249{
245 struct xonar_pcm179x *data = chip->model_data; 250 struct xonar_pcm179x *data = chip->model_data;
246 unsigned int i; 251 unsigned int i;
247 252
248 for (i = 0; i < data->dacs; ++i) { 253 for (i = 0; i < data->dacs; ++i) {
254 /* set ATLD before ATL/ATR */
255 pcm1796_write(chip, i, 18,
256 data->pcm1796_regs[0][18 - PCM1796_REG_BASE]);
257 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
258 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
249 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); 259 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
250 pcm1796_write(chip, i, 20, data->oversampling); 260 pcm1796_write(chip, i, 20,
261 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]);
251 pcm1796_write(chip, i, 21, 0); 262 pcm1796_write(chip, i, 21, 0);
252 } 263 }
253 update_pcm1796_mute(chip); /* set ATLD before ATL/ATR */ 264}
254 update_pcm1796_volume(chip); 265
266static void pcm1796_init(struct oxygen *chip)
267{
268 struct xonar_pcm179x *data = chip->model_data;
269
270 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
271 PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
272 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64;
273 pcm1796_registers_init(chip);
255} 274}
256 275
257static void xonar_d2_init(struct oxygen *chip) 276static void xonar_d2_init(struct oxygen *chip)
@@ -261,7 +280,6 @@ static void xonar_d2_init(struct oxygen *chip)
261 data->generic.anti_pop_delay = 300; 280 data->generic.anti_pop_delay = 300;
262 data->generic.output_enable_bit = GPIO_D2_OUTPUT_ENABLE; 281 data->generic.output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
263 data->dacs = 4; 282 data->dacs = 4;
264 data->oversampling = PCM1796_OS_64;
265 283
266 pcm1796_init(chip); 284 pcm1796_init(chip);
267 285
@@ -304,7 +322,6 @@ static void xonar_hdav_init(struct oxygen *chip)
304 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 322 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
305 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER; 323 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER;
306 data->pcm179x.dacs = chip->model.private_data ? 4 : 1; 324 data->pcm179x.dacs = chip->model.private_data ? 4 : 1;
307 data->pcm179x.oversampling = PCM1796_OS_64;
308 325
309 pcm1796_init(chip); 326 pcm1796_init(chip);
310 327
@@ -335,7 +352,6 @@ static void xonar_st_init_common(struct oxygen *chip)
335 data->generic.anti_pop_delay = 100; 352 data->generic.anti_pop_delay = 100;
336 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; 353 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
337 data->dacs = chip->model.private_data ? 4 : 1; 354 data->dacs = chip->model.private_data ? 4 : 1;
338 data->oversampling = PCM1796_OS_64;
339 355
340 pcm1796_init(chip); 356 pcm1796_init(chip);
341 357
@@ -438,7 +454,7 @@ static void xonar_st_suspend(struct oxygen *chip)
438 454
439static void xonar_d2_resume(struct oxygen *chip) 455static void xonar_d2_resume(struct oxygen *chip)
440{ 456{
441 pcm1796_init(chip); 457 pcm1796_registers_init(chip);
442 xonar_enable_output(chip); 458 xonar_enable_output(chip);
443} 459}
444 460
@@ -446,14 +462,14 @@ static void xonar_hdav_resume(struct oxygen *chip)
446{ 462{
447 struct xonar_hdav *data = chip->model_data; 463 struct xonar_hdav *data = chip->model_data;
448 464
449 pcm1796_init(chip); 465 pcm1796_registers_init(chip);
450 xonar_hdmi_resume(chip, &data->hdmi); 466 xonar_hdmi_resume(chip, &data->hdmi);
451 xonar_enable_output(chip); 467 xonar_enable_output(chip);
452} 468}
453 469
454static void xonar_stx_resume(struct oxygen *chip) 470static void xonar_stx_resume(struct oxygen *chip)
455{ 471{
456 pcm1796_init(chip); 472 pcm1796_registers_init(chip);
457 xonar_enable_output(chip); 473 xonar_enable_output(chip);
458} 474}
459 475
@@ -468,11 +484,35 @@ static void set_pcm1796_params(struct oxygen *chip,
468{ 484{
469 struct xonar_pcm179x *data = chip->model_data; 485 struct xonar_pcm179x *data = chip->model_data;
470 unsigned int i; 486 unsigned int i;
487 u8 reg;
488
489 reg = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
490 for (i = 0; i < data->dacs; ++i)
491 pcm1796_write_cached(chip, i, 20, reg);
492}
493
494static void update_pcm1796_volume(struct oxygen *chip)
495{
496 struct xonar_pcm179x *data = chip->model_data;
497 unsigned int i;
498
499 for (i = 0; i < data->dacs; ++i) {
500 pcm1796_write_cached(chip, i, 16, chip->dac_volume[i * 2]);
501 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1]);
502 }
503}
504
505static void update_pcm1796_mute(struct oxygen *chip)
506{
507 struct xonar_pcm179x *data = chip->model_data;
508 unsigned int i;
509 u8 value;
471 510
472 data->oversampling = 511 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
473 params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; 512 if (chip->dac_mute)
513 value |= PCM1796_MUTE;
474 for (i = 0; i < data->dacs; ++i) 514 for (i = 0; i < data->dacs; ++i)
475 pcm1796_write(chip, i, 20, data->oversampling); 515 pcm1796_write_cached(chip, i, 18, value);
476} 516}
477 517
478static void set_cs2000_params(struct oxygen *chip, 518static void set_cs2000_params(struct oxygen *chip,
@@ -489,9 +529,8 @@ static void set_cs2000_params(struct oxygen *chip,
489 [OXYGEN_RATE_176400] = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256, 529 [OXYGEN_RATE_176400] = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256,
490 [OXYGEN_RATE_192000] = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256, 530 [OXYGEN_RATE_192000] = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256,
491 }; 531 };
492 struct xonar_pcm179x *data = chip->model_data;
493 unsigned int rate_index; 532 unsigned int rate_index;
494 u8 rate_mclk; 533 u8 rate_mclk, reg;
495 534
496 rate_index = oxygen_read16(chip, OXYGEN_I2S_MULTICH_FORMAT) 535 rate_index = oxygen_read16(chip, OXYGEN_I2S_MULTICH_FORMAT)
497 & OXYGEN_I2S_RATE_MASK; 536 & OXYGEN_I2S_RATE_MASK;
@@ -499,10 +538,10 @@ static void set_cs2000_params(struct oxygen *chip,
499 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, 538 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
500 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); 539 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
501 if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_128) 540 if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_128)
502 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; 541 reg = CS2000_REF_CLK_DIV_1;
503 else 542 else
504 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_2; 543 reg = CS2000_REF_CLK_DIV_2;
505 cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1); 544 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);
506} 545}
507 546
508static void set_st_params(struct oxygen *chip, 547static void set_st_params(struct oxygen *chip,