oxygen.c 10.2 KB
Newer Older
C
Clemens Ladisch 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * C-Media CMI8788 driver for C-Media's reference design and for the X-Meridian
 *
 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
 *
 *
 *  This driver is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2.
 *
 *  This driver is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this driver; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

/*
 * SPI 0 -> 1st AK4396 (front)
22
 * SPI 1 -> 2nd AK4396 (surround)
C
Clemens Ladisch 已提交
23 24
 * SPI 2 -> 3rd AK4396 (center/LFE)
 * SPI 3 -> WM8785
25
 * SPI 4 -> 4th AK4396 (back)
C
Clemens Ladisch 已提交
26 27 28 29 30
 *
 * GPIO 0 -> DFS0 of AK5385
 * GPIO 1 -> DFS1 of AK5385
 */

31
#include <linux/delay.h>
32
#include <linux/mutex.h>
C
Clemens Ladisch 已提交
33
#include <linux/pci.h>
34
#include <sound/ac97_codec.h>
35
#include <sound/control.h>
C
Clemens Ladisch 已提交
36 37 38 39 40 41
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include "oxygen.h"
42
#include "ak4396.h"
43
#include "wm8785.h"
C
Clemens Ladisch 已提交
44 45 46

MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_DESCRIPTION("C-Media CMI8788 driver");
47
MODULE_LICENSE("GPL v2");
C
Clemens Ladisch 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}");

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;

module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "card index");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "enable card");

static struct pci_device_id oxygen_ids[] __devinitdata = {
	{ OXYGEN_PCI_SUBID(0x10b0, 0x0216) },
	{ OXYGEN_PCI_SUBID(0x10b0, 0x0218) },
	{ OXYGEN_PCI_SUBID(0x10b0, 0x0219) },
	{ OXYGEN_PCI_SUBID(0x13f6, 0x0001) },
	{ OXYGEN_PCI_SUBID(0x13f6, 0x0010) },
	{ OXYGEN_PCI_SUBID(0x13f6, 0x8788) },
	{ OXYGEN_PCI_SUBID(0x147a, 0xa017) },
	{ OXYGEN_PCI_SUBID(0x1a58, 0x0910) },
	{ OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = 1 },
	{ OXYGEN_PCI_SUBID(0x7284, 0x9761) },
	{ }
};
MODULE_DEVICE_TABLE(pci, oxygen_ids);

76 77 78 79 80 81

#define GPIO_AK5385_DFS_MASK	0x0003
#define GPIO_AK5385_DFS_NORMAL	0x0000
#define GPIO_AK5385_DFS_DOUBLE	0x0001
#define GPIO_AK5385_DFS_QUAD	0x0002

82 83
struct generic_data {
	u8 ak4396_ctl2;
84
	u16 saved_wm8785_registers[2];
85 86
};

C
Clemens Ladisch 已提交
87 88 89 90 91
static void ak4396_write(struct oxygen *chip, unsigned int codec,
			 u8 reg, u8 value)
{
	/* maps ALSA channel pair number to SPI output */
	static const u8 codec_spi_map[4] = {
92
		0, 1, 2, 4
C
Clemens Ladisch 已提交
93
	};
94
	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
C
Clemens Ladisch 已提交
95
			 OXYGEN_SPI_DATA_LENGTH_2 |
96
			 OXYGEN_SPI_CLOCK_160 |
C
Clemens Ladisch 已提交
97
			 (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
98
			 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
C
Clemens Ladisch 已提交
99 100 101 102 103
			 AK4396_WRITE | (reg << 8) | value);
}

static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
{
104 105
	struct generic_data *data = chip->model_data;

106
	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
C
Clemens Ladisch 已提交
107
			 OXYGEN_SPI_DATA_LENGTH_2 |
108
			 OXYGEN_SPI_CLOCK_160 |
109 110
			 (3 << OXYGEN_SPI_CODEC_SHIFT) |
			 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
C
Clemens Ladisch 已提交
111
			 (reg << 9) | value);
112 113
	if (reg < ARRAY_SIZE(data->saved_wm8785_registers))
		data->saved_wm8785_registers[reg] = value;
C
Clemens Ladisch 已提交
114 115
}

116 117 118 119 120 121 122 123 124 125 126 127
static void update_ak4396_volume(struct oxygen *chip)
{
	unsigned int i;

	for (i = 0; i < 4; ++i) {
		ak4396_write(chip, i,
			     AK4396_LCH_ATT, chip->dac_volume[i * 2]);
		ak4396_write(chip, i,
			     AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
	}
}

128
static void ak4396_registers_init(struct oxygen *chip)
C
Clemens Ladisch 已提交
129
{
130
	struct generic_data *data = chip->model_data;
C
Clemens Ladisch 已提交
131 132 133
	unsigned int i;

	for (i = 0; i < 4; ++i) {
134 135 136
		ak4396_write(chip, i,
			     AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
		ak4396_write(chip, i,
137
			     AK4396_CONTROL_2, data->ak4396_ctl2);
138 139
		ak4396_write(chip, i,
			     AK4396_CONTROL_3, AK4396_PCM);
C
Clemens Ladisch 已提交
140
	}
141
	update_ak4396_volume(chip);
142 143 144 145 146 147 148 149
}

static void ak4396_init(struct oxygen *chip)
{
	struct generic_data *data = chip->model_data;

	data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
	ak4396_registers_init(chip);
C
Clemens Ladisch 已提交
150 151 152 153 154
	snd_component_add(chip->card, "AK4396");
}

static void ak5385_init(struct oxygen *chip)
{
155 156
	oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_AK5385_DFS_MASK);
	oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_AK5385_DFS_MASK);
C
Clemens Ladisch 已提交
157 158 159
	snd_component_add(chip->card, "AK5385");
}

