diff options
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 10 | ||||
-rw-r--r-- | sound/pci/Kconfig | 15 | ||||
-rw-r--r-- | sound/pci/oxygen/Makefile | 2 | ||||
-rw-r--r-- | sound/pci/oxygen/hifier.c | 239 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen.c | 43 |
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 | ||
211 | config SND_OXYGEN | 211 | config 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 | ||
581 | config 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 | |||
593 | config SND_ICE1712 | 582 | config 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 @@ | |||
1 | snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o | 1 | snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o |
2 | snd-hifier-objs := hifier.o | ||
3 | snd-oxygen-objs := oxygen.o | 2 | snd-oxygen-objs := oxygen.o |
4 | snd-virtuoso-objs := virtuoso.o xonar_lib.o \ | 3 | snd-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 | ||
7 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o | 6 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o |
8 | obj-$(CONFIG_SND_HIFIER) += snd-hifier.o | ||
9 | obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o | 7 | obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o |
10 | obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o | 8 | obj-$(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 | |||
36 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
37 | MODULE_DESCRIPTION("TempoTec HiFier driver"); | ||
38 | MODULE_LICENSE("GPL v2"); | ||
39 | |||
40 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
41 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
42 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
43 | |||
44 | module_param_array(index, int, NULL, 0444); | ||
45 | MODULE_PARM_DESC(index, "card index"); | ||
46 | module_param_array(id, charp, NULL, 0444); | ||
47 | MODULE_PARM_DESC(id, "ID string"); | ||
48 | module_param_array(enable, bool, NULL, 0444); | ||
49 | MODULE_PARM_DESC(enable, "enable card"); | ||
50 | |||
51 | static 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 | }; | ||
57 | MODULE_DEVICE_TABLE(pci, hifier_ids); | ||
58 | |||
59 | struct hifier_data { | ||
60 | u8 ak4396_regs[5]; | ||
61 | }; | ||
62 | |||
63 | static 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 | |||
76 | static 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 | |||
84 | static 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 | |||
96 | static 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 | |||
108 | static void hifier_cleanup(struct oxygen *chip) | ||
109 | { | ||
110 | } | ||
111 | |||
112 | static void hifier_resume(struct oxygen *chip) | ||
113 | { | ||
114 | hifier_registers_init(chip); | ||
115 | } | ||
116 | |||
117 | static 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 | |||
142 | static 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 | |||
148 | static 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 | |||
159 | static void set_cs5340_params(struct oxygen *chip, | ||
160 | struct snd_pcm_hw_params *params) | ||
161 | { | ||
162 | } | ||
163 | |||
164 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | ||
165 | |||
166 | static 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 | |||
191 | static 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 | |||
198 | static 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 | |||
217 | static 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 | |||
228 | static int __init alsa_card_hifier_init(void) | ||
229 | { | ||
230 | return pci_register_driver(&hifier_driver); | ||
231 | } | ||
232 | |||
233 | static void __exit alsa_card_hifier_exit(void) | ||
234 | { | ||
235 | pci_unregister_driver(&hifier_driver); | ||
236 | } | ||
237 | |||
238 | module_init(alsa_card_hifier_init) | ||
239 | module_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 | ||
75 | static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { | 76 | static 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 | ||
100 | struct generic_data { | 103 | struct 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 | ||
240 | static void hifier_init(struct oxygen *chip) | ||
241 | { | ||
242 | ak4396_init(chip); | ||
243 | snd_component_add(chip->card, "CS5340"); | ||
244 | } | ||
245 | |||
235 | static void generic_cleanup(struct oxygen *chip) | 246 | static 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 | ||
282 | static void stereo_resume(struct oxygen *chip) | ||
283 | { | ||
284 | ak4396_registers_init(chip); | ||
285 | } | ||
286 | |||
271 | static void set_ak4396_params(struct oxygen *chip, | 287 | static 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 | ||
299 | static void update_ak4396_volume(struct oxygen *chip) | 315 | static 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 | ||
376 | static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params) | ||
377 | { | ||
378 | } | ||
379 | |||
359 | static int rolloff_info(struct snd_kcontrol *ctl, | 380 | static 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) { |