OSDN Git Service

ASoC: davinci-mcasp: Implement configurable dismod handling
authorPeter Ujfalusi <peter.ujfalusi@ti.com>
Fri, 16 Nov 2018 13:41:41 +0000 (15:41 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 28 Nov 2018 12:41:31 +0000 (12:41 +0000)
If the dismod is specified in the DT node, use the specified custom value
to configure the drive on state of the inactive TX slots.

If the dismod is not present or booted in legacy mode, the dismod is set
to low as it was the original behavior.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
include/linux/platform_data/davinci_asp.h
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-mcasp.h

index 85ad68f..7fe80f1 100644 (file)
@@ -79,6 +79,7 @@ struct davinci_mcasp_pdata {
        /* McASP specific fields */
        int tdm_slots;
        u8 op_mode;
+       u8 dismod;
        u8 num_serializer;
        u8 *serial_dir;
        u8 version;
index 0f3911b..40d3a91 100644 (file)
@@ -85,6 +85,7 @@ struct davinci_mcasp {
        u32     tdm_mask[2];
        int     slot_width;
        u8      op_mode;
+       u8      dismod;
        u8      num_serializer;
        u8      *serial_dir;
        u8      version;
@@ -834,7 +835,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
                if (mcasp->serial_dir[i] == TX_MODE &&
                                        tx_ser < max_active_serializers) {
                        mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
-                                      DISMOD_LOW, DISMOD_MASK);
+                                      mcasp->dismod, DISMOD_MASK);
                        set_bit(PIN_BIT_AXR(i), &mcasp->pdir);
                        tx_ser++;
                } else if (mcasp->serial_dir[i] == RX_MODE &&
@@ -847,6 +848,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
                        clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
                } else if (mcasp->serial_dir[i] == TX_MODE) {
                        /* Unused TX pins, clear PDIR  */
+                       mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
+                                      mcasp->dismod, DISMOD_MASK);
                        clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
                }
        }
@@ -1709,6 +1712,7 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
 
        if (pdev->dev.platform_data) {
                pdata = pdev->dev.platform_data;
+               pdata->dismod = DISMOD_LOW;
                return pdata;
        } else if (match) {
                pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata),
@@ -1798,6 +1802,18 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
        if (ret >= 0)
                pdata->sram_size_capture = val;
 
+       ret = of_property_read_u32(np, "dismod", &val);
+       if (ret >= 0) {
+               if (val == 0 || val == 2 || val == 3) {
+                       pdata->dismod = DISMOD_VAL(val);
+               } else {
+                       dev_warn(&pdev->dev, "Invalid dismod value: %u\n", val);
+                       pdata->dismod = DISMOD_LOW;
+               }
+       } else {
+               pdata->dismod = DISMOD_LOW;
+       }
+
        return  pdata;
 
 nodata:
@@ -1973,6 +1989,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
        mcasp->version = pdata->version;
        mcasp->txnumevt = pdata->txnumevt;
        mcasp->rxnumevt = pdata->rxnumevt;
+       mcasp->dismod = pdata->dismod;
 
        mcasp->dev = &pdev->dev;
 
index acb024a..5e4060d 100644 (file)
 #define DISMOD_3STATE  (0x0)
 #define DISMOD_LOW     (0x2 << 2)
 #define DISMOD_HIGH    (0x3 << 2)
+#define DISMOD_VAL(x)  ((x) << 2)
 #define DISMOD_MASK    DISMOD_HIGH
 #define TXSTATE                BIT(4)
 #define RXSTATE                BIT(5)