160
static void wm8785_registers_init(struct oxygen *chip)
C
Clemens Ladisch 已提交
161
{
162 163
	struct generic_data *data = chip->model_data;

164
	wm8785_write(chip, WM8785_R7, 0);
165 166
	wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]);
	wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]);
167
}
168

169 170 171 172 173 174 175 176
static void wm8785_init(struct oxygen *chip)
{
	struct generic_data *data = chip->model_data;

	data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE |
		WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST;
	data->saved_wm8785_registers[1] = WM8785_WL_24;
	wm8785_registers_init(chip);
C
Clemens Ladisch 已提交
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
	snd_component_add(chip->card, "WM8785");
}

static void generic_init(struct oxygen *chip)
{
	ak4396_init(chip);
	wm8785_init(chip);
}

static void meridian_init(struct oxygen *chip)
{
	ak4396_init(chip);
	ak5385_init(chip);
}

static void generic_cleanup(struct oxygen *chip)
{
}

C
Clemens Ladisch 已提交
196 197 198 199 200 201
static void generic_resume(struct oxygen *chip)
{
	ak4396_registers_init(chip);
	wm8785_registers_init(chip);
}

C
Clemens Ladisch 已提交
202 203 204
static void set_ak4396_params(struct oxygen *chip,
			      struct snd_pcm_hw_params *params)
{
205
	struct generic_data *data = chip->model_data;
C
Clemens Ladisch 已提交
206 207 208
	unsigned int i;
	u8 value;

209
	value = data->ak4396_ctl2 & ~AK4396_DFS_MASK;
C
Clemens Ladisch 已提交
210 211
	if (params_rate(params) <= 54000)
		value |= AK4396_DFS_NORMAL;
212
	else if (params_rate(params) <= 108000)
C
Clemens Ladisch 已提交
213 214 215
		value |= AK4396_DFS_DOUBLE;
	else
		value |= AK4396_DFS_QUAD;
216
	data->ak4396_ctl2 = value;
217 218 219

	msleep(1); /* wait for the new MCLK to become stable */

C
Clemens Ladisch 已提交
220
	for (i = 0; i < 4; ++i) {
221 222 223 224 225 226
		ak4396_write(chip, i,
			     AK4396_CONTROL_1, AK4396_DIF_24_MSB);
		ak4396_write(chip, i,
			     AK4396_CONTROL_2, value);
		ak4396_write(chip, i,
			     AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
C
Clemens Ladisch 已提交
227 228 229 230 231
	}
}

static void update_ak4396_mute(struct oxygen *chip)
{
232
	struct generic_data *data = chip->model_data;
C
Clemens Ladisch 已提交
233 234 235
	unsigned int i;
	u8 value;

236
	value = data->ak4396_ctl2 & ~AK4396_SMUTE;
C
Clemens Ladisch 已提交
237 238
	if (chip->dac_mute)
		value |= AK4396_SMUTE;
239
	data->ak4396_ctl2 = value;
C
Clemens Ladisch 已提交
240
	for (i = 0; i < 4; ++i)
241
		ak4396_write(chip, i, AK4396_CONTROL_2, value);
C
Clemens Ladisch 已提交
242 243 244 245 246 247 248
}

static void set_wm8785_params(struct oxygen *chip,
			      struct snd_pcm_hw_params *params)
{
	unsigned int value;

249
	wm8785_write(chip, WM8785_R7, 0);
C
Clemens Ladisch 已提交
250

251
	value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST;
252 253 254
	if (params_rate(params) <= 48000)
		value |= WM8785_OSR_SINGLE;
	else if (params_rate(params) <= 96000)
C
Clemens Ladisch 已提交
255 256
		value |= WM8785_OSR_DOUBLE;
	else
257
		value |= WM8785_OSR_QUAD;
258
	wm8785_write(chip, WM8785_R0, value);
C
Clemens Ladisch 已提交
259 260 261 262 263

	if (snd_pcm_format_width(params_format(params)) <= 16)
		value = WM8785_WL_16;
	else
		value = WM8785_WL_24;
264
	wm8785_write(chip, WM8785_R1, value);
C
Clemens Ladisch 已提交
265 266 267 268 269 270 271 272
}

static void set_ak5385_params(struct oxygen *chip,
			      struct snd_pcm_hw_params *params)
{
	unsigned int value;

