876 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Driver for Atmel AC97C4 *5 * Copyright (C) 2005-2009 Atmel Corporation6 */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 */32static DEFINE_MUTEX(opened_mutex);33 34struct 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 63static const struct snd_pcm_hardware atmel_ac97c_hw = {64 .info = (SNDRV_PCM_INFO_MMAP65 | SNDRV_PCM_INFO_MMAP_VALID66 | SNDRV_PCM_INFO_INTERLEAVED67 | SNDRV_PCM_INFO_BLOCK_TRANSFER68 | SNDRV_PCM_INFO_JOINT_DUPLEX69 | SNDRV_PCM_INFO_RESUME70 | SNDRV_PCM_INFO_PAUSE),71 .formats = (SNDRV_PCM_FMTBIT_S16_BE72 | 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 85static 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 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 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 123static 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 140static 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 157static 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 171static 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 185static 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 else216 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 267static 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 else298 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 349static int350atmel_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 380static int381atmel_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 412static snd_pcm_uframes_t413atmel_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 429static snd_pcm_uframes_t430atmel_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 446static 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 455static 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 464static 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 539static 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 567static 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 598static 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 606static 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 626static 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 639retry_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 654read_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 667timed_out:668 dev_dbg(&chip->pdev->dev, "codec read timeout\n");669 return 0xffff;670}671 672static 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 691static const struct of_device_id atmel_ac97c_dt_ids[] = {692 { .compatible = "atmel,at91sam9263-ac97c", },693 { }694};695MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids);696 697static 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 807err_ac97_bus:808 iounmap(chip->regs);809err_ioremap:810 free_irq(irq, chip);811err_request_irq:812 snd_card_free(card);813err_snd_card_new:814 clk_disable_unprepare(pclk);815err_prepare_enable:816 clk_put(pclk);817 return retval;818}819 820#ifdef CONFIG_PM_SLEEP821static 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 830static 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 839static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume);840#define ATMEL_AC97C_PM_OPS &atmel_ac97c_pm841#else842#define ATMEL_AC97C_PM_OPS NULL843#endif844 845static 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 862static 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};871module_platform_driver(atmel_ac97c_driver);872 873MODULE_LICENSE("GPL");874MODULE_DESCRIPTION("Driver for Atmel AC97 controller");875MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");876