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