diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
-rw-r--r-- | sound/pci/oxygen/oxygen.c | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 63f185c1ed1e..7c8ae31eb468 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -43,7 +43,7 @@ | |||
43 | 43 | ||
44 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 44 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
45 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); | 45 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); |
46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL v2"); |
47 | MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); | 47 | MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); |
48 | 48 | ||
49 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 49 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
@@ -80,6 +80,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); | |||
80 | 80 | ||
81 | struct generic_data { | 81 | struct generic_data { |
82 | u8 ak4396_ctl2; | 82 | u8 ak4396_ctl2; |
83 | u16 saved_wm8785_registers[2]; | ||
83 | }; | 84 | }; |
84 | 85 | ||
85 | static void ak4396_write(struct oxygen *chip, unsigned int codec, | 86 | static void ak4396_write(struct oxygen *chip, unsigned int codec, |
@@ -99,20 +100,35 @@ static void ak4396_write(struct oxygen *chip, unsigned int codec, | |||
99 | 100 | ||
100 | static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) | 101 | static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) |
101 | { | 102 | { |
103 | struct generic_data *data = chip->model_data; | ||
104 | |||
102 | oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | | 105 | oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | |
103 | OXYGEN_SPI_DATA_LENGTH_2 | | 106 | OXYGEN_SPI_DATA_LENGTH_2 | |
104 | OXYGEN_SPI_CLOCK_160 | | 107 | OXYGEN_SPI_CLOCK_160 | |
105 | (3 << OXYGEN_SPI_CODEC_SHIFT) | | 108 | (3 << OXYGEN_SPI_CODEC_SHIFT) | |
106 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, | 109 | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, |
107 | (reg << 9) | value); | 110 | (reg << 9) | value); |
111 | if (reg < ARRAY_SIZE(data->saved_wm8785_registers)) | ||
112 | data->saved_wm8785_registers[reg] = value; | ||
108 | } | 113 | } |
109 | 114 | ||
110 | static void ak4396_init(struct oxygen *chip) | 115 | static void update_ak4396_volume(struct oxygen *chip) |
116 | { | ||
117 | unsigned int i; | ||
118 | |||
119 | for (i = 0; i < 4; ++i) { | ||
120 | ak4396_write(chip, i, | ||
121 | AK4396_LCH_ATT, chip->dac_volume[i * 2]); | ||
122 | ak4396_write(chip, i, | ||
123 | AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | static void ak4396_registers_init(struct oxygen *chip) | ||
111 | { | 128 | { |
112 | struct generic_data *data = chip->model_data; | 129 | struct generic_data *data = chip->model_data; |
113 | unsigned int i; | 130 | unsigned int i; |
114 | 131 | ||
115 | data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; | ||
116 | for (i = 0; i < 4; ++i) { | 132 | for (i = 0; i < 4; ++i) { |
117 | ak4396_write(chip, i, | 133 | ak4396_write(chip, i, |
118 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); | 134 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); |
@@ -120,9 +136,16 @@ static void ak4396_init(struct oxygen *chip) | |||
120 | AK4396_CONTROL_2, data->ak4396_ctl2); | 136 | AK4396_CONTROL_2, data->ak4396_ctl2); |
121 | ak4396_write(chip, i, | 137 | ak4396_write(chip, i, |
122 | AK4396_CONTROL_3, AK4396_PCM); | 138 | AK4396_CONTROL_3, AK4396_PCM); |
123 | ak4396_write(chip, i, AK4396_LCH_ATT, 0); | ||
124 | ak4396_write(chip, i, AK4396_RCH_ATT, 0); | ||
125 | } | 139 | } |
140 | update_ak4396_volume(chip); | ||
141 | } | ||
142 | |||
143 | static void ak4396_init(struct oxygen *chip) | ||
144 | { | ||
145 | struct generic_data *data = chip->model_data; | ||
146 | |||
147 | data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; | ||
148 | ak4396_registers_init(chip); | ||
126 | snd_component_add(chip->card, "AK4396"); | 149 | snd_component_add(chip->card, "AK4396"); |
127 | } | 150 | } |
128 | 151 | ||
@@ -133,12 +156,23 @@ static void ak5385_init(struct oxygen *chip) | |||
133 | snd_component_add(chip->card, "AK5385"); | 156 | snd_component_add(chip->card, "AK5385"); |
134 | } | 157 | } |
135 | 158 | ||
136 | static void wm8785_init(struct oxygen *chip) | 159 | static void wm8785_registers_init(struct oxygen *chip) |
137 | { | 160 | { |
161 | struct generic_data *data = chip->model_data; | ||
162 | |||
138 | wm8785_write(chip, WM8785_R7, 0); | 163 | wm8785_write(chip, WM8785_R7, 0); |
139 | wm8785_write(chip, WM8785_R0, WM8785_MCR_SLAVE | | 164 | wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]); |
140 | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST); | 165 | wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]); |
141 | wm8785_write(chip, WM8785_R1, WM8785_WL_24); | 166 | } |
167 | |||
168 | static void wm8785_init(struct oxygen *chip) | ||
169 | { | ||
170 | struct generic_data *data = chip->model_data; | ||
171 | |||
172 | data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE | | ||
173 | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; | ||
174 | data->saved_wm8785_registers[1] = WM8785_WL_24; | ||
175 | wm8785_registers_init(chip); | ||
142 | snd_component_add(chip->card, "WM8785"); | 176 | snd_component_add(chip->card, "WM8785"); |
143 | } | 177 | } |
144 | 178 | ||
@@ -158,6 +192,12 @@ static void generic_cleanup(struct oxygen *chip) | |||
158 | { | 192 | { |
159 | } | 193 | } |
160 | 194 | ||
195 | static void generic_resume(struct oxygen *chip) | ||
196 | { | ||
197 | ak4396_registers_init(chip); | ||
198 | wm8785_registers_init(chip); | ||
199 | } | ||
200 | |||
161 | static void set_ak4396_params(struct oxygen *chip, | 201 | static void set_ak4396_params(struct oxygen *chip, |
162 | struct snd_pcm_hw_params *params) | 202 | struct snd_pcm_hw_params *params) |
163 | { | 203 | { |
@@ -183,18 +223,6 @@ static void set_ak4396_params(struct oxygen *chip, | |||
183 | } | 223 | } |
184 | } | 224 | } |
185 | 225 | ||
186 | static void update_ak4396_volume(struct oxygen *chip) | ||
187 | { | ||
188 | unsigned int i; | ||
189 | |||
190 | for (i = 0; i < 4; ++i) { | ||
191 | ak4396_write(chip, i, | ||
192 | AK4396_LCH_ATT, chip->dac_volume[i * 2]); | ||
193 | ak4396_write(chip, i, | ||
194 | AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | static void update_ak4396_mute(struct oxygen *chip) | 226 | static void update_ak4396_mute(struct oxygen *chip) |
199 | { | 227 | { |
200 | struct generic_data *data = chip->model_data; | 228 | struct generic_data *data = chip->model_data; |
@@ -256,6 +284,7 @@ static const struct oxygen_model model_generic = { | |||
256 | .owner = THIS_MODULE, | 284 | .owner = THIS_MODULE, |
257 | .init = generic_init, | 285 | .init = generic_init, |
258 | .cleanup = generic_cleanup, | 286 | .cleanup = generic_cleanup, |
287 | .resume = generic_resume, | ||
259 | .set_dac_params = set_ak4396_params, | 288 | .set_dac_params = set_ak4396_params, |
260 | .set_adc_params = set_wm8785_params, | 289 | .set_adc_params = set_wm8785_params, |
261 | .update_dac_volume = update_ak4396_volume, | 290 | .update_dac_volume = update_ak4396_volume, |
@@ -283,6 +312,7 @@ static const struct oxygen_model model_meridian = { | |||
283 | .owner = THIS_MODULE, | 312 | .owner = THIS_MODULE, |
284 | .init = meridian_init, | 313 | .init = meridian_init, |
285 | .cleanup = generic_cleanup, | 314 | .cleanup = generic_cleanup, |
315 | .resume = ak4396_registers_init, | ||
286 | .set_dac_params = set_ak4396_params, | 316 | .set_dac_params = set_ak4396_params, |
287 | .set_adc_params = set_ak5385_params, | 317 | .set_adc_params = set_ak5385_params, |
288 | .update_dac_volume = update_ak4396_volume, | 318 | .update_dac_volume = update_ak4396_volume, |
@@ -331,6 +361,10 @@ static struct pci_driver oxygen_driver = { | |||
331 | .id_table = oxygen_ids, | 361 | .id_table = oxygen_ids, |
332 | .probe = generic_oxygen_probe, | 362 | .probe = generic_oxygen_probe, |
333 | .remove = __devexit_p(oxygen_pci_remove), | 363 | .remove = __devexit_p(oxygen_pci_remove), |
364 | #ifdef CONFIG_PM | ||
365 | .suspend = oxygen_pci_suspend, | ||
366 | .resume = oxygen_pci_resume, | ||
367 | #endif | ||
334 | }; | 368 | }; |
335 | 369 | ||
336 | static int __init alsa_card_oxygen_init(void) | 370 | static int __init alsa_card_oxygen_init(void) |