Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hac.c
Go to the documentation of this file.
1 /*
2  * Hitachi Audio Controller (AC97) support for SH7760/SH7780
3  *
4  * Copyright (c) 2007 Manuel Lauss <[email protected]>
5  * licensed under the terms outlined in the file COPYING at the root
6  * of the linux kernel sources.
7  *
8  * dont forget to set IPSEL/OMSEL register bits (in your board code) to
9  * enable HAC output pins!
10  */
11 
12 /* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only
13  * the FIRST can be used since ASoC does not pass any information to the
14  * ac97_read/write() functions regarding WHICH unit to use. You'll have
15  * to edit the code a bit to use the other AC97 unit. --mlau
16  */
17 
18 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/interrupt.h>
22 #include <linux/wait.h>
23 #include <linux/delay.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #include <sound/ac97_codec.h>
27 #include <sound/initval.h>
28 #include <sound/soc.h>
29 
30 /* regs and bits */
31 #define HACCR 0x08
32 #define HACCSAR 0x20
33 #define HACCSDR 0x24
34 #define HACPCML 0x28
35 #define HACPCMR 0x2C
36 #define HACTIER 0x50
37 #define HACTSR 0x54
38 #define HACRIER 0x58
39 #define HACRSR 0x5C
40 #define HACACR 0x60
41 
42 #define CR_CR (1 << 15) /* "codec-ready" indicator */
43 #define CR_CDRT (1 << 11) /* cold reset */
44 #define CR_WMRT (1 << 10) /* warm reset */
45 #define CR_B9 (1 << 9) /* the mysterious "bit 9" */
46 #define CR_ST (1 << 5) /* AC97 link start bit */
47 
48 #define CSAR_RD (1 << 19) /* AC97 data read bit */
49 #define CSAR_WR (0)
50 
51 #define TSR_CMDAMT (1 << 31)
52 #define TSR_CMDDMT (1 << 30)
53 
54 #define RSR_STARY (1 << 22)
55 #define RSR_STDRY (1 << 21)
56 
57 #define ACR_DMARX16 (1 << 30)
58 #define ACR_DMATX16 (1 << 29)
59 #define ACR_TX12ATOM (1 << 26)
60 #define ACR_DMARX20 ((1 << 24) | (1 << 22))
61 #define ACR_DMATX20 ((1 << 23) | (1 << 21))
62 
63 #define CSDR_SHIFT 4
64 #define CSDR_MASK (0xffff << CSDR_SHIFT)
65 #define CSAR_SHIFT 12
66 #define CSAR_MASK (0x7f << CSAR_SHIFT)
67 
68 #define AC97_WRITE_RETRY 1
69 #define AC97_READ_RETRY 5
70 
71 /* manual-suggested AC97 codec access timeouts (us) */
72 #define TMO_E1 500 /* 21 < E1 < 1000 */
73 #define TMO_E2 13 /* 13 < E2 */
74 #define TMO_E3 21 /* 21 < E3 */
75 #define TMO_E4 500 /* 21 < E4 < 1000 */
76 
77 struct hac_priv {
78  unsigned long mmio; /* HAC base address */
79 } hac_cpu_data[] = {
80 #if defined(CONFIG_CPU_SUBTYPE_SH7760)
81  {
82  .mmio = 0xFE240000,
83  },
84  {
85  .mmio = 0xFE250000,
86  },
87 #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
88  {
89  .mmio = 0xFFE40000,
90  },
91 #else
92 #error "Unsupported SuperH SoC"
93 #endif
94 };
95 
96 #define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg)))
97 
98 /*
99  * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906)
100  */
101 static int hac_get_codec_data(struct hac_priv *hac, unsigned short r,
102  unsigned short *v)
103 {
104  unsigned int to1, to2, i;
105  unsigned short adr;
106 
107  for (i = AC97_READ_RETRY; i; i--) {
108  *v = 0;
109  /* wait for HAC to receive something from the codec */
110  for (to1 = TMO_E4;
111  to1 && !(HACREG(HACRSR) & RSR_STARY);
112  --to1)
113  udelay(1);
114  for (to2 = TMO_E4;
115  to2 && !(HACREG(HACRSR) & RSR_STDRY);
116  --to2)
117  udelay(1);
118 
119  if (!to1 && !to2)
120  return 0; /* codec comm is down */
121 
122  adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT);
123  *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT);
124 
125  HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
126 
127  if (r == adr)
128  break;
129 
130  /* manual says: wait at least 21 usec before retrying */
131  udelay(21);
132  }
133  HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
134  return i;
135 }
136 
137 static unsigned short hac_read_codec_aux(struct hac_priv *hac,
138  unsigned short reg)
139 {
140  unsigned short val;
141  unsigned int i, to;
142 
143  for (i = AC97_READ_RETRY; i; i--) {
144  /* send_read_request */
146  HACREG(HACTSR) &= ~(TSR_CMDAMT);
147  HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD;
149 
150  for (to = TMO_E3;
151  to && !(HACREG(HACTSR) & TSR_CMDAMT);
152  --to)
153  udelay(1);
154 
155  HACREG(HACTSR) &= ~TSR_CMDAMT;
156  val = 0;
157  if (hac_get_codec_data(hac, reg, &val) != 0)
158  break;
159  }
160 
161  return i ? val : ~0;
162 }
163 
164 static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
165  unsigned short val)
166 {
167  int unit_id = 0 /* ac97->private_data */;
168  struct hac_priv *hac = &hac_cpu_data[unit_id];
169  unsigned int i, to;
170  /* write_codec_aux */
171  for (i = AC97_WRITE_RETRY; i; i--) {
172  /* send_write_request */
175  HACREG(HACCSDR) = (val << CSDR_SHIFT);
176  HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD);
178 
179  /* poll-wait for CMDAMT and CMDDMT */
180  for (to = TMO_E1;
181  to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT));
182  --to)
183  udelay(1);
184 
186  if (to)
187  break;
188  /* timeout, try again */
189  }
190 }
191 
192 static unsigned short hac_ac97_read(struct snd_ac97 *ac97,
193  unsigned short reg)
194 {
195  int unit_id = 0 /* ac97->private_data */;
196  struct hac_priv *hac = &hac_cpu_data[unit_id];
197  return hac_read_codec_aux(hac, reg);
198 }
199 
200 static void hac_ac97_warmrst(struct snd_ac97 *ac97)
201 {
202  int unit_id = 0 /* ac97->private_data */;
203  struct hac_priv *hac = &hac_cpu_data[unit_id];
204  unsigned int tmo;
205 
206  HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9;
207  msleep(10);
208  HACREG(HACCR) = CR_ST | CR_B9;
209  for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--)
210  udelay(1);
211 
212  if (!tmo)
213  printk(KERN_INFO "hac: reset: AC97 link down!\n");
214  /* settings this bit lets us have a conversation with codec */
216 }
217 
218 static void hac_ac97_coldrst(struct snd_ac97 *ac97)
219 {
220  int unit_id = 0 /* ac97->private_data */;
221  struct hac_priv *hac;
222  hac = &hac_cpu_data[unit_id];
223 
224  HACREG(HACCR) = 0;
225  HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9;
226  msleep(10);
227  hac_ac97_warmrst(ac97);
228 }
229 
231  .read = hac_ac97_read,
232  .write = hac_ac97_write,
233  .reset = hac_ac97_coldrst,
234  .warm_reset = hac_ac97_warmrst,
235 };
236 EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 
238 static int hac_hw_params(struct snd_pcm_substream *substream,
239  struct snd_pcm_hw_params *params,
240  struct snd_soc_dai *dai)
241 {
242  struct hac_priv *hac = &hac_cpu_data[dai->id];
243  int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
244 
245  switch (params->msbits) {
246  case 16:
248  HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20;
249  break;
250  case 20:
251  HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16;
253  break;
254  default:
255  pr_debug("hac: invalid depth %d bit\n", params->msbits);
256  return -EINVAL;
257  break;
258  }
259 
260  return 0;
261 }
262 
263 #define AC97_RATES \
264  SNDRV_PCM_RATE_8000_192000
265 
266 #define AC97_FMTS \
267  SNDRV_PCM_FMTBIT_S16_LE
268 
269 static const struct snd_soc_dai_ops hac_dai_ops = {
270  .hw_params = hac_hw_params,
271 };
272 
273 static struct snd_soc_dai_driver sh4_hac_dai[] = {
274 {
275  .name = "hac-dai.0",
276  .ac97_control = 1,
277  .playback = {
278  .rates = AC97_RATES,
279  .formats = AC97_FMTS,
280  .channels_min = 2,
281  .channels_max = 2,
282  },
283  .capture = {
284  .rates = AC97_RATES,
285  .formats = AC97_FMTS,
286  .channels_min = 2,
287  .channels_max = 2,
288  },
289  .ops = &hac_dai_ops,
290 },
291 #ifdef CONFIG_CPU_SUBTYPE_SH7760
292 {
293  .name = "hac-dai.1",
294  .id = 1,
295  .playback = {
296  .rates = AC97_RATES,
297  .formats = AC97_FMTS,
298  .channels_min = 2,
299  .channels_max = 2,
300  },
301  .capture = {
302  .rates = AC97_RATES,
303  .formats = AC97_FMTS,
304  .channels_min = 2,
305  .channels_max = 2,
306  },
307  .ops = &hac_dai_ops,
308 
309 },
310 #endif
311 };
312 
313 static int __devinit hac_soc_platform_probe(struct platform_device *pdev)
314 {
315  return snd_soc_register_dais(&pdev->dev, sh4_hac_dai,
316  ARRAY_SIZE(sh4_hac_dai));
317 }
318 
319 static int __devexit hac_soc_platform_remove(struct platform_device *pdev)
320 {
321  snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai));
322  return 0;
323 }
324 
325 static struct platform_driver hac_pcm_driver = {
326  .driver = {
327  .name = "hac-pcm-audio",
328  .owner = THIS_MODULE,
329  },
330 
331  .probe = hac_soc_platform_probe,
332  .remove = __devexit_p(hac_soc_platform_remove),
333 };
334 
335 module_platform_driver(hac_pcm_driver);
336 
337 MODULE_LICENSE("GPL");
338 MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
339 MODULE_AUTHOR("Manuel Lauss <[email protected]>");