Merge remote-tracking branches 'asoc/fix/alc5632', 'asoc/fix/cs42l52', 'asoc/fix...
authorMark Brown <broonie@linaro.org>
Tue, 8 Apr 2014 20:22:11 +0000 (21:22 +0100)
committerMark Brown <broonie@linaro.org>
Tue, 8 Apr 2014 20:22:11 +0000 (21:22 +0100)
Documentation/devicetree/bindings/sound/fsl,ssi.txt
sound/soc/codecs/alc5632.c
sound/soc/codecs/cs42l52.c
sound/soc/codecs/cs42l52.h
sound/soc/codecs/cs42xx8.c
sound/soc/codecs/da732x.c
sound/soc/codecs/max98090.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_sai.h

index b93e9a9..3aa4a8f 100644 (file)
@@ -20,15 +20,6 @@ Required properties:
                     have.
 - interrupt-parent: The phandle for the interrupt controller that
                     services interrupts for this device.
-- fsl,mode:         The operating mode for the SSI interface.
-                    "i2s-slave" - I2S mode, SSI is clock slave
-                    "i2s-master" - I2S mode, SSI is clock master
-                    "lj-slave" - left-justified mode, SSI is clock slave
-                    "lj-master" - l.j. mode, SSI is clock master
-                    "rj-slave" - right-justified mode, SSI is clock slave
-                    "rj-master" - r.j., SSI is clock master
-                    "ac97-slave" - AC97 mode, SSI is clock slave
-                    "ac97-master" - AC97 mode, SSI is clock master
 - fsl,playback-dma: Phandle to a node for the DMA channel to use for
                     playback of audio.  This is typically dictated by SOC
                     design.  See the notes below.
@@ -47,6 +38,9 @@ Required properties:
                     be connected together, and SRFS and STFS be connected
                     together.  This would still allow different sample sizes,
                     but not different sample rates.
+ - clocks:          "ipg" - Required clock for the SSI unit
+                    "baud" - Required clock for SSI master mode. Otherwise this
+                     clock is not used
 
 Required are also ac97 link bindings if ac97 is used. See
 Documentation/devicetree/bindings/sound/soc-ac97link.txt for the necessary
@@ -64,6 +58,15 @@ Optional properties:
                    Documentation/devicetree/bindings/dma/dma.txt.
 - dma-names:       Two dmas have to be defined, "tx" and "rx", if fsl,imx-fiq
                    is not defined.
+- fsl,mode:         The operating mode for the SSI interface.
+                    "i2s-slave" - I2S mode, SSI is clock slave
+                    "i2s-master" - I2S mode, SSI is clock master
+                    "lj-slave" - left-justified mode, SSI is clock slave
+                    "lj-master" - l.j. mode, SSI is clock master
+                    "rj-slave" - right-justified mode, SSI is clock slave
+                    "rj-master" - r.j., SSI is clock master
+                    "ac97-slave" - AC97 mode, SSI is clock slave
+                    "ac97-master" - AC97 mode, SSI is clock master
 
 Child 'codec' node required properties:
 - compatible:       Compatible list, contains the name of the codec
index ec071a6..85942ca 100644 (file)
@@ -1061,7 +1061,6 @@ static int alc5632_resume(struct snd_soc_codec *codec)
 static int alc5632_probe(struct snd_soc_codec *codec)
 {
        struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
-       int ret;
 
        /* power on device  */
        alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1075,7 +1074,7 @@ static int alc5632_probe(struct snd_soc_codec *codec)
                return -EINVAL;
        }
 
-       return ret;
+       return 0;
 }
 
 /* power down chip */
@@ -1191,11 +1190,18 @@ static const struct i2c_device_id alc5632_i2c_table[] = {
 };
 MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
 
+static const struct of_device_id alc5632_of_match[] = {
+       { .compatible = "realtek,alc5632", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, alc5632_of_match);
+
 /* i2c codec control layer */
 static struct i2c_driver alc5632_i2c_driver = {
        .driver = {
                .name = "alc5632",
                .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(alc5632_of_match),
        },
        .probe = alc5632_i2c_probe,
        .remove =  alc5632_i2c_remove,
index f0ca6be..460d355 100644 (file)
@@ -1259,7 +1259,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
        }
 
        dev_info(&i2c_client->dev, "Cirrus Logic CS42L52, Revision: %02X\n",
-                       reg & 0xFF);
+                reg & CS42L52_CHIP_REV_MASK);
 
        /* Set Platform Data */
        if (cs42l52->pdata.mica_diff_cfg)
