Merge remote-tracking branches 'asoc/topic/rl6231' and 'asoc/topic/rt5514' into asoc...
authorMark Brown <broonie@kernel.org>
Fri, 10 Nov 2017 21:31:23 +0000 (21:31 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 10 Nov 2017 21:31:23 +0000 (21:31 +0000)
Documentation/devicetree/bindings/sound/rt5514.txt
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/rl6231.c
sound/soc/codecs/rt5514-spi.c
sound/soc/codecs/rt5514.c

index 929ca6756b02314ca44c9e8786ab32637a3d2294..4f33b0d96afeb106bb457ed071ab3f4779d80ec5 100644 (file)
@@ -1,22 +1,27 @@
 RT5514 audio CODEC
 
-This device supports I2C only.
+This device supports both I2C and SPI.
 
 Required properties:
 
 - compatible : "realtek,rt5514".
 
-- reg : The I2C address of the device.
+- reg : the I2C address of the device for I2C, the chip select
+        number for SPI.
 
 Optional properties:
 
 - clocks: The phandle of the master clock to the CODEC
 - clock-names: Should be "mclk"
 
+- interrupt-parent: The phandle for the interrupt controller.
+- interrupts: The interrupt number to the cpu. The interrupt specifier format
+             depends on the interrupt controller.
+
 - realtek,dmic-init-delay-ms
-  Set the DMIC initial delay (ms) to wait it ready.
+  Set the DMIC initial delay (ms) to wait it ready for I2C.
 
-Pins on the device (for linking into audio routes) for RT5514:
+Pins on the device (for linking into audio routes) for I2C:
 
   * DMIC1L
   * DMIC1R
index c367d11079bc90feec2ad0fa748d7ffc3035faba..01f436cc14c668f081a8e742099263d802b2d59e 100644 (file)
@@ -749,6 +749,10 @@ config SND_SOC_RT5514
 config SND_SOC_RT5514_SPI
        tristate
 
+config SND_SOC_RT5514_SPI_BUILTIN
+       bool # force RT5514_SPI to be built-in to avoid link errors
+       default SND_SOC_RT5514=y && SND_SOC_RT5514_SPI=m
+
 config SND_SOC_RT5616
        tristate "Realtek RT5616 CODEC"
        depends on I2C
index 05018b7ca72bdd7219cd64ba91525df7fc1c6e2f..0001069ce2a7e2f346cd7775f144864282d622e8 100644 (file)
@@ -360,6 +360,7 @@ obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
 obj-$(CONFIG_SND_SOC_RT298)    += snd-soc-rt298.o
 obj-$(CONFIG_SND_SOC_RT5514)   += snd-soc-rt5514.o
 obj-$(CONFIG_SND_SOC_RT5514_SPI)       += snd-soc-rt5514-spi.o
+obj-$(CONFIG_SND_SOC_RT5514_SPI_BUILTIN)       += snd-soc-rt5514-spi.o
 obj-$(CONFIG_SND_SOC_RT5616)   += snd-soc-rt5616.o
 obj-$(CONFIG_SND_SOC_RT5631)   += snd-soc-rt5631.o
 obj-$(CONFIG_SND_SOC_RT5640)   += snd-soc-rt5640.o
index 7b447d0b173a8c1860c2ff2b08a51e790887fb41..974a9040651db37da519ccb1e2cf5e2ff8d55ac2 100644 (file)
@@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(rl6231_get_pre_div);
  */
 int rl6231_calc_dmic_clk(int rate)
 {
-       int div[] = {2, 3, 4, 6, 8, 12};
+       static const int div[] = {2, 3, 4, 6, 8, 12};
        int i;
 
        if (rate < 1000000 * div[0]) {
@@ -189,7 +189,8 @@ EXPORT_SYMBOL_GPL(rl6231_pll_calc);
 
 int rl6231_get_clk_info(int sclk, int rate)
 {
-       int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
+       int i;
+       static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
 
        if (sclk <= 0 || rate <= 0)
                return -EINVAL;
index 12f2ecf3a4feeb3a6133012b33b5b10cad33999f..2df91db765acd6300406aa330cb0d85b3edb7d96 100644 (file)
@@ -147,8 +147,13 @@ done:
 
 static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
 {
+       size_t period_bytes;
        u8 buf[8];
 
+       if (!rt5514_dsp->substream)
+               return;
+
+       period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
        rt5514_dsp->get_size = 0;
 
        /**
@@ -176,6 +181,10 @@ static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
 
        rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base;
 
+       if (rt5514_dsp->buf_size % period_bytes)
+               rt5514_dsp->buf_size = (rt5514_dsp->buf_size / period_bytes) *
+                       period_bytes;
+
        if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
                rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
                schedule_delayed_work(&rt5514_dsp->copy_work, 0);
@@ -447,9 +456,45 @@ static int rt5514_spi_probe(struct spi_device *spi)
                return ret;
        }
 
+       device_init_wakeup(&spi->dev, true);
+
+       return 0;
+}
+
+static int __maybe_unused rt5514_suspend(struct device *dev)
+{
+       int irq = to_spi_device(dev)->irq;
+
+       if (device_may_wakeup(dev))
+               enable_irq_wake(irq);
+
+       return 0;
+}
+
+static int __maybe_unused rt5514_resume(struct device *dev)
+{
+       struct snd_soc_platform *platform = snd_soc_lookup_platform(dev);
+       struct rt5514_dsp *rt5514_dsp =
+               snd_soc_platform_get_drvdata(platform);
+       int irq = to_spi_device(dev)->irq;
+       u8 buf[8];
+
+       if (device_may_wakeup(dev))
+               disable_irq_wake(irq);
+
+       if (rt5514_dsp->substream) {
+               rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
+               if (buf[0] & RT5514_IRQ_STATUS_BIT)
+                       rt5514_schedule_copy(rt5514_dsp);
+       }
+
        return 0;
 }
 
+static const struct dev_pm_ops rt5514_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(rt5514_suspend, rt5514_resume)
+};
+
 static const struct of_device_id rt5514_of_match[] = {
        { .compatible = "realtek,rt5514", },
        {},
@@ -459,6 +504,7 @@ MODULE_DEVICE_TABLE(of, rt5514_of_match);
 static struct spi_driver rt5514_spi_driver = {
        .driver = {
                .name = "rt5514",
+               .pm = &rt5514_pm_ops,
                .of_match_table = of_match_ptr(rt5514_of_match),
        },
        .probe = rt5514_spi_probe,
index d7956ababd11775b0b9d04552faa68f2fadd2545..2a5b5d74e69714eeb966c6fc793021fcb7cd3a13 100644 (file)
@@ -1143,7 +1143,7 @@ static const struct acpi_device_id rt5514_acpi_match[] = {
 MODULE_DEVICE_TABLE(acpi, rt5514_acpi_match);
 #endif
 
-static int rt5514_parse_dt(struct rt5514_priv *rt5514, struct device *dev)
+static int rt5514_parse_dp(struct rt5514_priv *rt5514, struct device *dev)
 {
        device_property_read_u32(dev, "realtek,dmic-init-delay-ms",
                &rt5514->pdata.dmic_init_delay);
@@ -1183,8 +1183,8 @@ static int rt5514_i2c_probe(struct i2c_client *i2c,
 
        if (pdata)
                rt5514->pdata = *pdata;
-       else if (i2c->dev.of_node)
-               rt5514_parse_dt(rt5514, &i2c->dev);
+       else
+               rt5514_parse_dp(rt5514, &i2c->dev);
 
        rt5514->i2c_regmap = devm_regmap_init_i2c(i2c, &rt5514_i2c_regmap);
        if (IS_ERR(rt5514->i2c_regmap)) {