File Index
Files and directories
Sign in
FILE

ac97c.c

File preview with syntax highlighting.

linux-6.19.14/sound/atmel/ac97c.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Driver for Atmel AC97C
  4 *
  5 * Copyright (C) 2005-2009 Atmel Corporation
  6 */
  7#include <linux/clk.h>
  8#include <linux/delay.h>
  9#include <linux/bitmap.h>
 10#include <linux/device.h>
 11#include <linux/atmel_pdc.h>
 12#include <linux/gpio/consumer.h>
 13#include <linux/init.h>
 14#include <linux/interrupt.h>
 15#include <linux/mod_devicetable.h>
 16#include <linux/module.h>
 17#include <linux/platform_device.h>
 18#include <linux/mutex.h>
 19#include <linux/string.h>
 20#include <linux/types.h>
 21#include <linux/io.h>
 22
 23#include <sound/core.h>
 24#include <sound/initval.h>
 25#include <sound/pcm.h>
 26#include <sound/pcm_params.h>
 27#include <sound/ac97_codec.h>
 28#include <sound/memalloc.h>
 29
 30#include "ac97c.h"
 31
 32/* Serialize access to opened variable */
 33static DEFINE_MUTEX(opened_mutex);
 34
 35struct atmel_ac97c {
 36	struct clk			*pclk;
 37	struct platform_device		*pdev;
 38
 39	struct snd_pcm_substream	*playback_substream;
 40	struct snd_pcm_substream	*capture_substream;
 41	struct snd_card			*card;
 42	struct snd_pcm			*pcm;
 43	struct snd_ac97			*ac97;
 44	struct snd_ac97_bus		*ac97_bus;
 45
 46	u64				cur_format;
 47	unsigned int			cur_rate;
 48	int				playback_period, capture_period;
 49	/* Serialize access to opened variable */
 50	spinlock_t			lock;
 51	void __iomem			*regs;
 52	int				irq;
 53	int				opened;
 54	struct gpio_desc		*reset_pin;
 55};
 56
 57#define get_chip(card) ((struct atmel_ac97c *)(card)->private_data)
 58
 59#define ac97c_writel(chip, reg, val)			\
 60	__raw_writel((val), (chip)->regs + AC97C_##reg)
 61#define ac97c_readl(chip, reg)				\
 62	__raw_readl((chip)->regs + AC97C_##reg)
 63
 64static const struct snd_pcm_hardware atmel_ac97c_hw = {
 65	.info			= (SNDRV_PCM_INFO_MMAP
 66				  | SNDRV_PCM_INFO_MMAP_VALID
 67				  | SNDRV_PCM_INFO_INTERLEAVED
 68				  | SNDRV_PCM_INFO_BLOCK_TRANSFER
 69				  | SNDRV_PCM_INFO_JOINT_DUPLEX
 70				  | SNDRV_PCM_INFO_RESUME
 71				  | SNDRV_PCM_INFO_PAUSE),
 72	.formats		= (SNDRV_PCM_FMTBIT_S16_BE
 73				  | SNDRV_PCM_FMTBIT_S16_LE),
 74	.rates			= (SNDRV_PCM_RATE_CONTINUOUS),
 75	.rate_min		= 4000,
 76	.rate_max		= 48000,
 77	.channels_min		= 1,
 78	.channels_max		= 2,
 79	.buffer_bytes_max	= 2 * 2 * 64 * 2048,
 80	.period_bytes_min	= 4096,
 81	.period_bytes_max	= 4096,
 82	.periods_min		= 6,
 83	.periods_max		= 64,
 84};
 85
 86static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream)
 87{
 88	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
 89	struct snd_pcm_runtime *runtime = substream->runtime;
 90
 91	guard(mutex)(&opened_mutex);
 92	chip->opened++;
 93	runtime->hw = atmel_ac97c_hw;
 94	if (chip->cur_rate) {
 95		runtime->hw.rate_min = chip->cur_rate;
 96		runtime->hw.rate_max = chip->cur_rate;
 97	}
 98	if (chip->cur_format)
 99		runtime->hw.formats = pcm_format_to_bits(chip->cur_format);
100	chip->playback_substream = substream;
101	return 0;
102}
103
104static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream)
105{
106	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
107	struct snd_pcm_runtime *runtime = substream->runtime;
108
109	guard(mutex)(&opened_mutex);
110	chip->opened++;
111	runtime->hw = atmel_ac97c_hw;
112	if (chip->cur_rate) {
113		runtime->hw.rate_min = chip->cur_rate;
114		runtime->hw.rate_max = chip->cur_rate;
115	}
116	if (chip->cur_format)
117		runtime->hw.formats = pcm_format_to_bits(chip->cur_format);
118	chip->capture_substream = substream;
119	return 0;
120}
121
122static int atmel_ac97c_playback_close(struct snd_pcm_substream *substream)
123{
124	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
125
126	guard(mutex)(&opened_mutex);
127	chip->opened--;
128	if (!chip->opened) {
129		chip->cur_rate = 0;
130		chip->cur_format = 0;
131	}
132
133	chip->playback_substream = NULL;
134
135	return 0;
136}
137
138static int atmel_ac97c_capture_close(struct snd_pcm_substream *substream)
139{
140	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
141
142	guard(mutex)(&opened_mutex);
143	chip->opened--;
144	if (!chip->opened) {
145		chip->cur_rate = 0;
146		chip->cur_format = 0;
147	}
148
149	chip->capture_substream = NULL;
150
151	return 0;
152}
153
154static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
155		struct snd_pcm_hw_params *hw_params)
156{
157	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
158
159	/* Set restrictions to params. */
160	guard(mutex)(&opened_mutex);
161	chip->cur_rate = params_rate(hw_params);
162	chip->cur_format = params_format(hw_params);
163
164	return 0;
165}
166
167static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
168		struct snd_pcm_hw_params *hw_params)
169{
170	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
171
172	/* Set restrictions to params. */
173	guard(mutex)(&opened_mutex);
174	chip->cur_rate = params_rate(hw_params);
175	chip->cur_format = params_format(hw_params);
176
177	return 0;
178}
179
180static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
181{
182	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
183	struct snd_pcm_runtime *runtime = substream->runtime;
184	int block_size = frames_to_bytes(runtime, runtime->period_size);
185	unsigned long word = ac97c_readl(chip, OCA);
186	int retval;
187
188	chip->playback_period = 0;
189	word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
190
191	/* assign channels to AC97C channel A */
192	switch (runtime->channels) {
193	case 1:
194		word |= AC97C_CH_ASSIGN(PCM_LEFT, A);
195		break;
196	case 2:
197		word |= AC97C_CH_ASSIGN(PCM_LEFT, A)
198			| AC97C_CH_ASSIGN(PCM_RIGHT, A);
199		break;
200	default:
201		/* TODO: support more than two channels */
202		return -EINVAL;
203	}
204	ac97c_writel(chip, OCA, word);
205
206	/* configure sample format and size */
207	word = ac97c_readl(chip, CAMR);
208	if (chip->opened <= 1)
209		word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
210	else
211		word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
212
213	switch (runtime->format) {
214	case SNDRV_PCM_FORMAT_S16_LE:
215		break;
216	case SNDRV_PCM_FORMAT_S16_BE:
217		word &= ~(AC97C_CMR_CEM_LITTLE);
218		break;
219	default:
220		word = ac97c_readl(chip, OCA);
221		word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
222		ac97c_writel(chip, OCA, word);
223		return -EINVAL;
224	}
225
226	/* Enable underrun interrupt on channel A */
227	word |= AC97C_CSR_UNRUN;
228
229	ac97c_writel(chip, CAMR, word);
230
231	/* Enable channel A event interrupt */
232	word = ac97c_readl(chip, IMR);
233	word |= AC97C_SR_CAEVT;
234	ac97c_writel(chip, IER, word);
235
236	/* set variable rate if needed */
237	if (runtime->rate != 48000) {
238		word = ac97c_readl(chip, MR);
239		word |= AC97C_MR_VRA;
240		ac97c_writel(chip, MR, word);
241	} else {
242		word = ac97c_readl(chip, MR);
243		word &= ~(AC97C_MR_VRA);
244		ac97c_writel(chip, MR, word);
245	}
246
247	retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
248			runtime->rate);
249	if (retval)
250		dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
251				runtime->rate);
252
253	/* Initialize and start the PDC */
254	writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR);
255	writel(block_size / 2, chip->regs + ATMEL_PDC_TCR);
256	writel(runtime->dma_addr + block_size, chip->regs + ATMEL_PDC_TNPR);
257	writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR);
258
259	return retval;
260}
261
262static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
263{
264	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
265	struct snd_pcm_runtime *runtime = substream->runtime;
266	int block_size = frames_to_bytes(runtime, runtime->period_size);
267	unsigned long word = ac97c_readl(chip, ICA);
268	int retval;
269
270	chip->capture_period = 0;
271	word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
272
273	/* assign channels to AC97C channel A */
274	switch (runtime->channels) {
275	case 1:
276		word |= AC97C_CH_ASSIGN(PCM_LEFT, A);
277		break;
278	case 2:
279		word |= AC97C_CH_ASSIGN(PCM_LEFT, A)
280			| AC97C_CH_ASSIGN(PCM_RIGHT, A);
281		break;
282	default:
283		/* TODO: support more than two channels */
284		return -EINVAL;
285	}
286	ac97c_writel(chip, ICA, word);
287
288	/* configure sample format and size */
289	word = ac97c_readl(chip, CAMR);
290	if (chip->opened <= 1)
291		word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
292	else
293		word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
294
295	switch (runtime->format) {
296	case SNDRV_PCM_FORMAT_S16_LE:
297		break;
298	case SNDRV_PCM_FORMAT_S16_BE:
299		word &= ~(AC97C_CMR_CEM_LITTLE);
300		break;
301	default:
302		word = ac97c_readl(chip, ICA);
303		word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
304		ac97c_writel(chip, ICA, word);
305		return -EINVAL;
306	}
307
308	/* Enable overrun interrupt on channel A */
309	word |= AC97C_CSR_OVRUN;
310
311	ac97c_writel(chip, CAMR, word);
312
313	/* Enable channel A event interrupt */
314	word = ac97c_readl(chip, IMR);
315	word |= AC97C_SR_CAEVT;
316	ac97c_writel(chip, IER, word);
317
318	/* set variable rate if needed */
319	if (runtime->rate != 48000) {
320		word = ac97c_readl(chip, MR);
321		word |= AC97C_MR_VRA;
322		ac97c_writel(chip, MR, word);
323	} else {
324		word = ac97c_readl(chip, MR);
325		word &= ~(AC97C_MR_VRA);
326		ac97c_writel(chip, MR, word);
327	}
328
329	retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE,
330			runtime->rate);
331	if (retval)
332		dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
333				runtime->rate);
334
335	/* Initialize and start the PDC */
336	writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR);
337	writel(block_size / 2, chip->regs + ATMEL_PDC_RCR);
338	writel(runtime->dma_addr + block_size, chip->regs + ATMEL_PDC_RNPR);
339	writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR);
340
341	return retval;
342}
343
344static int
345atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
346{
347	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
348	unsigned long camr, ptcr = 0;
349
350	camr = ac97c_readl(chip, CAMR);
351
352	switch (cmd) {
353	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
354	case SNDRV_PCM_TRIGGER_RESUME:
355	case SNDRV_PCM_TRIGGER_START:
356		ptcr = ATMEL_PDC_TXTEN;
357		camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX;
358		break;
359	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
360	case SNDRV_PCM_TRIGGER_SUSPEND:
361	case SNDRV_PCM_TRIGGER_STOP:
362		ptcr |= ATMEL_PDC_TXTDIS;
363		if (chip->opened <= 1)
364			camr &= ~AC97C_CMR_CENA;
365		break;
366	default:
367		return -EINVAL;
368	}
369
370	ac97c_writel(chip, CAMR, camr);
371	writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
372	return 0;
373}
374
375static int
376atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
377{
378	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
379	unsigned long camr, ptcr = 0;
380
381	camr = ac97c_readl(chip, CAMR);
382	ptcr = readl(chip->regs + ATMEL_PDC_PTSR);
383
384	switch (cmd) {
385	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
386	case SNDRV_PCM_TRIGGER_RESUME:
387	case SNDRV_PCM_TRIGGER_START:
388		ptcr = ATMEL_PDC_RXTEN;
389		camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX;
390		break;
391	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
392	case SNDRV_PCM_TRIGGER_SUSPEND:
393	case SNDRV_PCM_TRIGGER_STOP:
394		ptcr |= ATMEL_PDC_RXTDIS;
395		if (chip->opened <= 1)
396			camr &= ~AC97C_CMR_CENA;
397		break;
398	default:
399		return -EINVAL;
400	}
401
402	ac97c_writel(chip, CAMR, camr);
403	writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
404	return 0;
405}
406
407static snd_pcm_uframes_t
408atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
409{
410	struct atmel_ac97c	*chip = snd_pcm_substream_chip(substream);
411	struct snd_pcm_runtime	*runtime = substream->runtime;
412	snd_pcm_uframes_t	frames;
413	unsigned long		bytes;
414
415	bytes = readl(chip->regs + ATMEL_PDC_TPR);
416	bytes -= runtime->dma_addr;
417
418	frames = bytes_to_frames(runtime, bytes);
419	if (frames >= runtime->buffer_size)
420		frames -= runtime->buffer_size;
421	return frames;
422}
423
424static snd_pcm_uframes_t
425atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
426{
427	struct atmel_ac97c	*chip = snd_pcm_substream_chip(substream);
428	struct snd_pcm_runtime	*runtime = substream->runtime;
429	snd_pcm_uframes_t	frames;
430	unsigned long		bytes;
431
432	bytes = readl(chip->regs + ATMEL_PDC_RPR);
433	bytes -= runtime->dma_addr;
434
435	frames = bytes_to_frames(runtime, bytes);
436	if (frames >= runtime->buffer_size)
437		frames -= runtime->buffer_size;
438	return frames;
439}
440
441static const struct snd_pcm_ops atmel_ac97_playback_ops = {
442	.open		= atmel_ac97c_playback_open,
443	.close		= atmel_ac97c_playback_close,
444	.hw_params	= atmel_ac97c_playback_hw_params,
445	.prepare	= atmel_ac97c_playback_prepare,
446	.trigger	= atmel_ac97c_playback_trigger,
447	.pointer	= atmel_ac97c_playback_pointer,
448};
449
450static const struct snd_pcm_ops atmel_ac97_capture_ops = {
451	.open		= atmel_ac97c_capture_open,
452	.close		= atmel_ac97c_capture_close,
453	.hw_params	= atmel_ac97c_capture_hw_params,
454	.prepare	= atmel_ac97c_capture_prepare,
455	.trigger	= atmel_ac97c_capture_trigger,
456	.pointer	= atmel_ac97c_capture_pointer,
457};
458
459static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
460{
461	struct atmel_ac97c	*chip  = (struct atmel_ac97c *)dev;
462	irqreturn_t		retval = IRQ_NONE;
463	u32			sr     = ac97c_readl(chip, SR);
464	u32			casr   = ac97c_readl(chip, CASR);
465	u32			cosr   = ac97c_readl(chip, COSR);
466	u32			camr   = ac97c_readl(chip, CAMR);
467
468	if (sr & AC97C_SR_CAEVT) {
469		struct snd_pcm_runtime *runtime;
470		int offset, next_period, block_size;
471		dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
472			(casr & AC97C_CSR_OVRUN)   ? " OVRUN"   : "",
473			(casr & AC97C_CSR_RXRDY)   ? " RXRDY"   : "",
474			(casr & AC97C_CSR_UNRUN)   ? " UNRUN"   : "",
475			(casr & AC97C_CSR_TXEMPTY) ? " TXEMPTY" : "",
476			(casr & AC97C_CSR_TXRDY)   ? " TXRDY"   : "",
477			!casr                      ? " NONE"    : "");
478		if ((casr & camr) & AC97C_CSR_ENDTX) {
479			runtime = chip->playback_substream->runtime;
480			block_size = frames_to_bytes(runtime, runtime->period_size);
481			chip->playback_period++;
482
483			if (chip->playback_period == runtime->periods)
484				chip->playback_period = 0;
485			next_period = chip->playback_period + 1;
486			if (next_period == runtime->periods)
487				next_period = 0;
488
489			offset = block_size * next_period;
490
491			writel(runtime->dma_addr + offset, chip->regs + ATMEL_PDC_TNPR);
492			writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR);
493
494			snd_pcm_period_elapsed(chip->playback_substream);
495		}
496		if ((casr & camr) & AC97C_CSR_ENDRX) {
497			runtime = chip->capture_substream->runtime;
498			block_size = frames_to_bytes(runtime, runtime->period_size);
499			chip->capture_period++;
500
501			if (chip->capture_period == runtime->periods)
502				chip->capture_period = 0;
503			next_period = chip->capture_period + 1;
504			if (next_period == runtime->periods)
505				next_period = 0;
506
507			offset = block_size * next_period;
508
509			writel(runtime->dma_addr + offset, chip->regs + ATMEL_PDC_RNPR);
510			writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR);
511			snd_pcm_period_elapsed(chip->capture_substream);
512		}
513		retval = IRQ_HANDLED;
514	}
515
516	if (sr & AC97C_SR_COEVT) {
517		dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
518			 (cosr & AC97C_CSR_OVRUN)   ? " OVRUN"   : "",
519			 (cosr & AC97C_CSR_RXRDY)   ? " RXRDY"   : "",
520			 (cosr & AC97C_CSR_TXEMPTY) ? " TXEMPTY" : "",
521			 (cosr & AC97C_CSR_TXRDY)   ? " TXRDY"   : "",
522			 !cosr                      ? " NONE"    : "");
523		retval = IRQ_HANDLED;
524	}
525
526	if (retval == IRQ_NONE) {
527		dev_err(&chip->pdev->dev, "spurious interrupt sr 0x%08x "
528				"casr 0x%08x cosr 0x%08x\n", sr, casr, cosr);
529	}
530
531	return retval;
532}
533
534static const struct ac97_pcm at91_ac97_pcm_defs[] = {
535	/* Playback */
536	{
537		.exclusive = 1,
538		.r = { {
539			.slots = ((1 << AC97_SLOT_PCM_LEFT)
540				  | (1 << AC97_SLOT_PCM_RIGHT)),
541		} },
542	},
543	/* PCM in */
544	{
545		.stream = 1,
546		.exclusive = 1,
547		.r = { {
548			.slots = ((1 << AC97_SLOT_PCM_LEFT)
549					| (1 << AC97_SLOT_PCM_RIGHT)),
550		} }
551	},
552	/* Mic in */
553	{
554		.stream = 1,
555		.exclusive = 1,
556		.r = { {
557			.slots = (1<<AC97_SLOT_MIC),
558		} }
559	},
560};
561
562static int atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
563{
564	struct snd_pcm		*pcm;
565	struct snd_pcm_hardware	hw = atmel_ac97c_hw;
566	int			retval;
567
568	retval = snd_ac97_pcm_assign(chip->ac97_bus,
569				     ARRAY_SIZE(at91_ac97_pcm_defs),
570				     at91_ac97_pcm_defs);
571	if (retval)
572		return retval;
573
574	retval = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
575	if (retval)
576		return retval;
577
578	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &atmel_ac97_capture_ops);
579	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &atmel_ac97_playback_ops);
580
581	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
582			&chip->pdev->dev, hw.periods_min * hw.period_bytes_min,
583			hw.buffer_bytes_max);
584
585	pcm->private_data = chip;
586	pcm->info_flags = 0;
587	strscpy(pcm->name, chip->card->shortname);
588	chip->pcm = pcm;
589
590	return 0;
591}
592
593static int atmel_ac97c_mixer_new(struct atmel_ac97c *chip)
594{
595	struct snd_ac97_template template;
596	memset(&template, 0, sizeof(template));
597	template.private_data = chip;
598	return snd_ac97_mixer(chip->ac97_bus, &template, &chip->ac97);
599}
600
601static void atmel_ac97c_write(struct snd_ac97 *ac97, unsigned short reg,
602		unsigned short val)
603{
604	struct atmel_ac97c *chip = get_chip(ac97);
605	unsigned long word;
606	int timeout = 40;
607
608	word = (reg & 0x7f) << 16 | val;
609
610	do {
611		if (ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) {
612			ac97c_writel(chip, COTHR, word);
613			return;
614		}
615		udelay(1);
616	} while (--timeout);
617
618	dev_dbg(&chip->pdev->dev, "codec write timeout\n");
619}
620
621static unsigned short atmel_ac97c_read(struct snd_ac97 *ac97,
622		unsigned short reg)
623{
624	struct atmel_ac97c *chip = get_chip(ac97);
625	unsigned long word;
626	int timeout = 40;
627	int write = 10;
628
629	word = (0x80 | (reg & 0x7f)) << 16;
630
631	if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0)
632		ac97c_readl(chip, CORHR);
633
634retry_write:
635	timeout = 40;
636
637	do {
638		if ((ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) != 0) {
639			ac97c_writel(chip, COTHR, word);
640			goto read_reg;
641		}
642		udelay(10);
643	} while (--timeout);
644
645	if (!--write)
646		goto timed_out;
647	goto retry_write;
648
649read_reg:
650	do {
651		if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) {
652			unsigned short val = ac97c_readl(chip, CORHR);
653			return val;
654		}
655		udelay(10);
656	} while (--timeout);
657
658	if (!--write)
659		goto timed_out;
660	goto retry_write;
661
662timed_out:
663	dev_dbg(&chip->pdev->dev, "codec read timeout\n");
664	return 0xffff;
665}
666
667static void atmel_ac97c_reset(struct atmel_ac97c *chip)
668{
669	ac97c_writel(chip, MR,   0);
670	ac97c_writel(chip, MR,   AC97C_MR_ENA);
671	ac97c_writel(chip, CAMR, 0);
672	ac97c_writel(chip, COMR, 0);
673
674	if (!IS_ERR(chip->reset_pin)) {
675		gpiod_set_value(chip->reset_pin, 0);
676		/* AC97 v2.2 specifications says minimum 1 us. */
677		udelay(2);
678		gpiod_set_value(chip->reset_pin, 1);
679	} else {
680		ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA);
681		udelay(2);
682		ac97c_writel(chip, MR, AC97C_MR_ENA);
683	}
684}
685
686static const struct of_device_id atmel_ac97c_dt_ids[] = {
687	{ .compatible = "atmel,at91sam9263-ac97c", },
688	{ }
689};
690MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids);
691
692static int atmel_ac97c_probe(struct platform_device *pdev)
693{
694	struct device			*dev = &pdev->dev;
695	struct snd_card			*card;
696	struct atmel_ac97c		*chip;
697	struct resource			*regs;
698	struct clk			*pclk;
699	static const struct snd_ac97_bus_ops	ops = {
700		.write	= atmel_ac97c_write,
701		.read	= atmel_ac97c_read,
702	};
703	int				retval;
704	int				irq;
705
706	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
707	if (!regs) {
708		dev_dbg(&pdev->dev, "no memory resource\n");
709		return -ENXIO;
710	}
711
712	irq = platform_get_irq(pdev, 0);
713	if (irq < 0) {
714		dev_dbg(&pdev->dev, "could not get irq: %d\n", irq);
715		return irq;
716	}
717
718	pclk = clk_get(&pdev->dev, "ac97_clk");
719	if (IS_ERR(pclk)) {
720		dev_dbg(&pdev->dev, "no peripheral clock\n");
721		return PTR_ERR(pclk);
722	}
723	retval = clk_prepare_enable(pclk);
724	if (retval)
725		goto err_prepare_enable;
726
727	retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
728			      SNDRV_DEFAULT_STR1, THIS_MODULE,
729			      sizeof(struct atmel_ac97c), &card);
730	if (retval) {
731		dev_dbg(&pdev->dev, "could not create sound card device\n");
732		goto err_snd_card_new;
733	}
734
735	chip = get_chip(card);
736
737	retval = request_irq(irq, atmel_ac97c_interrupt, 0, "AC97C", chip);
738	if (retval) {
739		dev_dbg(&pdev->dev, "unable to request irq %d\n", irq);
740		goto err_request_irq;
741	}
742	chip->irq = irq;
743
744	spin_lock_init(&chip->lock);
745
746	strscpy(card->driver, "Atmel AC97C");
747	strscpy(card->shortname, "Atmel AC97C");
748	strscpy(card->longname, "Atmel AC97 controller");
749
750	chip->card = card;
751	chip->pclk = pclk;
752	chip->pdev = pdev;
753	chip->regs = ioremap(regs->start, resource_size(regs));
754
755	if (!chip->regs) {
756		dev_dbg(&pdev->dev, "could not remap register memory\n");
757		retval = -ENOMEM;
758		goto err_ioremap;
759	}
760
761	chip->reset_pin = devm_gpiod_get_index(dev, "ac97", 2, GPIOD_OUT_HIGH);
762	if (IS_ERR(chip->reset_pin))
763		dev_dbg(dev, "reset pin not available\n");
764
765	atmel_ac97c_reset(chip);
766
767	/* Enable overrun interrupt from codec channel */
768	ac97c_writel(chip, COMR, AC97C_CSR_OVRUN);
769	ac97c_writel(chip, IER, ac97c_readl(chip, IMR) | AC97C_SR_COEVT);
770
771	retval = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
772	if (retval) {
773		dev_dbg(&pdev->dev, "could not register on ac97 bus\n");
774		goto err_ac97_bus;
775	}
776
777	retval = atmel_ac97c_mixer_new(chip);
778	if (retval) {
779		dev_dbg(&pdev->dev, "could not register ac97 mixer\n");
780		goto err_ac97_bus;
781	}
782
783	retval = atmel_ac97c_pcm_new(chip);
784	if (retval) {
785		dev_dbg(&pdev->dev, "could not register ac97 pcm device\n");
786		goto err_ac97_bus;
787	}
788
789	retval = snd_card_register(card);
790	if (retval) {
791		dev_dbg(&pdev->dev, "could not register sound card\n");
792		goto err_ac97_bus;
793	}
794
795	platform_set_drvdata(pdev, card);
796
797	dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n",
798			chip->regs, irq);
799
800	return 0;
801
802err_ac97_bus:
803	iounmap(chip->regs);
804err_ioremap:
805	free_irq(irq, chip);
806err_request_irq:
807	snd_card_free(card);
808err_snd_card_new:
809	clk_disable_unprepare(pclk);
810err_prepare_enable:
811	clk_put(pclk);
812	return retval;
813}
814
815static int atmel_ac97c_suspend(struct device *pdev)
816{
817	struct snd_card *card = dev_get_drvdata(pdev);
818	struct atmel_ac97c *chip = card->private_data;
819
820	clk_disable_unprepare(chip->pclk);
821	return 0;
822}
823
824static int atmel_ac97c_resume(struct device *pdev)
825{
826	struct snd_card *card = dev_get_drvdata(pdev);
827	struct atmel_ac97c *chip = card->private_data;
828	int ret = clk_prepare_enable(chip->pclk);
829
830	return ret;
831}
832
833static DEFINE_SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume);
834
835static void atmel_ac97c_remove(struct platform_device *pdev)
836{
837	struct snd_card *card = platform_get_drvdata(pdev);
838	struct atmel_ac97c *chip = get_chip(card);
839
840	ac97c_writel(chip, CAMR, 0);
841	ac97c_writel(chip, COMR, 0);
842	ac97c_writel(chip, MR,   0);
843
844	clk_disable_unprepare(chip->pclk);
845	clk_put(chip->pclk);
846	iounmap(chip->regs);
847	free_irq(chip->irq, chip);
848
849	snd_card_free(card);
850}
851
852static struct platform_driver atmel_ac97c_driver = {
853	.probe		= atmel_ac97c_probe,
854	.remove		= atmel_ac97c_remove,
855	.driver		= {
856		.name	= "atmel_ac97c",
857		.pm	= pm_ptr(&atmel_ac97c_pm),
858		.of_match_table = atmel_ac97c_dt_ids,
859	},
860};
861module_platform_driver(atmel_ac97c_driver);
862
863MODULE_LICENSE("GPL");
864MODULE_DESCRIPTION("Driver for Atmel AC97 controller");
865MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
~/ Read-only file preview.