index 6fb8f00..ac44599 100644 (file)
@@ -37,7 +37,7 @@
 #define CS42L52_CHIP_REV_A0                    0x00
 #define CS42L52_CHIP_REV_A1                    0x01
 #define CS42L52_CHIP_REV_B0                    0x02
-#define CS42L52_CHIP_REV_MASK                  0x03
+#define CS42L52_CHIP_REV_MASK                  0x07
 
 #define CS42L52_PWRCTL1                                0x02
 #define CS42L52_PWRCTL1_PDN_ALL                        0x9F
index 082299a..8502032 100644 (file)
@@ -495,17 +495,16 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap)
        regcache_cache_bypass(cs42xx8->regmap, true);
 
        /* Validate the chip ID */
-       regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val);
-       if (val < 0) {
-               dev_err(dev, "failed to get device ID: %x", val);
-               ret = -EINVAL;
+       ret = regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val);
+       if (ret < 0) {
+               dev_err(dev, "failed to get device ID, ret = %d", ret);
                goto err_enable;
        }
 
        /* The top four bits of the chip ID should be 0000 */
-       if ((val & CS42XX8_CHIPID_CHIP_ID_MASK) != 0x00) {
+       if (((val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4) != 0x00) {
                dev_err(dev, "unmatched chip ID: %d\n",
-                               val & CS42XX8_CHIPID_CHIP_ID_MASK);
+                       (val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4);
                ret = -EINVAL;
                goto err_enable;
        }
index 7d168ec..48f3fef 100644 (file)
@@ -1571,7 +1571,8 @@ static int da732x_i2c_probe(struct i2c_client *i2c,
        }
 
        dev_info(&i2c->dev, "Revision: %d.%d\n",
-                (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK));
+                (reg & DA732X_ID_MAJOR_MASK) >> 4,
+                (reg & DA732X_ID_MINOR_MASK));
 
        ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x,
                                     da732x_dai, ARRAY_SIZE(da732x_dai));
index 98c6e10..f7b0b37 100644 (file)
@@ -2399,11 +2399,18 @@ static const struct i2c_device_id max98090_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);
 
+static const struct of_device_id max98090_of_match[] = {
+       { .compatible = "maxim,max98090", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, max98090_of_match);
+
 static struct i2c_driver max98090_i2c_driver = {
        .driver = {
                .name = "max98090",
                .owner = THIS_MODULE,
                .pm = &max98090_pm,
+               .of_match_table = of_match_ptr(max98090_of_match),
        },
        .probe  = max98090_i2c_probe,
        .remove = max98090_i2c_remove,
index a01ae97..4f75cac 100644 (file)
@@ -336,7 +336,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
                mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
 
-               mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
+               mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
                mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
                break;
 
@@ -344,7 +344,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
                mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
 
-               mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
+               mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
                mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
                break;
 
@@ -352,7 +352,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
                mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
 
-               mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
+               mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
                mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
                break;
 
index c4a4231..56da8c8 100644 (file)
 
 #include "fsl_sai.h"
 
+#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
+                      FSL_SAI_CSR_FEIE)
+
+static irqreturn_t fsl_sai_isr(int irq, void *devid)
+{
+       struct fsl_sai *sai = (struct fsl_sai *)devid;
+       struct device *dev = &sai->pdev->dev;
+       u32 xcsr, mask;
+
+       /* Only handle those what we enabled */
+       mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
+
+       /* Tx IRQ */
+       regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
+       xcsr &= mask;
+
+       if (xcsr & FSL_SAI_CSR_WSF)
+               dev_dbg(dev, "isr: Start of Tx word detected\n");
+
+       if (xcsr & FSL_SAI_CSR_SEF)
+               dev_warn(dev, "isr: Tx Frame sync error detected\n");
+
+       if (xcsr & FSL_SAI_CSR_FEF) {
+               dev_warn(dev, "isr: Transmit underrun detected\n");
+               /* FIFO reset for safety */
+               xcsr |= FSL_SAI_CSR_FR;
+       }
+
+       if (xcsr & FSL_SAI_CSR_FWF)
+               dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");
+
+       if (xcsr & FSL_SAI_CSR_FRF)
+               dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");
+
+       regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
+                          FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr);
+
+       /* Rx IRQ */
+       regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
+       xcsr &= mask;
+
+       if (xcsr & FSL_SAI_CSR_WSF)
+               dev_dbg(dev, "isr: Start of Rx word detected\n");
+
+       if (xcsr & FSL_SAI_CSR_SEF)
+               dev_warn(dev, "isr: Rx Frame sync error detected\n");
+
+       if (xcsr & FSL_SAI_CSR_FEF) {
+               dev_warn(dev, "isr: Receive overflow detected\n");
+               /* FIFO reset for safety */
+               xcsr |= FSL_SAI_CSR_FR;
+       }
+
+       if (xcsr & FSL_SAI_CSR_FWF)
+               dev_dbg(dev, "isr: Enabled receive FIFO is full\n");
+
+       if (xcsr & FSL_SAI_CSR_FRF)
+               dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");
+
+       regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+                          FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr);
+
+       return IRQ_HANDLED;
+}
+
 static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
                int clk_id, unsigned int freq, int fsl_dir)
 {
@@ -114,7 +179,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
                 * that is, together with the last bit of the previous
                 * data word.
                 */
-               val_cr2 &= ~FSL_SAI_CR2_BCP;
+               val_cr2 |= FSL_SAI_CR2_BCP;
                val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
                break;
        case SND_SOC_DAIFMT_LEFT_J:
@@ -122,7 +187,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
                 * Frame high, one word length for frame sync,
                 * frame sync asserts with the first bit of the frame.
                 */
-               val_cr2 &= ~FSL_SAI_CR2_BCP;
+               val_cr2 |= FSL_SAI_CR2_BCP;
                val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
                break;
        case SND_SOC_DAIFMT_DSP_A:
@@ -132,7 +197,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
                 * that is, together with the last bit of the previous
                 * data word.
                 */
-               val_cr2 &= ~FSL_SAI_CR2_BCP;
+               val_cr2 |= FSL_SAI_CR2_BCP;
                val_cr4 &= ~FSL_SAI_CR4_FSP;
                val_cr4 |= FSL_SAI_CR4_FSE;
                sai->is_dsp_mode = true;
@@ -142,7 +207,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
                 * Frame high, one bit for frame sync,
                 * frame sync asserts with the first bit of the frame.
                 */
-               val_cr2 &= ~FSL_SAI_CR2_BCP;
+               val_cr2 |= FSL_SAI_CR2_BCP;
                val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
                sai->is_dsp_mode = true;
                break;
@@ -373,8 +438,8 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
 {
        struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
 
-       regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0);
-       regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0);
+       regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, FSL_SAI_FLAGS);
+       regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, FSL_SAI_FLAGS);
        regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
                           FSL_SAI_MAXBURST_TX * 2);
        regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
