0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/init.h>
0017 #include <linux/module.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/wait.h>
0021 #include <linux/delay.h>
0022 #include <sound/core.h>
0023 #include <sound/pcm.h>
0024 #include <sound/ac97_codec.h>
0025 #include <sound/initval.h>
0026 #include <sound/soc.h>
0027
0028
0029 #define HACCR 0x08
0030 #define HACCSAR 0x20
0031 #define HACCSDR 0x24
0032 #define HACPCML 0x28
0033 #define HACPCMR 0x2C
0034 #define HACTIER 0x50
0035 #define HACTSR 0x54
0036 #define HACRIER 0x58
0037 #define HACRSR 0x5C
0038 #define HACACR 0x60
0039
0040 #define CR_CR (1 << 15)
0041 #define CR_CDRT (1 << 11)
0042 #define CR_WMRT (1 << 10)
0043 #define CR_B9 (1 << 9)
0044 #define CR_ST (1 << 5)
0045
0046 #define CSAR_RD (1 << 19)
0047 #define CSAR_WR (0)
0048
0049 #define TSR_CMDAMT (1 << 31)
0050 #define TSR_CMDDMT (1 << 30)
0051
0052 #define RSR_STARY (1 << 22)
0053 #define RSR_STDRY (1 << 21)
0054
0055 #define ACR_DMARX16 (1 << 30)
0056 #define ACR_DMATX16 (1 << 29)
0057 #define ACR_TX12ATOM (1 << 26)
0058 #define ACR_DMARX20 ((1 << 24) | (1 << 22))
0059 #define ACR_DMATX20 ((1 << 23) | (1 << 21))
0060
0061 #define CSDR_SHIFT 4
0062 #define CSDR_MASK (0xffff << CSDR_SHIFT)
0063 #define CSAR_SHIFT 12
0064 #define CSAR_MASK (0x7f << CSAR_SHIFT)
0065
0066 #define AC97_WRITE_RETRY 1
0067 #define AC97_READ_RETRY 5
0068
0069
0070 #define TMO_E1 500
0071 #define TMO_E2 13
0072 #define TMO_E3 21
0073 #define TMO_E4 500
0074
0075 struct hac_priv {
0076 unsigned long mmio;
0077 } hac_cpu_data[] = {
0078 #if defined(CONFIG_CPU_SUBTYPE_SH7760)
0079 {
0080 .mmio = 0xFE240000,
0081 },
0082 {
0083 .mmio = 0xFE250000,
0084 },
0085 #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
0086 {
0087 .mmio = 0xFFE40000,
0088 },
0089 #else
0090 #error "Unsupported SuperH SoC"
0091 #endif
0092 };
0093
0094 #define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg)))
0095
0096
0097
0098
0099 static int hac_get_codec_data(struct hac_priv *hac, unsigned short r,
0100 unsigned short *v)
0101 {
0102 unsigned int to1, to2, i;
0103 unsigned short adr;
0104
0105 for (i = AC97_READ_RETRY; i; i--) {
0106 *v = 0;
0107
0108 for (to1 = TMO_E4;
0109 to1 && !(HACREG(HACRSR) & RSR_STARY);
0110 --to1)
0111 udelay(1);
0112 for (to2 = TMO_E4;
0113 to2 && !(HACREG(HACRSR) & RSR_STDRY);
0114 --to2)
0115 udelay(1);
0116
0117 if (!to1 && !to2)
0118 return 0;
0119
0120 adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT);
0121 *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT);
0122
0123 HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
0124
0125 if (r == adr)
0126 break;
0127
0128
0129 udelay(21);
0130 }
0131 HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY);
0132 return i;
0133 }
0134
0135 static unsigned short hac_read_codec_aux(struct hac_priv *hac,
0136 unsigned short reg)
0137 {
0138 unsigned short val;
0139 unsigned int i, to;
0140
0141 for (i = AC97_READ_RETRY; i; i--) {
0142
0143 local_irq_disable();
0144 HACREG(HACTSR) &= ~(TSR_CMDAMT);
0145 HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD;
0146 local_irq_enable();
0147
0148 for (to = TMO_E3;
0149 to && !(HACREG(HACTSR) & TSR_CMDAMT);
0150 --to)
0151 udelay(1);
0152
0153 HACREG(HACTSR) &= ~TSR_CMDAMT;
0154 val = 0;
0155 if (hac_get_codec_data(hac, reg, &val) != 0)
0156 break;
0157 }
0158
0159 return i ? val : ~0;
0160 }
0161
0162 static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
0163 unsigned short val)
0164 {
0165 int unit_id = 0 ;
0166 struct hac_priv *hac = &hac_cpu_data[unit_id];
0167 unsigned int i, to;
0168
0169 for (i = AC97_WRITE_RETRY; i; i--) {
0170
0171 local_irq_disable();
0172 HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT);
0173 HACREG(HACCSDR) = (val << CSDR_SHIFT);
0174 HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD);
0175 local_irq_enable();
0176
0177
0178 for (to = TMO_E1;
0179 to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT));
0180 --to)
0181 udelay(1);
0182
0183 HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT);
0184 if (to)
0185 break;
0186
0187 }
0188 }
0189
0190 static unsigned short hac_ac97_read(struct snd_ac97 *ac97,
0191 unsigned short reg)
0192 {
0193 int unit_id = 0 ;
0194 struct hac_priv *hac = &hac_cpu_data[unit_id];
0195 return hac_read_codec_aux(hac, reg);
0196 }
0197
0198 static void hac_ac97_warmrst(struct snd_ac97 *ac97)
0199 {
0200 int unit_id = 0 ;
0201 struct hac_priv *hac = &hac_cpu_data[unit_id];
0202 unsigned int tmo;
0203
0204 HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9;
0205 msleep(10);
0206 HACREG(HACCR) = CR_ST | CR_B9;
0207 for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--)
0208 udelay(1);
0209
0210 if (!tmo)
0211 printk(KERN_INFO "hac: reset: AC97 link down!\n");
0212
0213 HACREG(HACACR) |= ACR_TX12ATOM;
0214 }
0215
0216 static void hac_ac97_coldrst(struct snd_ac97 *ac97)
0217 {
0218 int unit_id = 0 ;
0219 struct hac_priv *hac;
0220 hac = &hac_cpu_data[unit_id];
0221
0222 HACREG(HACCR) = 0;
0223 HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9;
0224 msleep(10);
0225 hac_ac97_warmrst(ac97);
0226 }
0227
0228 static struct snd_ac97_bus_ops hac_ac97_ops = {
0229 .read = hac_ac97_read,
0230 .write = hac_ac97_write,
0231 .reset = hac_ac97_coldrst,
0232 .warm_reset = hac_ac97_warmrst,
0233 };
0234
0235 static int hac_hw_params(struct snd_pcm_substream *substream,
0236 struct snd_pcm_hw_params *params,
0237 struct snd_soc_dai *dai)
0238 {
0239 struct hac_priv *hac = &hac_cpu_data[dai->id];
0240 int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
0241
0242 switch (params->msbits) {
0243 case 16:
0244 HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16;
0245 HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20;
0246 break;
0247 case 20:
0248 HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16;
0249 HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20;
0250 break;
0251 default:
0252 pr_debug("hac: invalid depth %d bit\n", params->msbits);
0253 return -EINVAL;
0254 break;
0255 }
0256
0257 return 0;
0258 }
0259
0260 #define AC97_RATES \
0261 SNDRV_PCM_RATE_8000_192000
0262
0263 #define AC97_FMTS \
0264 SNDRV_PCM_FMTBIT_S16_LE
0265
0266 static const struct snd_soc_dai_ops hac_dai_ops = {
0267 .hw_params = hac_hw_params,
0268 };
0269
0270 static struct snd_soc_dai_driver sh4_hac_dai[] = {
0271 {
0272 .name = "hac-dai.0",
0273 .playback = {
0274 .rates = AC97_RATES,
0275 .formats = AC97_FMTS,
0276 .channels_min = 2,
0277 .channels_max = 2,
0278 },
0279 .capture = {
0280 .rates = AC97_RATES,
0281 .formats = AC97_FMTS,
0282 .channels_min = 2,
0283 .channels_max = 2,
0284 },
0285 .ops = &hac_dai_ops,
0286 },
0287 #ifdef CONFIG_CPU_SUBTYPE_SH7760
0288 {
0289 .name = "hac-dai.1",
0290 .id = 1,
0291 .playback = {
0292 .rates = AC97_RATES,
0293 .formats = AC97_FMTS,
0294 .channels_min = 2,
0295 .channels_max = 2,
0296 },
0297 .capture = {
0298 .rates = AC97_RATES,
0299 .formats = AC97_FMTS,
0300 .channels_min = 2,
0301 .channels_max = 2,
0302 },
0303 .ops = &hac_dai_ops,
0304
0305 },
0306 #endif
0307 };
0308
0309 static const struct snd_soc_component_driver sh4_hac_component = {
0310 .name = "sh4-hac",
0311 .legacy_dai_naming = 1,
0312 };
0313
0314 static int hac_soc_platform_probe(struct platform_device *pdev)
0315 {
0316 int ret;
0317
0318 ret = snd_soc_set_ac97_ops(&hac_ac97_ops);
0319 if (ret != 0)
0320 return ret;
0321
0322 return devm_snd_soc_register_component(&pdev->dev, &sh4_hac_component,
0323 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
0324 }
0325
0326 static int hac_soc_platform_remove(struct platform_device *pdev)
0327 {
0328 snd_soc_set_ac97_ops(NULL);
0329 return 0;
0330 }
0331
0332 static struct platform_driver hac_pcm_driver = {
0333 .driver = {
0334 .name = "hac-pcm-audio",
0335 },
0336
0337 .probe = hac_soc_platform_probe,
0338 .remove = hac_soc_platform_remove,
0339 };
0340
0341 module_platform_driver(hac_pcm_driver);
0342
0343 MODULE_LICENSE("GPL v2");
0344 MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
0345 MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");