ASoC: au1x: convert to platform drivers.
[safe/jmp/linux-2.6] / sound / soc / blackfin / bf5xx-ac97.c
index 3be2be6..e693229 100644 (file)
 #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
 };
 
@@ -294,28 +277,28 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
        if (!dai->active)
                return 0;
 
-       ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
+#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
+       ret = sport_set_multichannel(sport, 16, 0x3FF, 1);
+#else
+       ret = sport_set_multichannel(sport, 16, 0x1F, 1);
+#endif
        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;
 }
 
@@ -332,11 +315,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
        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 */
@@ -355,7 +338,11 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
                goto sport_err;
        }
        /*SPORT works in TDM mode to simulate AC97 transfers*/
+#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
+       ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
+#else
        ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
+#endif
        if (ret) {
                pr_err("SPORT is busy!\n");
                ret = -EBUSY;
@@ -383,9 +370,9 @@ sport_config_err:
 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;
@@ -398,7 +385,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
 {
        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