@@ -490,12 +555,14 @@ static int fsl_sai_probe(struct platform_device *pdev)
        struct fsl_sai *sai;
        struct resource *res;
        void __iomem *base;
-       int ret;
+       int irq, ret;
 
        sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
        if (!sai)
                return -ENOMEM;
 
+       sai->pdev = pdev;
+
        sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
        if (sai->big_endian_regs)
                fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
@@ -514,6 +581,18 @@ static int fsl_sai_probe(struct platform_device *pdev)
                return PTR_ERR(sai->regmap);
        }
 
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
+               return irq;
+       }
+
+       ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
+               return ret;
+       }
+
        sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
        sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
        sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
index e432260..a264185 100644 (file)
 
 /* SAI Transmit/Recieve Control Register */
 #define FSL_SAI_CSR_TERE       BIT(31)
+#define FSL_SAI_CSR_FR         BIT(25)
+#define FSL_SAI_CSR_xF_SHIFT   16
+#define FSL_SAI_CSR_xF_W_SHIFT 18
+#define FSL_SAI_CSR_xF_MASK    (0x1f << FSL_SAI_CSR_xF_SHIFT)
+#define FSL_SAI_CSR_xF_W_MASK  (0x7 << FSL_SAI_CSR_xF_W_SHIFT)
+#define FSL_SAI_CSR_WSF                BIT(20)
+#define FSL_SAI_CSR_SEF                BIT(19)
+#define FSL_SAI_CSR_FEF                BIT(18)
 #define FSL_SAI_CSR_FWF                BIT(17)
+#define FSL_SAI_CSR_FRF                BIT(16)
+#define FSL_SAI_CSR_xIE_SHIFT  8
+#define FSL_SAI_CSR_WSIE       BIT(12)
+#define FSL_SAI_CSR_SEIE       BIT(11)
+#define FSL_SAI_CSR_FEIE       BIT(10)
+#define FSL_SAI_CSR_FWIE       BIT(9)
 #define FSL_SAI_CSR_FRIE       BIT(8)
 #define FSL_SAI_CSR_FRDE       BIT(0)
 
 #define FSL_SAI_MAXBURST_RX 6
 
 struct fsl_sai {
+       struct platform_device *pdev;
        struct regmap *regmap;
 
        bool big_endian_regs;