| Thomas Bogendoerfer | 787dba3 | 2008-07-12 12:12:20 +0200 | [diff] [blame] | 1 | /* | 
 | 2 |  *  Driver for A2 audio system used in SGI machines | 
 | 3 |  *  Copyright (c) 2008 Thomas Bogendoerfer <tsbogend@alpha.fanken.de> | 
 | 4 |  * | 
 | 5 |  *  Based on OSS code from Ladislav Michl <ladis@linux-mips.org>, which | 
 | 6 |  *  was based on code from Ulf Carlsson | 
 | 7 |  * | 
 | 8 |  *  This program is free software; you can redistribute it and/or modify | 
 | 9 |  *  it under the terms of the GNU General Public License version 2 as | 
 | 10 |  *  published by the Free Software Foundation. | 
 | 11 |  * | 
 | 12 |  *  This program is distributed in the hope that it will be useful, | 
 | 13 |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 14 |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 15 |  *  GNU General Public License for more details. | 
 | 16 |  * | 
 | 17 |  *  You should have received a copy of the GNU General Public License | 
 | 18 |  *  along with this program; if not, write to the Free Software | 
 | 19 |  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
 | 20 |  * | 
 | 21 |  */ | 
 | 22 | #include <linux/kernel.h> | 
 | 23 | #include <linux/init.h> | 
 | 24 | #include <linux/interrupt.h> | 
 | 25 | #include <linux/dma-mapping.h> | 
 | 26 | #include <linux/platform_device.h> | 
 | 27 | #include <linux/io.h> | 
