aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt10
-rw-r--r--sound/pci/Kconfig15
-rw-r--r--sound/pci/oxygen/Makefile2
-rw-r--r--sound/pci/oxygen/hifier.c239
-rw-r--r--sound/pci/oxygen/oxygen.c43
5 files changed, 42 insertions, 267 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index d0eb696d32e8..f1a1787e71e5 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -974,13 +974,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
974 974
975 See hdspm.txt for details. 975 See hdspm.txt for details.
976 976
977 Module snd-hifier
978 -----------------
979
980 Module for the MediaTek/TempoTec HiFier Fantasia sound card.
981
982 This module supports autoprobe and multiple cards.
983
984 Module snd-ice1712 977 Module snd-ice1712
985 ------------------ 978 ------------------
986 979
@@ -1531,7 +1524,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1531 Module snd-oxygen 1524 Module snd-oxygen
1532 ----------------- 1525 -----------------
1533 1526
1534 Module for sound cards based on the C-Media CMI8788 chip: 1527 Module for sound cards based on the C-Media CMI8787/8788 chip:
1535 * Asound A-8788 1528 * Asound A-8788
1536 * AuzenTech X-Meridian 1529 * AuzenTech X-Meridian
1537 * Bgears b-Enspirer 1530 * Bgears b-Enspirer
@@ -1540,6 +1533,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1540 * HT-Omega Claro halo (XT) 1533 * HT-Omega Claro halo (XT)
1541 * Razer Barracuda AC-1 1534 * Razer Barracuda AC-1
1542 * Sondigo Inferno 1535 * Sondigo Inferno
1536 * TempoTec HiFier Fantasia
1543 1537
1544 This module supports autoprobe and multiple cards. 1538 This module supports autoprobe and multiple cards.
1545 1539
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 12e34653b8a8..dfe406de9935 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -209,7 +209,7 @@ config SND_OXYGEN_LIB
209 tristate 209 tristate
210 210
211config SND_OXYGEN 211config SND_OXYGEN
212 tristate "C-Media 8788 (Oxygen)" 212 tristate "C-Media 8787, 8788 (Oxygen)"
213 select SND_OXYGEN_LIB 213 select SND_OXYGEN_LIB
214 select SND_PCM 214 select SND_PCM
215 select SND_MPU401_UART 215 select SND_MPU401_UART
@@ -224,6 +224,7 @@ config SND_OXYGEN
224 * HT-Omega Claro halo (XT) 224 * HT-Omega Claro halo (XT)
225 * Razer Barracuda AC-1 225 * Razer Barracuda AC-1
226 * Sondigo Inferno 226 * Sondigo Inferno
227 * TempoTec/MediaTek HiFier Fantasia
227 228
228 To compile this driver as a module, choose M here: the module 229 To compile this driver as a module, choose M here: the module
229 will be called snd-oxygen. 230 will be called snd-oxygen.
@@ -578,18 +579,6 @@ config SND_HDSPM
578 To compile this driver as a module, choose M here: the module 579 To compile this driver as a module, choose M here: the module
579 will be called snd-hdspm. 580 will be called snd-hdspm.
580 581
581config SND_HIFIER
582 tristate "TempoTec HiFier Fantasia"
583 select SND_OXYGEN_LIB
584 select SND_PCM
585 select SND_MPU401_UART
586 help
587 Say Y here to include support for the MediaTek/TempoTec HiFier
588 Fantasia sound card.
589
590 To compile this driver as a module, choose M here: the module
591 will be called snd-hifier.
592
593config SND_ICE1712 582config SND_ICE1712
594 tristate "ICEnsemble ICE1712 (Envy24)" 583 tristate "ICEnsemble ICE1712 (Envy24)"
595 select SND_MPU401_UART 584 select SND_MPU401_UART
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index acd8f15f7bff..bd67c0d7779c 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,10 +1,8 @@
1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o 1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
2snd-hifier-objs := hifier.o
3snd-oxygen-objs := oxygen.o 2snd-oxygen-objs := oxygen.o
4snd-virtuoso-objs := virtuoso.o xonar_lib.o \ 3snd-virtuoso-objs := virtuoso.o xonar_lib.o \
5 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o 4 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
6 5
7obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o 6obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
8obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
9obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o 7obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
10obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o 8obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
deleted file mode 100644
index 5a87d683691f..000000000000
--- a/sound/pci/oxygen/hifier.c
+++ /dev/null
@@ -1,239 +0,0 @@
1/*
2 * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
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/*
21 * CMI8788:
22 *
23 * SPI 0 -> AK4396
24 */
25
26#include <linux/delay.h>
27#include <linux/pci.h>
28#include <sound/control.h>
29#include <sound/core.h>
30#include <sound/initval.h>
31#include <sound/pcm.h>
32#include <sound/tlv.h>
33#include "oxygen.h"
34#include "ak4396.h"
35
36MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
37MODULE_DESCRIPTION("TempoTec HiFier driver");
38MODULE_LICENSE("GPL v2");
39
40static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
41static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
42static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
43
44module_param_array(index, int, NULL, 0444);
45MODULE_PARM_DESC(index, "card index");
46module_param_array(id, charp, NULL, 0444);
47MODULE_PARM_DESC(id, "ID string");
48module_param_array(enable, bool, NULL, 0444);
49MODULE_PARM_DESC(enable, "enable card");
50
51static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
52 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
53 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
55 { }
56};
57MODULE_DEVICE_TABLE(pci, hifier_ids);
58
59struct hifier_data {
60 u8 ak4396_regs[5];
61};
62
63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
64{
65 struct hifier_data *data = chip->model_data;
66
67 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
68 OXYGEN_SPI_DATA_LENGTH_2 |
69 OXYGEN_SPI_CLOCK_160 |
70 (0 << OXYGEN_SPI_CODEC_SHIFT) |
71 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
72 AK4396_WRITE | (reg << 8) | value);
73 data->ak4396_regs[reg] = value;
74}
75
76static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
77{
78 struct hifier_data *data = chip->model_data;
79
80 if (value != data->ak4396_regs[reg])
81 ak4396_write(chip, reg, value);
82}
83
84static void hifier_registers_init(struct oxygen *chip)
85{
86 struct hifier_data *data = chip->model_data;
87
88 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
89 ak4396_write(chip, AK4396_CONTROL_2,
90 data->ak4396_regs[AK4396_CONTROL_2]);
91 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
92 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
93 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
94}
95
96static void hifier_init(struct oxygen *chip)
97{
98 struct hifier_data *data = chip->model_data;
99
100 data->ak4396_regs[AK4396_CONTROL_2] =
101 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
102 hifier_registers_init(chip);
103
104 snd_component_add(chip->card, "AK4396");
105 snd_component_add(chip->card, "CS5340");
106}
107
108static void hifier_cleanup(struct oxygen *chip)
109{
110}
111
112static void hifier_resume(struct oxygen *chip)
113{
114 hifier_registers_init(chip);
115}
116
117static void set_ak4396_params(struct oxygen *chip,
118 struct snd_pcm_hw_params *params)
119{
120 struct hifier_data *data = chip->model_data;
121 u8 value;
122
123 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
124 if (params_rate(params) <= 54000)
125 value |= AK4396_DFS_NORMAL;
126 else if (params_rate(params) <= 108000)
127 value |= AK4396_DFS_DOUBLE;
128 else
129 value |= AK4396_DFS_QUAD;
130
131 msleep(1); /* wait for the new MCLK to become stable */
132
133 if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
134 ak4396_write(chip, AK4396_CONTROL_1,
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]);
146}
147
148static void update_ak4396_mute(struct oxygen *chip)
149{
150 struct hifier_data *data = chip->model_data;
151 u8 value;
152
153 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
154 if (chip->dac_mute)
155 value |= AK4396_SMUTE;
156 ak4396_write_cached(chip, AK4396_CONTROL_2, value);
157}
158
159static void set_cs5340_params(struct oxygen *chip,
160 struct snd_pcm_hw_params *params)
161{
162}
163
164static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
165
166static const struct oxygen_model model_hifier = {
167 .shortname = "C-Media CMI8787",
168 .longname = "C-Media Oxygen HD Audio",
169 .chip = "CMI8788",
170 .init = hifier_init,
171 .cleanup = hifier_cleanup,
172 .resume = hifier_resume,
173 .get_i2s_mclk = oxygen_default_i2s_mclk,
174 .set_dac_params = set_ak4396_params,
175 .set_adc_params = set_cs5340_params,
176 .update_dac_volume = update_ak4396_volume,
177 .update_dac_mute = update_ak4396_mute,
178 .dac_tlv = ak4396_db_scale,
179 .model_data_size = sizeof(struct hifier_data),
180 .device_config = PLAYBACK_0_TO_I2S |
181 PLAYBACK_1_TO_SPDIF |
182 CAPTURE_0_FROM_I2S_1,
183 .dac_channels = 2,
184 .dac_volume_min = 0,
185 .dac_volume_max = 255,
186 .function_flags = OXYGEN_FUNCTION_SPI,
187 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
188 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
189};
190
191static int __devinit get_hifier_model(struct oxygen *chip,
192 const struct pci_device_id *id)
193{
194 chip->model = model_hifier;
195 return 0;
196}
197
198static int __devinit hifier_probe(struct pci_dev *pci,
199 const struct pci_device_id *pci_id)
200{
201 static int dev;
202 int err;
203
204 if (dev >= SNDRV_CARDS)
205 return -ENODEV;
206 if (!enable[dev]) {
207 ++dev;
208 return -ENOENT;
209 }
210 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
211 hifier_ids, get_hifier_model);
212 if (err >= 0)
213 ++dev;
214 return err;
215}
216
217static struct pci_driver hifier_driver = {
218 .name = "CMI8787HiFier",
219 .id_table = hifier_ids,
220 .probe = hifier_probe,
221 .remove = __devexit_p(oxygen_pci_remove),
222#ifdef CONFIG_PM
223 .suspend = oxygen_pci_suspend,
224 .resume = oxygen_pci_resume,
225#endif
226};
227
228static int __init alsa_card_hifier_init(void)
229{
230 return pci_register_driver(&hifier_driver);
231}
232
233static void __exit alsa_card_hifier_exit(void)
234{
235 pci_unregister_driver(&hifier_driver);
236}
237
238module_init(alsa_card_hifier_init)
239module_exit(alsa_card_hifier_exit)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 98a8eb3c92f7..5e258b26f044 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -70,6 +70,7 @@ enum {
70 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 70 MODEL_MERIDIAN, /* AuzenTech X-Meridian */
71 MODEL_CLARO, /* HT-Omega Claro */ 71 MODEL_CLARO, /* HT-Omega Claro */
72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */ 72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */
73 MODEL_HIFIER, /* TempoTec HiFier Fantasia */
73}; 74};
74 75
75static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { 76static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
@@ -81,6 +82,8 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, 82 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF }, 83 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
83 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 84 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
85 { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER },
86 { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER },
84 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 87 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
85 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 88 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
86 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, 89 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
@@ -98,6 +101,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
98#define GPIO_CLARO_HP 0x0100 101#define GPIO_CLARO_HP 0x0100
99 102
100struct generic_data { 103struct generic_data {
104 unsigned int dacs;
101 u8 ak4396_regs[4][5]; 105 u8 ak4396_regs[4][5];
102 u16 wm8785_regs[3]; 106 u16 wm8785_regs[3];
103}; 107};
@@ -148,7 +152,7 @@ static void ak4396_registers_init(struct oxygen *chip)
148 struct generic_data *data = chip->model_data; 152 struct generic_data *data = chip->model_data;
149 unsigned int i; 153 unsigned int i;
150 154
151 for (i = 0; i < 4; ++i) { 155 for (i = 0; i < data->dacs; ++i) {
152 ak4396_write(chip, i, AK4396_CONTROL_1, 156 ak4396_write(chip, i, AK4396_CONTROL_1,
153 AK4396_DIF_24_MSB | AK4396_RSTN); 157 AK4396_DIF_24_MSB | AK4396_RSTN);
154 ak4396_write(chip, i, AK4396_CONTROL_2, 158 ak4396_write(chip, i, AK4396_CONTROL_2,
@@ -166,6 +170,7 @@ static void ak4396_init(struct oxygen *chip)
166{ 170{
167 struct generic_data *data = chip->model_data; 171 struct generic_data *data = chip->model_data;
168 172
173 data->dacs = chip->model.dac_channels / 2;
169 data->ak4396_regs[0][AK4396_CONTROL_2] = 174 data->ak4396_regs[0][AK4396_CONTROL_2] =
170 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 175 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
171 ak4396_registers_init(chip); 176 ak4396_registers_init(chip);
@@ -232,6 +237,12 @@ static void claro_halo_init(struct oxygen *chip)
232 claro_enable_hp(chip); 237 claro_enable_hp(chip);
233} 238}
234 239
240static void hifier_init(struct oxygen *chip)
241{
242 ak4396_init(chip);
243 snd_component_add(chip->card, "CS5340");
244}
245
235static void generic_cleanup(struct oxygen *chip) 246static void generic_cleanup(struct oxygen *chip)
236{ 247{
237} 248}
@@ -268,6 +279,11 @@ static void claro_resume(struct oxygen *chip)
268 claro_enable_hp(chip); 279 claro_enable_hp(chip);
269} 280}
270 281
282static void stereo_resume(struct oxygen *chip)
283{
284 ak4396_registers_init(chip);
285}
286
271static void set_ak4396_params(struct oxygen *chip, 287static void set_ak4396_params(struct oxygen *chip,
272 struct snd_pcm_hw_params *params) 288 struct snd_pcm_hw_params *params)
273{ 289{
@@ -286,7 +302,7 @@ static void set_ak4396_params(struct oxygen *chip,
286 msleep(1); /* wait for the new MCLK to become stable */ 302 msleep(1); /* wait for the new MCLK to become stable */
287 303
288 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { 304 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
289 for (i = 0; i < 4; ++i) { 305 for (i = 0; i < data->dacs; ++i) {
290 ak4396_write(chip, i, AK4396_CONTROL_1, 306 ak4396_write(chip, i, AK4396_CONTROL_1,
291 AK4396_DIF_24_MSB); 307 AK4396_DIF_24_MSB);
292 ak4396_write(chip, i, AK4396_CONTROL_2, value); 308 ak4396_write(chip, i, AK4396_CONTROL_2, value);
@@ -298,9 +314,10 @@ static void set_ak4396_params(struct oxygen *chip,
298 314
299static void update_ak4396_volume(struct oxygen *chip) 315static void update_ak4396_volume(struct oxygen *chip)
300{ 316{
317 struct generic_data *data = chip->model_data;
301 unsigned int i; 318 unsigned int i;
302 319
303 for (i = 0; i < 4; ++i) { 320 for (i = 0; i < data->dacs; ++i) {
304 ak4396_write_cached(chip, i, AK4396_LCH_ATT, 321 ak4396_write_cached(chip, i, AK4396_LCH_ATT,
305 chip->dac_volume[i * 2]); 322 chip->dac_volume[i * 2]);
306 ak4396_write_cached(chip, i, AK4396_RCH_ATT, 323 ak4396_write_cached(chip, i, AK4396_RCH_ATT,
@@ -317,7 +334,7 @@ static void update_ak4396_mute(struct oxygen *chip)
317 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; 334 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
318 if (chip->dac_mute) 335 if (chip->dac_mute)
319 value |= AK4396_SMUTE; 336 value |= AK4396_SMUTE;
320 for (i = 0; i < 4; ++i) 337 for (i = 0; i < data->dacs; ++i)
321 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); 338 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
322} 339}
323 340
@@ -356,6 +373,10 @@ static void set_ak5385_params(struct oxygen *chip,
356 value, GPIO_AK5385_DFS_MASK); 373 value, GPIO_AK5385_DFS_MASK);
357} 374}
358 375
376static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
377{
378}
379
359static int rolloff_info(struct snd_kcontrol *ctl, 380static int rolloff_info(struct snd_kcontrol *ctl,
360 struct snd_ctl_elem_info *info) 381 struct snd_ctl_elem_info *info)
361{ 382{
@@ -400,7 +421,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
400 reg &= ~AK4396_SLOW; 421 reg &= ~AK4396_SLOW;
401 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; 422 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
402 if (changed) { 423 if (changed) {
403 for (i = 0; i < 4; ++i) 424 for (i = 0; i < data->dacs; ++i)
404 ak4396_write(chip, i, AK4396_CONTROL_2, reg); 425 ak4396_write(chip, i, AK4396_CONTROL_2, reg);
405 } 426 }
406 mutex_unlock(&chip->mutex); 427 mutex_unlock(&chip->mutex);
@@ -550,6 +571,18 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
550 CAPTURE_0_FROM_I2S_2 | 571 CAPTURE_0_FROM_I2S_2 |
551 CAPTURE_1_FROM_SPDIF; 572 CAPTURE_1_FROM_SPDIF;
552 break; 573 break;
574 case MODEL_HIFIER:
575 chip->model.shortname = "C-Media CMI8787";
576 chip->model.chip = "CMI8787";
577 chip->model.init = hifier_init;
578 chip->model.resume = stereo_resume;
579 chip->model.mixer_init = generic_mixer_init;
580 chip->model.set_adc_params = set_no_params;
581 chip->model.device_config = PLAYBACK_0_TO_I2S |
582 PLAYBACK_1_TO_SPDIF |
583 CAPTURE_0_FROM_I2S_1;
584 chip->model.dac_channels = 2;
585 break;
553 } 586 }
554 if (id->driver_data == MODEL_MERIDIAN || 587 if (id->driver_data == MODEL_MERIDIAN ||
555 id->driver_data == MODEL_CLARO_HALO) { 588 id->driver_data == MODEL_CLARO_HALO) {