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

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

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/atmel/ac97c.c (Architecture sparc64) and /sound/atmel/ac97c.c (Architecture m68k)


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