	if (params_rate(params) <= 54000)
273
		value = GPIO_AK5385_DFS_NORMAL;
C
Clemens Ladisch 已提交
274
	else if (params_rate(params) <= 108000)
275
		value = GPIO_AK5385_DFS_DOUBLE;
C
Clemens Ladisch 已提交
276
	else
277 278 279
		value = GPIO_AK5385_DFS_QUAD;
	oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
			      value, GPIO_AK5385_DFS_MASK);
C
Clemens Ladisch 已提交
280 281 282 283 284 285 286 287 288 289 290
}

static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);

static const struct oxygen_model model_generic = {
	.shortname = "C-Media CMI8788",
	.longname = "C-Media Oxygen HD Audio",
	.chip = "CMI8788",
	.owner = THIS_MODULE,
	.init = generic_init,
	.cleanup = generic_cleanup,
C
Clemens Ladisch 已提交
291
	.resume = generic_resume,
C
Clemens Ladisch 已提交
292 293 294 295
	.set_dac_params = set_ak4396_params,
	.set_adc_params = set_wm8785_params,
	.update_dac_volume = update_ak4396_volume,
	.update_dac_mute = update_ak4396_mute,
296
	.dac_tlv = ak4396_db_scale,
297
	.model_data_size = sizeof(struct generic_data),
298 299 300 301 302 303
	.pcm_dev_cfg = PLAYBACK_0_TO_I2S |
		       PLAYBACK_1_TO_SPDIF |
		       PLAYBACK_2_TO_AC97_1 |
		       CAPTURE_0_FROM_I2S_1 |
		       CAPTURE_1_FROM_SPDIF |
		       CAPTURE_2_FROM_AC97_1,
304
	.dac_channels = 8,
305 306
	.dac_volume_min = 0,
	.dac_volume_max = 255,
307 308
	.function_flags = OXYGEN_FUNCTION_SPI |
			  OXYGEN_FUNCTION_ENABLE_SPI_4_5,
309 310
	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
C
Clemens Ladisch 已提交
311 312 313 314 315 316 317 318
};
static const struct oxygen_model model_meridian = {
	.shortname = "C-Media CMI8788",
	.longname = "C-Media Oxygen HD Audio",
	.chip = "CMI8788",
	.owner = THIS_MODULE,
	.init = meridian_init,
	.cleanup = generic_cleanup,
C
Clemens Ladisch 已提交
319
	.resume = ak4396_registers_init,
C
Clemens Ladisch 已提交
320 321 322 323
	.set_dac_params = set_ak4396_params,
	.set_adc_params = set_ak5385_params,
	.update_dac_volume = update_ak4396_volume,
	.update_dac_mute = update_ak4396_mute,
324
	.dac_tlv = ak4396_db_scale,
325
	.model_data_size = sizeof(struct generic_data),
326 327 328 329 330 331
	.pcm_dev_cfg = PLAYBACK_0_TO_I2S |
		       PLAYBACK_1_TO_SPDIF |
		       PLAYBACK_2_TO_AC97_1 |
		       CAPTURE_0_FROM_I2S_2 |
		       CAPTURE_1_FROM_SPDIF |
		       CAPTURE_2_FROM_AC97_1,
332
	.dac_channels = 8,
333 334
	.dac_volume_min = 0,
	.dac_volume_max = 255,
335
	.misc_flags = OXYGEN_MISC_MIDI,
336 337
	.function_flags = OXYGEN_FUNCTION_SPI |
			  OXYGEN_FUNCTION_ENABLE_SPI_4_5,
338 339
	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
C
Clemens Ladisch 已提交
340 341 342 343 344 345
};

static int __devinit generic_oxygen_probe(struct pci_dev *pci,
					  const struct pci_device_id *pci_id)
{
	static int dev;
346
	int is_meridian;
C
Clemens Ladisch 已提交
347 348 349 350 351 352 353 354
	int err;

	if (dev >= SNDRV_CARDS)
		return -ENODEV;
	if (!enable[dev]) {
		++dev;
		return -ENOENT;
	}
355
	is_meridian = pci_id->driver_data;
356
	err = oxygen_pci_probe(pci, index[dev], id[dev],
357 358
			       is_meridian ? &model_meridian : &model_generic,
			       0);
C
Clemens Ladisch 已提交
359 360 361 362 363 364 365 366 367 368
	if (err >= 0)
		++dev;
	return err;
}

static struct pci_driver oxygen_driver = {
	.name = "CMI8788",
	.id_table = oxygen_ids,
	.probe = generic_oxygen_probe,
	.remove = __devexit_p(oxygen_pci_remove),
C
Clemens Ladisch 已提交
369 370 371 372
#ifdef CONFIG_PM
	.suspend = oxygen_pci_suspend,
	.resume = oxygen_pci_resume,
#endif
C
Clemens Ladisch 已提交
373 374 375 376 377 378 379 380 381 382 383 384 385 386
};

static int __init alsa_card_oxygen_init(void)
{
	return pci_register_driver(&oxygen_driver);
}

static void __exit alsa_card_oxygen_exit(void)
{
	pci_unregister_driver(&oxygen_driver);
}

module_init(alsa_card_oxygen_init)
module_exit(alsa_card_oxygen_exit)