~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/atmel/ac97c.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php