#include "bf5xx-sport.h"
#include "bf5xx-ac97.h"
-#if defined(CONFIG_BF54x)
-#define PIN_REQ_SPORT_0 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, \
- P_SPORT0_RFS, P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
-
-#define PIN_REQ_SPORT_1 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, \
- P_SPORT1_RFS, P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
-
-#define PIN_REQ_SPORT_2 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, \
- P_SPORT2_RFS, P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0}
-
-#define PIN_REQ_SPORT_3 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, \
- P_SPORT3_RFS, P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0}
-#else
-#define PIN_REQ_SPORT_0 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
- P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
-
-#define PIN_REQ_SPORT_1 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
- P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
-#endif
+/* Anomaly notes:
+ * 05000250 - AD1980 is running in TDM mode and RFS/TFS are generated by SPORT
+ * contrtoller. But, RFSDIV and TFSDIV are always set to 16*16-1,
+ * while the max AC97 data size is 13*16. The DIV is always larger
+ * than data size. AD73311 and ad2602 are not running in TDM mode.
+ * AD1836 and AD73322 depend on external RFS/TFS only. So, this
+ * anomaly does not affect blackfin sound drivers.
+*/
static int *cmd_count;
static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
+#define SPORT_REQ(x) \
+ [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
+ P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
static u16 sport_req[][7] = {
- PIN_REQ_SPORT_0,
-#ifdef PIN_REQ_SPORT_1
- PIN_REQ_SPORT_1,
+#ifdef SPORT0_TCR1
+ SPORT_REQ(0),
+#endif
+#ifdef SPORT1_TCR1
+ SPORT_REQ(1),
#endif
-#ifdef PIN_REQ_SPORT_2
- PIN_REQ_SPORT_2,
+#ifdef SPORT2_TCR1
+ SPORT_REQ(2),
#endif
-#ifdef PIN_REQ_SPORT_3
- PIN_REQ_SPORT_3,
+#ifdef SPORT3_TCR1
+ SPORT_REQ(3),
#endif
- };
+};
+#define SPORT_PARAMS(x) \
+ [x] = { \
+ .dma_rx_chan = CH_SPORT##x##_RX, \
+ .dma_tx_chan = CH_SPORT##x##_TX, \
+ .err_irq = IRQ_SPORT##x##_ERROR, \
+ .regs = (struct sport_register *)SPORT##x##_TCR1, \
+ }
static struct sport_param sport_params[4] = {
- {
- .dma_rx_chan = CH_SPORT0_RX,
- .dma_tx_chan = CH_SPORT0_TX,
- .err_irq = IRQ_SPORT0_ERROR,
- .regs = (struct sport_register *)SPORT0_TCR1,
- },
-#ifdef PIN_REQ_SPORT_1
- {
- .dma_rx_chan = CH_SPORT1_RX,
- .dma_tx_chan = CH_SPORT1_TX,
- .err_irq = IRQ_SPORT1_ERROR,
- .regs = (struct sport_register *)SPORT1_TCR1,
- },
+#ifdef SPORT0_TCR1
+ SPORT_PARAMS(0),
#endif
-#ifdef PIN_REQ_SPORT_2
- {
- .dma_rx_chan = CH_SPORT2_RX,
- .dma_tx_chan = CH_SPORT2_TX,
- .err_irq = IRQ_SPORT2_ERROR,
- .regs = (struct sport_register *)SPORT2_TCR1,
- },
+#ifdef SPORT1_TCR1
+ SPORT_PARAMS(1),
#endif
-#ifdef PIN_REQ_SPORT_3
- {
- .dma_rx_chan = CH_SPORT3_RX,
- .dma_tx_chan = CH_SPORT3_TX,
- .err_irq = IRQ_SPORT3_ERROR,
- .regs = (struct sport_register *)SPORT3_TCR1,
- }
+#ifdef SPORT2_TCR1
+ SPORT_PARAMS(2),
+#endif
+#ifdef SPORT3_TCR1
+ SPORT_PARAMS(3),
#endif
};
EXPORT_SYMBOL_GPL(soc_ac97_ops);
#ifdef CONFIG_PM
-static int bf5xx_ac97_suspend(struct platform_device *pdev,
- struct snd_soc_dai *dai)
+static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
{
struct sport_device *sport =
(struct sport_device *)dai->private_data;
return 0;
}
-static int bf5xx_ac97_resume(struct platform_device *pdev,
- struct snd_soc_dai *dai)
+static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
{
int ret;
struct sport_device *sport =
if (!dai->active)
return 0;
- ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
+ ret = sport_set_multichannel(sport, 16, 0x1F, 1);
if (ret) {
pr_err("SPORT is busy!\n");
return -EBUSY;
}
- ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
+ ret = sport_config_rx(sport, IRFS, 0xF, 0, (16*16-1));
if (ret) {
pr_err("SPORT is busy!\n");
return -EBUSY;
}
- ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
+ ret = sport_config_tx(sport, ITFS, 0xF, 0, (16*16-1));
if (ret) {
pr_err("SPORT is busy!\n");
return -EBUSY;
}
- if (dai->capture.active)
- sport_rx_start(sport);
- if (dai->playback.active)
- sport_tx_start(sport);
return 0;
}
if (cmd_count == NULL)
return -ENOMEM;
- if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
+ if (peripheral_request_list(sport_req[sport_num], "soc-audio")) {
pr_err("Requesting Peripherals failed\n");
ret = -EFAULT;
goto peripheral_err;
- }
+ }
#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
/* Request PB3 as reset pin */
sport_err:
#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-#endif
gpio_err:
- peripheral_free_list(&sport_req[sport_num][0]);
+#endif
+ peripheral_free_list(sport_req[sport_num]);
peripheral_err:
free_page((unsigned long)cmd_count);
cmd_count = NULL;
{
free_page((unsigned long)cmd_count);
cmd_count = NULL;
- peripheral_free_list(&sport_req[sport_num][0]);
+ peripheral_free_list(sport_req[sport_num]);
#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
#endif
};
EXPORT_SYMBOL_GPL(bfin_ac97_dai);
+static int __init bfin_ac97_init(void)
+{
+ return snd_soc_register_dai(&bfin_ac97_dai);
+}
+module_init(bfin_ac97_init);
+
+static void __exit bfin_ac97_exit(void)
+{
+ snd_soc_unregister_dai(&bfin_ac97_dai);
+}
+module_exit(bfin_ac97_exit);
+
MODULE_AUTHOR("Roy Huang");
MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
MODULE_LICENSE("GPL");