| Tejun Heo | 5a0e3ad | 2010-03-24 17:04:11 +0900 | [diff] [blame] | 28 | #include <linux/slab.h> | 
| Paul Gortmaker | da155d5 | 2011-07-15 12:38:28 -0400 | [diff] [blame] | 29 | #include <linux/module.h> | 
| Thomas Bogendoerfer | 787dba3 | 2008-07-12 12:12:20 +0200 | [diff] [blame] | 30 |  | 
 | 31 | #include <asm/sgi/hpc3.h> | 
 | 32 | #include <asm/sgi/ip22.h> | 
 | 33 |  | 
 | 34 | #include <sound/core.h> | 
 | 35 | #include <sound/control.h> | 
 | 36 | #include <sound/pcm.h> | 
 | 37 | #include <sound/pcm-indirect.h> | 
 | 38 | #include <sound/initval.h> | 
 | 39 |  | 
 | 40 | #include "hal2.h" | 
 | 41 |  | 
 | 42 | static int index = SNDRV_DEFAULT_IDX1;  /* Index 0-MAX */ | 
 | 43 | static char *id = SNDRV_DEFAULT_STR1;   /* ID for this card */ | 
 | 44 |  | 
 | 45 | module_param(index, int, 0444); | 
 | 46 | MODULE_PARM_DESC(index, "Index value for SGI HAL2 soundcard."); | 
 | 47 | module_param(id, charp, 0444); | 
 | 48 | MODULE_PARM_DESC(id, "ID string for SGI HAL2 soundcard."); | 
 | 49 | MODULE_DESCRIPTION("ALSA driver for SGI HAL2 audio"); | 
 | 50 | MODULE_AUTHOR("Thomas Bogendoerfer"); | 
 | 51 | MODULE_LICENSE("GPL"); | 
 | 52 |  | 
 | 53 |  | 
 | 54 | #define H2_BLOCK_SIZE	1024 | 
 | 55 | #define H2_BUF_SIZE	16384 | 
 | 56 |  | 
 | 57 | struct hal2_pbus { | 
 | 58 | 	struct hpc3_pbus_dmacregs *pbus; | 
 | 59 | 	int pbusnr; | 
 | 60 | 	unsigned int ctrl;		/* Current state of pbus->pbdma_ctrl */ | 
 | 61 | }; | 
 | 62 |  | 
 | 63 | struct hal2_desc { | 
 | 64 | 	struct hpc_dma_desc desc; | 
 | 65 | 	u32 pad;			/* padding */ | 
 | 66 | }; | 
 | 67 |  | 
 | 68 | struct hal2_codec { | 
 | 69 | 	struct snd_pcm_indirect pcm_indirect; | 
 | 70 | 	struct snd_pcm_substream *substream; | 
 | 71 |  | 
 | 72 | 	unsigned char *buffer; | 
 | 73 | 	dma_addr_t buffer_dma; | 
 | 74 | 	struct hal2_desc *desc; | 
 | 75 | 	dma_addr_t desc_dma; | 
 | 76 | 	int desc_count; | 
 | 77 | 	struct hal2_pbus pbus; | 
 | 78 | 	int voices;			/* mono/stereo */ | 
 | 79 | 	unsigned int sample_rate; | 
 | 80 | 	unsigned int master;		/* Master frequency */ | 
 | 81 | 	unsigned short mod;		/* MOD value */ | 
 | 82 | 	unsigned short inc;		/* INC value */ | 
 | 83 | }; | 
 | 84 |  | 
 | 85 | #define H2_MIX_OUTPUT_ATT	0 | 
 | 86 | #define H2_MIX_INPUT_GAIN	1 | 
 | 87 |  | 
 | 88 | struct snd_hal2 { | 
 | 89 | 	struct snd_card *card; | 
 | 90 |  | 
 | 91 | 	struct hal2_ctl_regs *ctl_regs;	/* HAL2 ctl registers */ | 
 | 92 | 	struct hal2_aes_regs *aes_regs;	/* HAL2 aes registers */ | 
 | 93 | 	struct hal2_vol_regs *vol_regs;	/* HAL2 vol registers */ | 
 | 94 | 	struct hal2_syn_regs *syn_regs;	/* HAL2 syn registers */ | 
 | 95 |  | 
 | 96 | 	struct hal2_codec dac; | 
 | 97 | 	struct hal2_codec adc; | 
 | 98 | }; | 
 | 99 |  | 
 | 100 | #define H2_INDIRECT_WAIT(regs)	while (hal2_read(®s->isr) & H2_ISR_TSTATUS); | 
 | 101 |  | 
 | 102 | #define H2_READ_ADDR(addr)	(addr | (1<<7)) | 
 | 103 | #define H2_WRITE_ADDR(addr)	(addr) | 
 | 104 |  | 
 | 105 | static inline u32 hal2_read(u32 *reg) | 
 | 106 | { | 
 | 107 | 	return __raw_readl(reg); | 
 | 108 | } | 
 | 109 |  | 
 | 110 | static inline void hal2_write(u32 val, u32 *reg) | 
 | 111 | { | 
 | 112 | 	__raw_writel(val, reg); | 
 | 113 | } | 
 | 114 |  | 
 | 115 |  | 
 | 116 | static u32 hal2_i_read32(struct snd_hal2 *hal2, u16 addr) | 
 | 117 | { | 
 | 118 | 	u32 ret; | 
 | 119 | 	struct hal2_ctl_regs *regs = hal2->ctl_regs; | 
 | 120 |  | 
 | 121 | 	hal2_write(H2_READ_ADDR(addr), ®s->iar); | 
 | 122 | 	H2_INDIRECT_WAIT(regs); | 
 | 123 | 	ret = hal2_read(®s->idr0) & 0xffff; | 
 | 124 | 	hal2_write(H2_READ_ADDR(addr) | 0x1, ®s->iar); | 
 | 125 | 	H2_INDIRECT_WAIT(regs); | 
 | 126 | 	ret |= (hal2_read(®s->idr0) & 0xffff) << 16; | 
 | 127 | 	return ret; | 
 | 128 | } | 
 | 129 |  | 
 | 130 | static void hal2_i_write16(struct snd_hal2 *hal2, u16 addr, u16 val) | 
 | 131 | { | 
 | 132 | 	struct hal2_ctl_regs *regs = hal2->ctl_regs; | 
 | 133 |  | 
 | 134 | 	hal2_write(val, ®s->idr0); | 
 | 135 | 	hal2_write(0, ®s->idr1); | 
 | 136 | 	hal2_write(0, ®s->idr2); | 
 | 137 | 	hal2_write(0, ®s->idr3); | 
 | 138 | 	hal2_write(H2_WRITE_ADDR(addr), ®s->iar); | 
 | 139 | 	H2_INDIRECT_WAIT(regs); | 
 | 140 | } | 
 | 141 |  | 
 | 142 | static void hal2_i_write32(struct snd_hal2 *hal2, u16 addr, u32 val) | 
 | 143 | { | 
 | 144 | 	struct hal2_ctl_regs *regs = hal2->ctl_regs; | 
 | 145 |  | 
 | 146 | 	hal2_write(val & 0xffff, ®s->idr0); | 
 | 147 | 	hal2_write(val >> 16, ®s->idr1); | 
 | 148 | 	hal2_write(0, ®s->idr2); | 
 | 149 | 	hal2_write(0, ®s->idr3); | 
 | 150 | 	hal2_write(H2_WRITE_ADDR(addr), ®s->iar); | 
 | 151 | 	H2_INDIRECT_WAIT(regs); | 
 | 152 | } | 
 | 153 |  | 
 | 154 | static void hal2_i_setbit16(struct snd_hal2 *hal2, u16 addr, u16 bit) | 
 | 155 | { | 
 | 156 | 	struct hal2_ctl_regs *regs = hal2->ctl_regs; | 
 | 157 |  | 
 | 158 | 	hal2_write(H2_READ_ADDR(addr), ®s->iar); | 
 | 159 | 	H2_INDIRECT_WAIT(regs); | 
 | 160 | 	hal2_write((hal2_read(®s->idr0) & 0xffff) | bit, ®s->idr0); | 
 | 161 | 	hal2_write(0, ®s->idr1); | 
 | 162 | 	hal2_write(0, ®s->idr2); | 
 | 163 | 	hal2_write(0, ®s->idr3); | 
 | 164 | 	hal2_write(H2_WRITE_ADDR(addr), ®s->iar); | 
 | 165 | 	H2_INDIRECT_WAIT(regs); | 
 | 166 | } | 
 | 167 |  | 
 | 168 | static void hal2_i_clearbit16(struct snd_hal2 *hal2, u16 addr, u16 bit) | 
 | 169 | { | 
 | 170 | 	struct hal2_ctl_regs *regs = hal2->ctl_regs; | 
 | 171 |  | 
 | 172 | 	hal2_write(H2_READ_ADDR(addr), ®s->iar); | 
 | 173 | 	H2_INDIRECT_WAIT(regs); | 
 | 174 | 	hal2_write((hal2_read(®s->idr0) & 0xffff) & ~bit, ®s->idr0); | 
 | 175 | 	hal2_write(0, ®s->idr1); | 
 | 176 | 	hal2_write(0, ®s->idr2); | 
 | 177 | 	hal2_write(0, ®s->idr3); | 
 | 178 | 	hal2_write(H2_WRITE_ADDR(addr), ®s->iar); | 
 | 179 | 	H2_INDIRECT_WAIT(regs); | 
 | 180 | } | 
 | 181 |  | 
 | 182 | static int hal2_gain_info(struct snd_kcontrol *kcontrol, | 
 | 183 | 			       struct snd_ctl_elem_info *uinfo) | 
 | 184 | { | 
 | 185 | 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 
 | 186 | 	uinfo->count = 2; | 
 | 187 | 	uinfo->value.integer.min = 0; | 
 | 188 | 	switch ((int)kcontrol->private_value) { | 
 | 189 | 	case H2_MIX_OUTPUT_ATT: | 
 | 190 | 		uinfo->value.integer.max = 31; | 
 | 191 | 		break; | 
 | 192 | 	case H2_MIX_INPUT_GAIN: | 
 | 193 | 		uinfo->value.integer.max = 15; | 
 | 194 | 		break; | 
 | 195 | 	} | 
 | 196 | 	return 0; | 
 | 197 | } | 
 | 198 |  | 
 | 199 | static int hal2_gain_get(struct snd_kcontrol *kcontrol, | 
 | 200 | 			       struct snd_ctl_elem_value *ucontrol) | 
 | 201 | { | 
 | 202 | 	struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol); | 
 | 203 | 	u32 tmp; | 
 | 204 | 	int l, r; | 
 | 205 |  | 
 | 206 | 	switch ((int)kcontrol->private_value) { | 
 | 207 | 	case H2_MIX_OUTPUT_ATT: | 
 | 208 | 		tmp = hal2_i_read32(hal2, H2I_DAC_C2); | 
 | 209 | 		if (tmp & H2I_C2_MUTE) { | 
 | 210 | 			l = 0; | 
 | 211 | 			r = 0; | 
 | 212 | 		} else { | 
 | 213 | 			l = 31 - ((tmp >> H2I_C2_L_ATT_SHIFT) & 31); | 
 | 214 | 			r = 31 - ((tmp >> H2I_C2_R_ATT_SHIFT) & 31); | 
 | 215 | 		} | 
 | 216 | 		break; | 
 | 217 | 	case H2_MIX_INPUT_GAIN: | 
 | 218 | 		tmp = hal2_i_read32(hal2, H2I_ADC_C2); | 
 | 219 | 		l = (tmp >> H2I_C2_L_GAIN_SHIFT) & 15; | 
 | 220 | 		r = (tmp >> H2I_C2_R_GAIN_SHIFT) & 15; | 
 | 221 | 		break; | 
 | 222 | 	} | 
 | 223 | 	ucontrol->value.integer.value[0] = l; | 
 | 224 | 	ucontrol->value.integer.value[1] = r; | 
 | 225 |  | 
 | 226 | 	return 0; | 
 | 227 | } | 
 | 228 |  | 
 | 229 | static int hal2_gain_put(struct snd_kcontrol *kcontrol, | 
 | 230 | 			 struct snd_ctl_elem_value *ucontrol) | 
 | 231 | { | 
 | 232 | 	struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol); | 
 | 233 | 	u32 old, new; | 
 | 234 | 	int l, r; | 
 | 235 |  | 
 | 236 | 	l = ucontrol->value.integer.value[0]; | 
 | 237 | 	r = ucontrol->value.integer.value[1]; | 
 | 238 |  | 
 | 239 | 	switch ((int)kcontrol->private_value) { | 
 | 240 | 	case H2_MIX_OUTPUT_ATT: | 
 | 241 | 		old = hal2_i_read32(hal2, H2I_DAC_C2); | 
 | 242 | 		new = old & ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE); | 
 | 243 | 		if (l | r) { | 
 | 244 | 			l = 31 - l; | 
 | 245 | 			r = 31 - r; | 
 | 246 | 			new |= (l << H2I_C2_L_ATT_SHIFT); | 
 | 247 | 			new |= (r << H2I_C2_R_ATT_SHIFT); | 
 | 248 | 		} else | 
 | 249 | 			new |= H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE; | 
 | 250 | 		hal2_i_write32(hal2, H2I_DAC_C2, new); | 
 | 251 | 		break; | 
 | 252 | 	case H2_MIX_INPUT_GAIN: | 
 | 253 | 		old = hal2_i_read32(hal2, H2I_ADC_C2); | 
 | 254 | 		new = old & ~(H2I_C2_L_GAIN_M | H2I_C2_R_GAIN_M); | 
 | 255 | 		new |= (l << H2I_C2_L_GAIN_SHIFT); | 
 | 256 | 		new |= (r << H2I_C2_R_GAIN_SHIFT); | 
 | 257 | 		hal2_i_write32(hal2, H2I_ADC_C2, new); | 
 | 258 | 		break; | 
 | 259 | 	} | 
 | 260 | 	return old != new; | 
 | 261 | } | 
 | 262 |  | 
 | 263 | static struct snd_kcontrol_new hal2_ctrl_headphone __devinitdata = { | 
 | 264 | 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER, | 
 | 265 | 	.name           = "Headphone Playback Volume", | 
 | 266 | 	.access         = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 
 | 267 | 	.private_value  = H2_MIX_OUTPUT_ATT, | 
 | 268 | 	.info           = hal2_gain_info, | 
 | 269 | 	.get            = hal2_gain_get, | 
 | 270 | 	.put            = hal2_gain_put, | 
 | 271 | }; | 
 | 272 |  | 
 | 273 | static struct snd_kcontrol_new hal2_ctrl_mic __devinitdata = { | 
 | 274 | 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER, | 
 | 275 | 	.name           = "Mic Capture Volume", | 
 | 276 | 	.access         = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 
 | 277 | 	.private_value  = H2_MIX_INPUT_GAIN, | 
 | 278 | 	.info           = hal2_gain_info, | 
 | 279 | 	.get            = hal2_gain_get, | 
 | 280 | 	.put            = hal2_gain_put, | 
 | 281 | }; | 
 | 282 |  | 
 | 283 | static int __devinit hal2_mixer_create(struct snd_hal2 *hal2) | 
 | 284 | { | 
 | 285 | 	int err; | 
 | 286 |  | 
 | 287 | 	/* mute DAC */ | 
 | 288 | 	hal2_i_write32(hal2, H2I_DAC_C2, | 
 | 289 | 		       H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE); | 
 | 290 | 	/* mute ADC */ | 
 | 291 | 	hal2_i_write32(hal2, H2I_ADC_C2, 0); | 
 | 292 |  | 
 | 293 | 	err = snd_ctl_add(hal2->card, | 
 | 294 | 			  snd_ctl_new1(&hal2_ctrl_headphone, hal2)); | 
 | 295 | 	if (err < 0) | 
 | 296 | 		return err; | 
 | 297 |  | 
 | 298 | 	err = snd_ctl_add(hal2->card, | 
 | 299 | 			  snd_ctl_new1(&hal2_ctrl_mic, hal2)); | 
 | 300 | 	if (err < 0) | 
 | 301 | 		return err; | 
 | 302 |  | 
 | 303 | 	return 0; | 
 | 304 | } | 
 | 305 |  | 
 | 306 | static irqreturn_t hal2_interrupt(int irq, void *dev_id) | 
 | 307 | { | 
 | 308 | 	struct snd_hal2 *hal2 = dev_id; | 
 | 309 | 	irqreturn_t ret = IRQ_NONE; | 
 | 310 |  | 
 | 311 | 	/* decide what caused this interrupt */ | 
 | 312 | 	if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) { | 
 | 313 | 		snd_pcm_period_elapsed(hal2->dac.substream); | 
 | 314 | 		ret = IRQ_HANDLED; | 
 | 315 | 	} | 
 | 316 | 	if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) { | 
 | 317 | 		snd_pcm_period_elapsed(hal2->adc.substream); | 
 | 318 | 		ret = IRQ_HANDLED; | 
 | 319 | 	} | 
 | 320 | 	return ret; | 
 | 321 | } | 
 | 322 |  | 
 | 323 | static int hal2_compute_rate(struct hal2_codec *codec, unsigned int rate) | 
 | 324 | { | 
 | 325 | 	unsigned short mod; | 
 | 326 |  | 
 | 327 | 	if (44100 % rate < 48000 % rate) { | 
 | 328 | 		mod = 4 * 44100 / rate; | 
 | 329 | 		codec->master = 44100; | 
 | 330 | 	} else { | 
 | 331 | 		mod = 4 * 48000 / rate; | 
 | 332 | 		codec->master = 48000; | 
 | 333 | 	} | 
 | 334 |  | 
 | 335 | 	codec->inc = 4; | 
 | 336 | 	codec->mod = mod; | 
 | 337 | 	rate = 4 * codec->master / mod; | 
 | 338 |  | 
 | 339 | 	return rate; | 
 | 340 | } | 
 | 341 |  | 
 | 342 | static void hal2_set_dac_rate(struct snd_hal2 *hal2) | 
 | 343 | { | 
 | 344 | 	unsigned int master = hal2->dac.master; | 
 | 345 | 	int inc = hal2->dac.inc; | 
 | 346 | 	int mod = hal2->dac.mod; | 
 | 347 |  | 
 | 348 | 	hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0); | 
 | 349 | 	hal2_i_write32(hal2, H2I_BRES1_C2, | 
 | 350 | 		       ((0xffff & (inc - mod - 1)) << 16) | inc); | 
 | 351 | } | 
 | 352 |  | 
 | 353 | static void hal2_set_adc_rate(struct snd_hal2 *hal2) | 
 | 354 | { | 
 | 355 | 	unsigned int master = hal2->adc.master; | 
 | 356 | 	int inc = hal2->adc.inc; | 
 | 357 | 	int mod = hal2->adc.mod; | 
 | 358 |  | 
 | 359 | 	hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0); | 
 | 360 | 	hal2_i_write32(hal2, H2I_BRES2_C2, | 
 | 361 | 		       ((0xffff & (inc - mod - 1)) << 16) | inc); | 
 | 362 | } | 
 | 363 |  | 
 | 364 | static void hal2_setup_dac(struct snd_hal2 *hal2) | 
 | 365 | { | 
 | 366 | 	unsigned int fifobeg, fifoend, highwater, sample_size; | 
 | 367 | 	struct hal2_pbus *pbus = &hal2->dac.pbus; | 
 | 368 |  | 
 | 369 | 	/* Now we set up some PBUS information. The PBUS needs information about | 
 | 370 | 	 * what portion of the fifo it will use. If it's receiving or | 
 | 371 | 	 * transmitting, and finally whether the stream is little endian or big | 
 | 372 | 	 * endian. The information is written later, on the start call. | 
 | 373 | 	 */ | 
 | 374 | 	sample_size = 2 * hal2->dac.voices; | 
 | 375 | 	/* Fifo should be set to hold exactly four samples. Highwater mark | 
 | 376 | 	 * should be set to two samples. */ | 
 | 377 | 	highwater = (sample_size * 2) >> 1;	/* halfwords */ | 
 | 378 | 	fifobeg = 0;				/* playback is first */ | 
 | 379 | 	fifoend = (sample_size * 4) >> 3;	/* doublewords */ | 
 | 380 | 	pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD | | 
 | 381 | 		     (highwater << 8) | (fifobeg << 16) | (fifoend << 24); | 
 | 382 | 	/* We disable everything before we do anything at all */ | 
 | 383 | 	pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; | 
 | 384 | 	hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX); | 
 | 385 | 	/* Setup the HAL2 for playback */ | 
 | 386 | 	hal2_set_dac_rate(hal2); | 
 | 387 | 	/* Set endianess */ | 
 | 388 | 	hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX); | 
 | 389 | 	/* Set DMA bus */ | 
 | 390 | 	hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); | 
 | 391 | 	/* We are using 1st Bresenham clock generator for playback */ | 
 | 392 | 	hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT) | 
 | 393 | 			| (1 << H2I_C1_CLKID_SHIFT) | 
 | 394 | 			| (hal2->dac.voices << H2I_C1_DATAT_SHIFT)); | 
 | 395 | } | 
 | 396 |  | 
 | 397 | static void hal2_setup_adc(struct snd_hal2 *hal2) | 
 | 398 | { | 
 | 399 | 	unsigned int fifobeg, fifoend, highwater, sample_size; | 
 | 400 | 	struct hal2_pbus *pbus = &hal2->adc.pbus; | 
 | 401 |  | 
 | 402 | 	sample_size = 2 * hal2->adc.voices; | 
 | 403 | 	highwater = (sample_size * 2) >> 1;		/* halfwords */ | 
 | 404 | 	fifobeg = (4 * 4) >> 3;				/* record is second */ | 
 | 405 | 	fifoend = (4 * 4 + sample_size * 4) >> 3;	/* doublewords */ | 
 | 406 | 	pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD | | 
 | 407 | 		     (highwater << 8) | (fifobeg << 16) | (fifoend << 24); | 
 | 408 | 	pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; | 
 | 409 | 	hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR); | 
 | 410 | 	/* Setup the HAL2 for record */ | 
 | 411 | 	hal2_set_adc_rate(hal2); | 
 | 412 | 	/* Set endianess */ | 
 | 413 | 	hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR); | 
 | 414 | 	/* Set DMA bus */ | 
 | 415 | 	hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr)); | 
 | 416 | 	/* We are using 2nd Bresenham clock generator for record */ | 
 | 417 | 	hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT) | 
 | 418 | 			| (2 << H2I_C1_CLKID_SHIFT) | 
 | 419 | 			| (hal2->adc.voices << H2I_C1_DATAT_SHIFT)); | 
 | 420 | } | 
 | 421 |  | 
 | 422 | static void hal2_start_dac(struct snd_hal2 *hal2) | 
 | 423 | { | 
 | 424 | 	struct hal2_pbus *pbus = &hal2->dac.pbus; | 
 | 425 |  | 
 | 426 | 	pbus->pbus->pbdma_dptr = hal2->dac.desc_dma; | 
 | 427 | 	pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; | 
 | 428 | 	/* enable DAC */ | 
 | 429 | 	hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX); | 
 | 430 | } | 
 | 431 |  | 
 | 432 | static void hal2_start_adc(struct snd_hal2 *hal2) | 
 | 433 | { | 
 | 434 | 	struct hal2_pbus *pbus = &hal2->adc.pbus; | 
 | 435 |  | 
 | 436 | 	pbus->pbus->pbdma_dptr = hal2->adc.desc_dma; | 
 | 437 | 	pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT; | 
 | 438 | 	/* enable ADC */ | 
 | 439 | 	hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR); | 
 | 440 | } | 
 | 441 |  | 
 | 442 | static inline void hal2_stop_dac(struct snd_hal2 *hal2) | 
 | 443 | { | 
 | 444 | 	hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; | 
 | 445 | 	/* The HAL2 itself may remain enabled safely */ | 
 | 446 | } | 
 | 447 |  | 
 | 448 | static inline void hal2_stop_adc(struct snd_hal2 *hal2) | 
 | 449 | { | 
 | 450 | 	hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD; | 
 | 451 | } | 
 | 452 |  | 
 | 453 | static int hal2_alloc_dmabuf(struct hal2_codec *codec) | 
 | 454 | { | 
 | 455 | 	struct hal2_desc *desc; | 
 | 456 | 	dma_addr_t desc_dma, buffer_dma; | 
 | 457 | 	int count = H2_BUF_SIZE / H2_BLOCK_SIZE; | 
 | 458 | 	int i; | 
 | 459 |  | 
 | 460 | 	codec->buffer = dma_alloc_noncoherent(NULL, H2_BUF_SIZE, | 
 | 461 | 					      &buffer_dma, GFP_KERNEL); | 
 | 462 | 	if (!codec->buffer) | 
 | 463 | 		return -ENOMEM; | 
 | 464 | 	desc = dma_alloc_noncoherent(NULL, count * sizeof(struct hal2_desc), | 
 | 465 | 				     &desc_dma, GFP_KERNEL); | 
 | 466 | 	if (!desc) { | 
 | 467 | 		dma_free_noncoherent(NULL, H2_BUF_SIZE, | 
 | 468 | 				     codec->buffer, buffer_dma); | 
 | 469 | 		return -ENOMEM; | 
 | 470 | 	} | 
 | 471 | 	codec->buffer_dma = buffer_dma; | 
 | 472 | 	codec->desc_dma = desc_dma; | 
 | 473 | 	codec->desc = desc; | 
 | 474 | 	for (i = 0; i < count; i++) { | 
 | 475 | 		desc->desc.pbuf = buffer_dma + i * H2_BLOCK_SIZE; | 
 | 476 | 		desc->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE; | 
 | 477 | 		desc->desc.pnext = (i == count - 1) ? | 
 | 478 | 		      desc_dma : desc_dma + (i + 1) * sizeof(struct hal2_desc); | 
 | 479 | 		desc++; | 
 | 480 | 	} | 
 | 481 | 	dma_cache_sync(NULL, codec->desc, count * sizeof(struct hal2_desc), | 
 | 482 | 		       DMA_TO_DEVICE); | 
 | 483 | 	codec->desc_count = count; | 
 | 484 | 	return 0; | 
 | 485 | } | 
 | 486 |  | 
 | 487 | static void hal2_free_dmabuf(struct hal2_codec *codec) | 
 | 488 | { | 
 | 489 | 	dma_free_noncoherent(NULL, codec->desc_count * sizeof(struct hal2_desc), | 
 | 490 | 			     codec->desc, codec->desc_dma); | 
 | 491 | 	dma_free_noncoherent(NULL, H2_BUF_SIZE, codec->buffer, | 
 | 492 | 			     codec->buffer_dma); | 
 | 493 | } | 
 | 494 |  | 
 | 495 | static struct snd_pcm_hardware hal2_pcm_hw = { | 
 | 496 | 	.info = (SNDRV_PCM_INFO_MMAP | | 
 | 497 | 		 SNDRV_PCM_INFO_MMAP_VALID | | 
 | 498 | 		 SNDRV_PCM_INFO_INTERLEAVED | | 
 | 499 | 		 SNDRV_PCM_INFO_BLOCK_TRANSFER), | 
 | 500 | 	.formats =          SNDRV_PCM_FMTBIT_S16_BE, | 
 | 501 | 	.rates =            SNDRV_PCM_RATE_8000_48000, | 
 | 502 | 	.rate_min =         8000, | 
 | 503 | 	.rate_max =         48000, | 
 | 504 | 	.channels_min =     2, | 
 | 505 | 	.channels_max =     2, | 
 | 506 | 	.buffer_bytes_max = 65536, | 
 | 507 | 	.period_bytes_min = 1024, | 
 | 508 | 	.period_bytes_max = 65536, | 
 | 509 | 	.periods_min =      2, | 
 | 510 | 	.periods_max =      1024, | 
 | 511 | }; | 
 | 512 |  | 
 | 513 | static int hal2_pcm_hw_params(struct snd_pcm_substream *substream, | 
 | 514 | 			      struct snd_pcm_hw_params *params) | 
 | 515 | { | 
 | 516 | 	int err; | 
 | 517 |  | 
 | 518 | 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | 
 | 519 | 	if (err < 0) | 
 | 520 | 		return err; | 
 | 521 |  | 
 | 522 | 	return 0; | 
 | 523 | } | 
 | 524 |  | 
 | 525 | static int hal2_pcm_hw_free(struct snd_pcm_substream *substream) | 
 | 526 | { | 
 | 527 | 	return snd_pcm_lib_free_pages(substream); | 
 | 528 | } | 
 | 529 |  | 
 | 530 | static int hal2_playback_open(struct snd_pcm_substream *substream) | 
 | 531 | { | 
 | 532 | 	struct snd_pcm_runtime *runtime = substream->runtime; | 
 | 533 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 534 | 	int err; | 
 | 535 |  | 
 | 536 | 	runtime->hw = hal2_pcm_hw; | 
 | 537 |  | 
 | 538 | 	err = hal2_alloc_dmabuf(&hal2->dac); | 
 | 539 | 	if (err) | 
 | 540 | 		return err; | 
 | 541 | 	return 0; | 
 | 542 | } | 
 | 543 |  | 
 | 544 | static int hal2_playback_close(struct snd_pcm_substream *substream) | 
 | 545 | { | 
 | 546 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 547 |  | 
 | 548 | 	hal2_free_dmabuf(&hal2->dac); | 
 | 549 | 	return 0; | 
 | 550 | } | 
 | 551 |  | 
 | 552 | static int hal2_playback_prepare(struct snd_pcm_substream *substream) | 
 | 553 | { | 
 | 554 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 555 | 	struct snd_pcm_runtime *runtime = substream->runtime; | 
 | 556 | 	struct hal2_codec *dac = &hal2->dac; | 
 | 557 |  | 
 | 558 | 	dac->voices = runtime->channels; | 
 | 559 | 	dac->sample_rate = hal2_compute_rate(dac, runtime->rate); | 
 | 560 | 	memset(&dac->pcm_indirect, 0, sizeof(dac->pcm_indirect)); | 
 | 561 | 	dac->pcm_indirect.hw_buffer_size = H2_BUF_SIZE; | 
 | 562 | 	dac->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); | 
 | 563 | 	dac->substream = substream; | 
 | 564 | 	hal2_setup_dac(hal2); | 
 | 565 | 	return 0; | 
 | 566 | } | 
 | 567 |  | 
 | 568 | static int hal2_playback_trigger(struct snd_pcm_substream *substream, int cmd) | 
 | 569 | { | 
 | 570 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 571 |  | 
 | 572 | 	switch (cmd) { | 
 | 573 | 	case SNDRV_PCM_TRIGGER_START: | 
 | 574 | 		hal2->dac.pcm_indirect.hw_io = hal2->dac.buffer_dma; | 
 | 575 | 		hal2->dac.pcm_indirect.hw_data = 0; | 
 | 576 | 		substream->ops->ack(substream); | 
 | 577 | 		hal2_start_dac(hal2); | 
 | 578 | 		break; | 
 | 579 | 	case SNDRV_PCM_TRIGGER_STOP: | 
 | 580 | 		hal2_stop_dac(hal2); | 
 | 581 | 		break; | 
 | 582 | 	default: | 
 | 583 | 		return -EINVAL; | 
 | 584 | 	} | 
 | 585 | 	return 0; | 
 | 586 | } | 
 | 587 |  | 
 | 588 | static snd_pcm_uframes_t | 
 | 589 | hal2_playback_pointer(struct snd_pcm_substream *substream) | 
 | 590 | { | 
 | 591 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 592 | 	struct hal2_codec *dac = &hal2->dac; | 
 | 593 |  | 
 | 594 | 	return snd_pcm_indirect_playback_pointer(substream, &dac->pcm_indirect, | 
 | 595 | 						 dac->pbus.pbus->pbdma_bptr); | 
 | 596 | } | 
 | 597 |  | 
 | 598 | static void hal2_playback_transfer(struct snd_pcm_substream *substream, | 
 | 599 | 				   struct snd_pcm_indirect *rec, size_t bytes) | 
 | 600 | { | 
 | 601 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 602 | 	unsigned char *buf = hal2->dac.buffer + rec->hw_data; | 
 | 603 |  | 
 | 604 | 	memcpy(buf, substream->runtime->dma_area + rec->sw_data, bytes); | 
 | 605 | 	dma_cache_sync(NULL, buf, bytes, DMA_TO_DEVICE); | 
 | 606 |  | 
 | 607 | } | 
 | 608 |  | 
 | 609 | static int hal2_playback_ack(struct snd_pcm_substream *substream) | 
 | 610 | { | 
 | 611 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 612 | 	struct hal2_codec *dac = &hal2->dac; | 
 | 613 |  | 
 | 614 | 	dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; | 
 | 615 | 	snd_pcm_indirect_playback_transfer(substream, | 
 | 616 | 					   &dac->pcm_indirect, | 
 | 617 | 					   hal2_playback_transfer); | 
 | 618 | 	return 0; | 
 | 619 | } | 
 | 620 |  | 
 | 621 | static int hal2_capture_open(struct snd_pcm_substream *substream) | 
 | 622 | { | 
 | 623 | 	struct snd_pcm_runtime *runtime = substream->runtime; | 
 | 624 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 625 | 	struct hal2_codec *adc = &hal2->adc; | 
 | 626 | 	int err; | 
 | 627 |  | 
 | 628 | 	runtime->hw = hal2_pcm_hw; | 
 | 629 |  | 
 | 630 | 	err = hal2_alloc_dmabuf(adc); | 
 | 631 | 	if (err) | 
 | 632 | 		return err; | 
 | 633 | 	return 0; | 
 | 634 | } | 
 | 635 |  | 
 | 636 | static int hal2_capture_close(struct snd_pcm_substream *substream) | 
 | 637 | { | 
 | 638 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 639 |  | 
 | 640 | 	hal2_free_dmabuf(&hal2->adc); | 
 | 641 | 	return 0; | 
 | 642 | } | 
 | 643 |  | 
 | 644 | static int hal2_capture_prepare(struct snd_pcm_substream *substream) | 
 | 645 | { | 
 | 646 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 647 | 	struct snd_pcm_runtime *runtime = substream->runtime; | 
 | 648 | 	struct hal2_codec *adc = &hal2->adc; | 
 | 649 |  | 
 | 650 | 	adc->voices = runtime->channels; | 
 | 651 | 	adc->sample_rate = hal2_compute_rate(adc, runtime->rate); | 
 | 652 | 	memset(&adc->pcm_indirect, 0, sizeof(adc->pcm_indirect)); | 
 | 653 | 	adc->pcm_indirect.hw_buffer_size = H2_BUF_SIZE; | 
 | 654 | 	adc->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; | 
 | 655 | 	adc->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); | 
 | 656 | 	adc->substream = substream; | 
 | 657 | 	hal2_setup_adc(hal2); | 
 | 658 | 	return 0; | 
 | 659 | } | 
 | 660 |  | 
 | 661 | static int hal2_capture_trigger(struct snd_pcm_substream *substream, int cmd) | 
 | 662 | { | 
 | 663 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 664 |  | 
 | 665 | 	switch (cmd) { | 
 | 666 | 	case SNDRV_PCM_TRIGGER_START: | 
 | 667 | 		hal2->adc.pcm_indirect.hw_io = hal2->adc.buffer_dma; | 
 | 668 | 		hal2->adc.pcm_indirect.hw_data = 0; | 
 | 669 | 		printk(KERN_DEBUG "buffer_dma %x\n", hal2->adc.buffer_dma); | 
 | 670 | 		hal2_start_adc(hal2); | 
 | 671 | 		break; | 
 | 672 | 	case SNDRV_PCM_TRIGGER_STOP: | 
 | 673 | 		hal2_stop_adc(hal2); | 
 | 674 | 		break; | 
 | 675 | 	default: | 
 | 676 | 		return -EINVAL; | 
 | 677 | 	} | 
 | 678 | 	return 0; | 
 | 679 | } | 
 | 680 |  | 
 | 681 | static snd_pcm_uframes_t | 
 | 682 | hal2_capture_pointer(struct snd_pcm_substream *substream) | 
 | 683 | { | 
 | 684 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 685 | 	struct hal2_codec *adc = &hal2->adc; | 
 | 686 |  | 
 | 687 | 	return snd_pcm_indirect_capture_pointer(substream, &adc->pcm_indirect, | 
 | 688 | 						adc->pbus.pbus->pbdma_bptr); | 
 | 689 | } | 
 | 690 |  | 
 | 691 | static void hal2_capture_transfer(struct snd_pcm_substream *substream, | 
 | 692 | 				  struct snd_pcm_indirect *rec, size_t bytes) | 
 | 693 | { | 
 | 694 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 695 | 	unsigned char *buf = hal2->adc.buffer + rec->hw_data; | 
 | 696 |  | 
 | 697 | 	dma_cache_sync(NULL, buf, bytes, DMA_FROM_DEVICE); | 
 | 698 | 	memcpy(substream->runtime->dma_area + rec->sw_data, buf, bytes); | 
 | 699 | } | 
 | 700 |  | 
 | 701 | static int hal2_capture_ack(struct snd_pcm_substream *substream) | 
 | 702 | { | 
 | 703 | 	struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 
 | 704 | 	struct hal2_codec *adc = &hal2->adc; | 
 | 705 |  | 
 | 706 | 	snd_pcm_indirect_capture_transfer(substream, | 
 | 707 | 					  &adc->pcm_indirect, | 
 | 708 | 					  hal2_capture_transfer); | 
 | 709 | 	return 0; | 
 | 710 | } | 
 | 711 |  | 
 | 712 | static struct snd_pcm_ops hal2_playback_ops = { | 
 | 713 | 	.open =        hal2_playback_open, | 
 | 714 | 	.close =       hal2_playback_close, | 
 | 715 | 	.ioctl =       snd_pcm_lib_ioctl, | 
 | 716 | 	.hw_params =   hal2_pcm_hw_params, | 
 | 717 | 	.hw_free =     hal2_pcm_hw_free, | 
 | 718 | 	.prepare =     hal2_playback_prepare, | 
 | 719 | 	.trigger =     hal2_playback_trigger, | 
 | 720 | 	.pointer =     hal2_playback_pointer, | 
 | 721 | 	.ack =         hal2_playback_ack, | 
 | 722 | }; | 
 | 723 |  | 
 | 724 | static struct snd_pcm_ops hal2_capture_ops = { | 
 | 725 | 	.open =        hal2_capture_open, | 
 | 726 | 	.close =       hal2_capture_close, | 
 | 727 | 	.ioctl =       snd_pcm_lib_ioctl, | 
 | 728 | 	.hw_params =   hal2_pcm_hw_params, | 
 | 729 | 	.hw_free =     hal2_pcm_hw_free, | 
 | 730 | 	.prepare =     hal2_capture_prepare, | 
 | 731 | 	.trigger =     hal2_capture_trigger, | 
 | 732 | 	.pointer =     hal2_capture_pointer, | 
 | 733 | 	.ack =         hal2_capture_ack, | 
 | 734 | }; | 
 | 735 |  | 
 | 736 | static int __devinit hal2_pcm_create(struct snd_hal2 *hal2) | 
 | 737 | { | 
 | 738 | 	struct snd_pcm *pcm; | 
 | 739 | 	int err; | 
 | 740 |  | 
 | 741 | 	/* create first pcm device with one outputs and one input */ | 
 | 742 | 	err = snd_pcm_new(hal2->card, "SGI HAL2 Audio", 0, 1, 1, &pcm); | 
 | 743 | 	if (err < 0) | 
 | 744 | 		return err; | 
 | 745 |  | 
 | 746 | 	pcm->private_data = hal2; | 
 | 747 | 	strcpy(pcm->name, "SGI HAL2"); | 
 | 748 |  | 
 | 749 | 	/* set operators */ | 
 | 750 | 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 
 | 751 | 			&hal2_playback_ops); | 
 | 752 | 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | 
 | 753 | 			&hal2_capture_ops); | 
 | 754 | 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, | 
 | 755 | 					   snd_dma_continuous_data(GFP_KERNEL), | 
 | 756 | 					   0, 1024 * 1024); | 
 | 757 |  | 
 | 758 | 	return 0; | 
 | 759 | } | 
 | 760 |  | 
 | 761 | static int hal2_dev_free(struct snd_device *device) | 
 | 762 | { | 
 | 763 | 	struct snd_hal2 *hal2 = device->device_data; | 
 | 764 |  | 
 | 765 | 	free_irq(SGI_HPCDMA_IRQ, hal2); | 
 | 766 | 	kfree(hal2); | 
 | 767 | 	return 0; | 
 | 768 | } | 
 | 769 |  | 
 | 770 | static struct snd_device_ops hal2_ops = { | 
 | 771 | 	.dev_free = hal2_dev_free, | 
 | 772 | }; | 
 | 773 |  | 
 | 774 | static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3, | 
 | 775 | 			    int index) | 
 | 776 | { | 
 | 777 | 	codec->pbus.pbusnr = index; | 
 | 778 | 	codec->pbus.pbus = &hpc3->pbdma[index]; | 
 | 779 | } | 
 | 780 |  | 
 | 781 | static int hal2_detect(struct snd_hal2 *hal2) | 
 | 782 | { | 
 | 783 | 	unsigned short board, major, minor; | 
 | 784 | 	unsigned short rev; | 
 | 785 |  | 
 | 786 | 	/* reset HAL2 */ | 
 | 787 | 	hal2_write(0, &hal2->ctl_regs->isr); | 
 | 788 |  | 
 | 789 | 	/* release reset */ | 
 | 790 | 	hal2_write(H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N, | 
 | 791 | 		   &hal2->ctl_regs->isr); | 
 | 792 |  | 
 | 793 |  | 
 | 794 | 	hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE); | 
 | 795 | 	rev = hal2_read(&hal2->ctl_regs->rev); | 
 | 796 | 	if (rev & H2_REV_AUDIO_PRESENT) | 
 | 797 | 		return -ENODEV; | 
 | 798 |  | 
 | 799 | 	board = (rev & H2_REV_BOARD_M) >> 12; | 
 | 800 | 	major = (rev & H2_REV_MAJOR_CHIP_M) >> 4; | 
 | 801 | 	minor = (rev & H2_REV_MINOR_CHIP_M); | 
 | 802 |  | 
 | 803 | 	printk(KERN_INFO "SGI HAL2 revision %i.%i.%i\n", | 
 | 804 | 	       board, major, minor); | 
 | 805 |  | 
 | 806 | 	return 0; | 
 | 807 | } | 
 | 808 |  | 
 | 809 | static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip) | 
 | 810 | { | 
 | 811 | 	struct snd_hal2 *hal2; | 
 | 812 | 	struct hpc3_regs *hpc3 = hpc3c0; | 
 | 813 | 	int err; | 
 | 814 |  | 
 | 815 | 	hal2 = kzalloc(sizeof(struct snd_hal2), GFP_KERNEL); | 
 | 816 | 	if (!hal2) | 
 | 817 | 		return -ENOMEM; | 
 | 818 |  | 
 | 819 | 	hal2->card = card; | 
 | 820 |  | 
 | 821 | 	if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, IRQF_SHARED, | 
 | 822 | 			"SGI HAL2", hal2)) { | 
 | 823 | 		printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ); | 
 | 824 | 		kfree(hal2); | 
 | 825 | 		return -EAGAIN; | 
 | 826 | 	} | 
 | 827 |  | 
 | 828 | 	hal2->ctl_regs = (struct hal2_ctl_regs *)hpc3->pbus_extregs[0]; | 
 | 829 | 	hal2->aes_regs = (struct hal2_aes_regs *)hpc3->pbus_extregs[1]; | 
 | 830 | 	hal2->vol_regs = (struct hal2_vol_regs *)hpc3->pbus_extregs[2]; | 
 | 831 | 	hal2->syn_regs = (struct hal2_syn_regs *)hpc3->pbus_extregs[3]; | 
 | 832 |  | 
 | 833 | 	if (hal2_detect(hal2) < 0) { | 
 | 834 | 		kfree(hal2); | 
 | 835 | 		return -ENODEV; | 
 | 836 | 	} | 
 | 837 |  | 
 | 838 | 	hal2_init_codec(&hal2->dac, hpc3, 0); | 
 | 839 | 	hal2_init_codec(&hal2->adc, hpc3, 1); | 
 | 840 |  | 
 | 841 | 	/* | 
 | 842 | 	 * All DMA channel interfaces in HAL2 are designed to operate with | 
 | 843 | 	 * PBUS programmed for 2 cycles in D3, 2 cycles in D4 and 2 cycles | 
 | 844 | 	 * in D5. HAL2 is a 16-bit device which can accept both big and little | 
 | 845 | 	 * endian format. It assumes that even address bytes are on high | 
 | 846 | 	 * portion of PBUS (15:8) and assumes that HPC3 is programmed to | 
 | 847 | 	 * accept a live (unsynchronized) version of P_DREQ_N from HAL2. | 
 | 848 | 	 */ | 
 | 849 | #define HAL2_PBUS_DMACFG ((0 << HPC3_DMACFG_D3R_SHIFT) | \ | 
 | 850 | 			  (2 << HPC3_DMACFG_D4R_SHIFT) | \ | 
 | 851 | 			  (2 << HPC3_DMACFG_D5R_SHIFT) | \ | 
 | 852 | 			  (0 << HPC3_DMACFG_D3W_SHIFT) | \ | 
 | 853 | 			  (2 << HPC3_DMACFG_D4W_SHIFT) | \ | 
 | 854 | 			  (2 << HPC3_DMACFG_D5W_SHIFT) | \ | 
 | 855 | 				HPC3_DMACFG_DS16 | \ | 
 | 856 | 				HPC3_DMACFG_EVENHI | \ | 
 | 857 | 				HPC3_DMACFG_RTIME | \ | 
 | 858 | 			  (8 << HPC3_DMACFG_BURST_SHIFT) | \ | 
 | 859 | 				HPC3_DMACFG_DRQLIVE) | 
 | 860 | 	/* | 
 | 861 | 	 * Ignore what's mentioned in the specification and write value which | 
 | 862 | 	 * works in The Real World (TM) | 
 | 863 | 	 */ | 
 | 864 | 	hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844; | 
 | 865 | 	hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844; | 
 | 866 |  | 
 | 867 | 	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, hal2, &hal2_ops); | 
 | 868 | 	if (err < 0) { | 
 | 869 | 		free_irq(SGI_HPCDMA_IRQ, hal2); | 
 | 870 | 		kfree(hal2); | 
 | 871 | 		return err; | 
 | 872 | 	} | 
 | 873 | 	*rchip = hal2; | 
 | 874 | 	return 0; | 
 | 875 | } | 
 | 876 |  | 
 | 877 | static int __devinit hal2_probe(struct platform_device *pdev) | 
 | 878 | { | 
 | 879 | 	struct snd_card *card; | 
 | 880 | 	struct snd_hal2 *chip; | 
 | 881 | 	int err; | 
 | 882 |  | 
| Takashi Iwai | bd7dd77 | 2008-12-28 16:45:02 +0100 | [diff] [blame] | 883 | 	err = snd_card_create(index, id, THIS_MODULE, 0, &card); | 
 | 884 | 	if (err < 0) | 
 | 885 | 		return err; | 
| Thomas Bogendoerfer | 787dba3 | 2008-07-12 12:12:20 +0200 | [diff] [blame] | 886 |  | 
 | 887 | 	err = hal2_create(card, &chip); | 
 | 888 | 	if (err < 0) { | 
 | 889 | 		snd_card_free(card); | 
 | 890 | 		return err; | 
 | 891 | 	} | 
 | 892 | 	snd_card_set_dev(card, &pdev->dev); | 
 | 893 |  | 
 | 894 | 	err = hal2_pcm_create(chip); | 
 | 895 | 	if (err < 0) { | 
 | 896 | 		snd_card_free(card); | 
 | 897 | 		return err; | 
 | 898 | 	} | 
 | 899 | 	err = hal2_mixer_create(chip); | 
 | 900 | 	if (err < 0) { | 
 | 901 | 		snd_card_free(card); | 
 | 902 | 		return err; | 
 | 903 | 	} | 
 | 904 |  | 
 | 905 | 	strcpy(card->driver, "SGI HAL2 Audio"); | 
 | 906 | 	strcpy(card->shortname, "SGI HAL2 Audio"); | 
 | 907 | 	sprintf(card->longname, "%s irq %i", | 
 | 908 | 		card->shortname, | 
 | 909 | 		SGI_HPCDMA_IRQ); | 
 | 910 |  | 
 | 911 | 	err = snd_card_register(card); | 
 | 912 | 	if (err < 0) { | 
 | 913 | 		snd_card_free(card); | 
 | 914 | 		return err; | 
 | 915 | 	} | 
 | 916 | 	platform_set_drvdata(pdev, card); | 
 | 917 | 	return 0; | 
 | 918 | } | 
 | 919 |  | 
| Takashi Iwai | 2f229a3 | 2009-10-02 11:04:54 +0200 | [diff] [blame] | 920 | static int __devexit hal2_remove(struct platform_device *pdev) | 
| Thomas Bogendoerfer | 787dba3 | 2008-07-12 12:12:20 +0200 | [diff] [blame] | 921 | { | 
 | 922 | 	struct snd_card *card = platform_get_drvdata(pdev); | 
 | 923 |  | 
 | 924 | 	snd_card_free(card); | 
 | 925 | 	platform_set_drvdata(pdev, NULL); | 
 | 926 | 	return 0; | 
 | 927 | } | 
 | 928 |  | 
 | 929 | static struct platform_driver hal2_driver = { | 
 | 930 | 	.probe	= hal2_probe, | 
 | 931 | 	.remove	= __devexit_p(hal2_remove), | 
 | 932 | 	.driver = { | 
 | 933 | 		.name	= "sgihal2", | 
 | 934 | 		.owner	= THIS_MODULE, | 
 | 935 | 	} | 
 | 936 | }; | 
 | 937 |  | 
| Axel Lin | 51451b8 | 2011-11-24 18:47:25 +0800 | [diff] [blame] | 938 | module_platform_driver(hal2_driver); |