Commit 7c9c29ee authored by Mark Brown's avatar Mark Brown

Merge tag 'asoc-v4.3-rc2' into asoc-next

ASoC: Updates for v4.4

A first batch of updates targetted at v4.4.  There are no substantial
core fixes here, the biggest block of changes is updates to the rcar
drivers and the addition of a CODEC driver for the AK4613.

# gpg: Signature made Fri 25 Sep 2015 05:37:06 KST using RSA key ID 5D5487D0
# gpg: key CD7BEEBC: no public key for trusted key - skipped
# gpg: key CD7BEEBC marked as ultimately trusted
# gpg: key AF88CD16: no public key for trusted key - skipped
# gpg: key AF88CD16 marked as ultimately trusted
# gpg: key 16005C11: no public key for trusted key - skipped
# gpg: key 16005C11 marked as ultimately trusted
# gpg: key 5621E907: no public key for trusted key - skipped
# gpg: key 5621E907 marked as ultimately trusted
# gpg: key 5C6153AD: no public key for trusted key - skipped
# gpg: key 5C6153AD marked as ultimately trusted
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>"
# gpg:                 aka "Mark Brown <broonie@debian.org>"
# gpg:                 aka "Mark Brown <broonie@kernel.org>"
# gpg:                 aka "Mark Brown <broonie@tardis.ed.ac.uk>"
# gpg:                 aka "Mark Brown <broonie@linaro.org>"
# gpg:                 aka "Mark Brown <Mark.Brown@linaro.org>"
parents 32b88194 4922e7a1
AK4613 I2C transmitter
This device supports I2C mode only.
Required properties:
- compatible : "asahi-kasei,ak4613"
- reg : The chip select number on the I2C bus
Example:
&i2c {
ak4613: ak4613@0x10 {
compatible = "asahi-kasei,ak4613";
reg = <0x10>;
};
};
...@@ -7,7 +7,14 @@ Required properties: ...@@ -7,7 +7,14 @@ Required properties:
- compatible : "asahi-kasei,ak4642" or "asahi-kasei,ak4643" or "asahi-kasei,ak4648" - compatible : "asahi-kasei,ak4642" or "asahi-kasei,ak4643" or "asahi-kasei,ak4648"
- reg : The chip select number on the I2C bus - reg : The chip select number on the I2C bus
Example: Optional properties:
- #clock-cells : common clock binding; shall be set to 0
- clocks : common clock binding; MCKI clock
- clock-frequency : common clock binding; frequency of MCKO
- clock-output-names : common clock binding; MCKO clock name
Example 1:
&i2c { &i2c {
ak4648: ak4648@0x12 { ak4648: ak4648@0x12 {
...@@ -15,3 +22,16 @@ Example: ...@@ -15,3 +22,16 @@ Example:
reg = <0x12>; reg = <0x12>;
}; };
}; };
Example 2:
&i2c {
ak4643: codec@12 {
compatible = "asahi-kasei,ak4643";
reg = <0x12>;
#clock-cells = <0>;
clocks = <&audio_clock>;
clock-frequency = <12288000>;
clock-output-names = "ak4643_mcko";
};
};
...@@ -4,10 +4,12 @@ Required properties: ...@@ -4,10 +4,12 @@ Required properties:
- compatible : "renesas,rcar_sound-<soctype>", fallbacks - compatible : "renesas,rcar_sound-<soctype>", fallbacks
"renesas,rcar_sound-gen1" if generation1, and "renesas,rcar_sound-gen1" if generation1, and
"renesas,rcar_sound-gen2" if generation2 "renesas,rcar_sound-gen2" if generation2
"renesas,rcar_sound-gen3" if generation3
Examples with soctypes are: Examples with soctypes are:
- "renesas,rcar_sound-r8a7778" (R-Car M1A) - "renesas,rcar_sound-r8a7778" (R-Car M1A)
- "renesas,rcar_sound-r8a7790" (R-Car H2) - "renesas,rcar_sound-r8a7790" (R-Car H2)
- "renesas,rcar_sound-r8a7791" (R-Car M2-W) - "renesas,rcar_sound-r8a7791" (R-Car M2-W)
- "renesas,rcar_sound-r8a7795" (R-Car H3)
- reg : Should contain the register physical address. - reg : Should contain the register physical address.
required register is required register is
SRU/ADG/SSI if generation1 SRU/ADG/SSI if generation1
...@@ -30,6 +32,11 @@ Required properties: ...@@ -30,6 +32,11 @@ Required properties:
- rcar_sound,dai : DAI contents. - rcar_sound,dai : DAI contents.
The number of DAI subnode should be same as HW. The number of DAI subnode should be same as HW.
see below for detail. see below for detail.
- #sound-dai-cells : it must be 0 if your system is using single DAI
it must be 1 if your system is using multi DAI
- #clock-cells : it must be 0 if your system has audio_clkout
it must be 1 if your system has audio_clkout0/1/2/3
- clock-frequency : for all audio_clkout0/1/2/3
SSI subnode properties: SSI subnode properties:
- interrupts : Should contain SSI interrupt for PIO transfer - interrupts : Should contain SSI interrupt for PIO transfer
......
* Allwinner A10 Codec
Required properties:
- compatible: must be either "allwinner,sun4i-a10-codec" or
"allwinner,sun7i-a20-codec"
- reg: must contain the registers location and length
- interrupts: must contain the codec interrupt
- dmas: DMA channels for tx and rx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt
- dma-names: should include "tx" and "rx".
- clocks: a list of phandle + clock-specifer pairs, one for each entry
in clock-names.
- clock-names: should contain followings:
- "apb": the parent APB clock for this controller
- "codec": the parent module clock
- routing : A list of the connections between audio components. Each
entry is a pair of strings, the first being the connection's sink,
the second being the connection's source.
Example:
codec: codec@01c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun7i-a20-codec";
reg = <0x01c22c00 0x40>;
interrupts = <0 30 4>;
clocks = <&apb0_gates 0>, <&codec_clk>;
clock-names = "apb", "codec";
dmas = <&dma 0 19>, <&dma 0 19>;
dma-names = "rx", "tx";
routing = "Headphone Jack", "HP Right",
"Headphone Jack", "HP Left";
};
...@@ -4,11 +4,15 @@ This specifies audio DAI's TDM slot. ...@@ -4,11 +4,15 @@ This specifies audio DAI's TDM slot.
TDM slot properties: TDM slot properties:
dai-tdm-slot-num : Number of slots in use. dai-tdm-slot-num : Number of slots in use.
dai-tdm-slot-width : Width in bits for each slot. dai-tdm-slot-width : Width in bits for each slot.
dai-tdm-slot-tx-mask : Transmit direction slot mask, optional
dai-tdm-slot-rx-mask : Receive direction slot mask, optional
For instance: For instance:
dai-tdm-slot-num = <2>; dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <8>; dai-tdm-slot-width = <8>;
dai-tdm-slot-tx-mask = <0 1>;
dai-tdm-slot-rx-mask = <1 0>;
And for each spcified driver, there could be one .of_xlate_tdm_slot_mask() And for each spcified driver, there could be one .of_xlate_tdm_slot_mask()
to specify a explicit mapping of the channels and the slots. If it's absent to specify a explicit mapping of the channels and the slots. If it's absent
...@@ -18,3 +22,8 @@ tx and rx masks. ...@@ -18,3 +22,8 @@ tx and rx masks.
For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit
for an active slot as default, and the default active bits are at the LSB of for an active slot as default, and the default active bits are at the LSB of
the masks. the masks.
The explicit masks are given as array of integers, where the first
number presents bit-0 (LSB), second presents bit-1, etc. Any non zero
number is considered 1 and 0 is 0. snd_soc_of_xlate_tdm_slot_mask()
does not do anything, if either mask is set non zero value.
...@@ -871,14 +871,7 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as, ...@@ -871,14 +871,7 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
* Calculate the lowest divider that satisfies the * Calculate the lowest divider that satisfies the
* constraint, assuming div32/fdiv/mbz == 0. * constraint, assuming div32/fdiv/mbz == 0.
*/ */
if (xfer->speed_hz) scbr = DIV_ROUND_UP(bus_hz, xfer->speed_hz);
scbr = DIV_ROUND_UP(bus_hz, xfer->speed_hz);
else
/*
* This can happend if max_speed is null.
* In this case, we set the lowest possible speed
*/
scbr = 0xff;
/* /*
* If the resulting divider doesn't fit into the * If the resulting divider doesn't fit into the
...@@ -1300,14 +1293,12 @@ static int atmel_spi_one_transfer(struct spi_master *master, ...@@ -1300,14 +1293,12 @@ static int atmel_spi_one_transfer(struct spi_master *master,
return -EINVAL; return -EINVAL;
} }
if (xfer->bits_per_word) { asd = spi->controller_state;
asd = spi->controller_state; bits = (asd->csr >> 4) & 0xf;
bits = (asd->csr >> 4) & 0xf; if (bits != xfer->bits_per_word - 8) {
if (bits != xfer->bits_per_word - 8) { dev_dbg(&spi->dev,
dev_dbg(&spi->dev,
"you can't yet change bits_per_word in transfers\n"); "you can't yet change bits_per_word in transfers\n");
return -ENOPROTOOPT; return -ENOPROTOOPT;
}
} }
/* /*
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#ifndef RCAR_SND_H #ifndef RCAR_SND_H
#define RCAR_SND_H #define RCAR_SND_H
#include <linux/sh_clk.h>
#define RSND_GEN1_SRU 0 #define RSND_GEN1_SRU 0
#define RSND_GEN1_ADG 1 #define RSND_GEN1_ADG 1
......
...@@ -21,6 +21,8 @@ struct rt5645_platform_data { ...@@ -21,6 +21,8 @@ struct rt5645_platform_data {
/* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */ /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */
unsigned int jd_mode; unsigned int jd_mode;
/* Invert JD when jack insert */
bool jd_invert;
}; };
#endif #endif
...@@ -19,6 +19,8 @@ struct asoc_simple_dai { ...@@ -19,6 +19,8 @@ struct asoc_simple_dai {
unsigned int sysclk; unsigned int sysclk;
int slots; int slots;
int slot_width; int slot_width;
unsigned int tx_slot_mask;
unsigned int rx_slot_mask;
struct clk *clk; struct clk *clk;
}; };
......
...@@ -226,6 +226,18 @@ ...@@ -226,6 +226,18 @@
.info = snd_soc_info_volsw, \ .info = snd_soc_info_volsw, \
.get = xhandler_get, .put = xhandler_put, \ .get = xhandler_get, .put = xhandler_put, \
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) } .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) }
#define SOC_SINGLE_RANGE_EXT_TLV(xname, xreg, xshift, xmin, xmax, xinvert, \
xhandler_get, xhandler_put, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
SNDRV_CTL_ELEM_ACCESS_READWRITE,\
.tlv.p = (tlv_array), \
.info = snd_soc_info_volsw_range, \
.get = xhandler_get, .put = xhandler_put, \
.private_value = (unsigned long)&(struct soc_mixer_control) \
{.reg = xreg, .rreg = xreg, .shift = xshift, \
.rshift = xshift, .min = xmin, .max = xmax, \
.platform_max = xmax, .invert = xinvert} }
#define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\ #define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
xhandler_get, xhandler_put, tlv_array) \ xhandler_get, xhandler_put, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
...@@ -1603,6 +1615,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card, ...@@ -1603,6 +1615,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
const char *propname); const char *propname);
int snd_soc_of_parse_tdm_slot(struct device_node *np, int snd_soc_of_parse_tdm_slot(struct device_node *np,
unsigned int *tx_mask,
unsigned int *rx_mask,
unsigned int *slots, unsigned int *slots,
unsigned int *slot_width); unsigned int *slot_width);
void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card, void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
......
...@@ -58,6 +58,7 @@ source "sound/soc/sh/Kconfig" ...@@ -58,6 +58,7 @@ source "sound/soc/sh/Kconfig"
source "sound/soc/sirf/Kconfig" source "sound/soc/sirf/Kconfig"
source "sound/soc/spear/Kconfig" source "sound/soc/spear/Kconfig"
source "sound/soc/sti/Kconfig" source "sound/soc/sti/Kconfig"
source "sound/soc/sunxi/Kconfig"
source "sound/soc/tegra/Kconfig" source "sound/soc/tegra/Kconfig"
source "sound/soc/txx9/Kconfig" source "sound/soc/txx9/Kconfig"
source "sound/soc/ux500/Kconfig" source "sound/soc/ux500/Kconfig"
......
...@@ -40,6 +40,7 @@ obj-$(CONFIG_SND_SOC) += sh/ ...@@ -40,6 +40,7 @@ obj-$(CONFIG_SND_SOC) += sh/
obj-$(CONFIG_SND_SOC) += sirf/ obj-$(CONFIG_SND_SOC) += sirf/
obj-$(CONFIG_SND_SOC) += spear/ obj-$(CONFIG_SND_SOC) += spear/
obj-$(CONFIG_SND_SOC) += sti/ obj-$(CONFIG_SND_SOC) += sti/
obj-$(CONFIG_SND_SOC) += sunxi/
obj-$(CONFIG_SND_SOC) += tegra/ obj-$(CONFIG_SND_SOC) += tegra/
obj-$(CONFIG_SND_SOC) += txx9/ obj-$(CONFIG_SND_SOC) += txx9/
obj-$(CONFIG_SND_SOC) += ux500/ obj-$(CONFIG_SND_SOC) += ux500/
......
...@@ -176,6 +176,7 @@ static const struct of_device_id atmel_asoc_wm8904_dt_ids[] = { ...@@ -176,6 +176,7 @@ static const struct of_device_id atmel_asoc_wm8904_dt_ids[] = {
{ .compatible = "atmel,asoc-wm8904", }, { .compatible = "atmel,asoc-wm8904", },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, atmel_asoc_wm8904_dt_ids);
#endif #endif
static struct platform_driver atmel_asoc_wm8904_driver = { static struct platform_driver atmel_asoc_wm8904_driver = {
......
...@@ -38,14 +38,7 @@ static int db1000_audio_probe(struct platform_device *pdev) ...@@ -38,14 +38,7 @@ static int db1000_audio_probe(struct platform_device *pdev)
{ {
struct snd_soc_card *card = &db1000_ac97; struct snd_soc_card *card = &db1000_ac97;
card->dev = &pdev->dev; card->dev = &pdev->dev;
return snd_soc_register_card(card); return devm_snd_soc_register_card(&pdev->dev, card);
}
static int db1000_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
} }
static struct platform_driver db1000_audio_driver = { static struct platform_driver db1000_audio_driver = {
...@@ -54,7 +47,6 @@ static struct platform_driver db1000_audio_driver = { ...@@ -54,7 +47,6 @@ static struct platform_driver db1000_audio_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = db1000_audio_probe, .probe = db1000_audio_probe,
.remove = db1000_audio_remove,
}; };
module_platform_driver(db1000_audio_driver); module_platform_driver(db1000_audio_driver);
......
...@@ -178,14 +178,7 @@ static int db1200_audio_probe(struct platform_device *pdev) ...@@ -178,14 +178,7 @@ static int db1200_audio_probe(struct platform_device *pdev)
card = db1200_cards[pid->driver_data]; card = db1200_cards[pid->driver_data];
card->dev = &pdev->dev; card->dev = &pdev->dev;
return snd_soc_register_card(card); return devm_snd_soc_register_card(&pdev->dev, card);
}
static int db1200_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
} }
static struct platform_driver db1200_audio_driver = { static struct platform_driver db1200_audio_driver = {
...@@ -195,7 +188,6 @@ static struct platform_driver db1200_audio_driver = { ...@@ -195,7 +188,6 @@ static struct platform_driver db1200_audio_driver = {
}, },
.id_table = db1200_pids, .id_table = db1200_pids,
.probe = db1200_audio_probe, .probe = db1200_audio_probe,
.remove = db1200_audio_remove,
}; };
module_platform_driver(db1200_audio_driver); module_platform_driver(db1200_audio_driver);
......
...@@ -87,27 +87,18 @@ static int bf5xx_ad1836_driver_probe(struct platform_device *pdev) ...@@ -87,27 +87,18 @@ static int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
platform_set_drvdata(pdev, card); platform_set_drvdata(pdev, card);
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) if (ret)
dev_err(&pdev->dev, "Failed to register card\n"); dev_err(&pdev->dev, "Failed to register card\n");
return ret; return ret;
} }
static int bf5xx_ad1836_driver_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static struct platform_driver bf5xx_ad1836_driver = { static struct platform_driver bf5xx_ad1836_driver = {
.driver = { .driver = {
.name = "bfin-snd-ad1836", .name = "bfin-snd-ad1836",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = bf5xx_ad1836_driver_probe, .probe = bf5xx_ad1836_driver_probe,
.remove = bf5xx_ad1836_driver_remove,
}; };
module_platform_driver(bf5xx_ad1836_driver); module_platform_driver(bf5xx_ad1836_driver);
......
...@@ -154,16 +154,7 @@ static int bfin_eval_adau1373_probe(struct platform_device *pdev) ...@@ -154,16 +154,7 @@ static int bfin_eval_adau1373_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
return snd_soc_register_card(&bfin_eval_adau1373); return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1373);
}
static int bfin_eval_adau1373_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
} }
static struct platform_driver bfin_eval_adau1373_driver = { static struct platform_driver bfin_eval_adau1373_driver = {
...@@ -172,7 +163,6 @@ static struct platform_driver bfin_eval_adau1373_driver = { ...@@ -172,7 +163,6 @@ static struct platform_driver bfin_eval_adau1373_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = bfin_eval_adau1373_probe, .probe = bfin_eval_adau1373_probe,
.remove = bfin_eval_adau1373_remove,
}; };
module_platform_driver(bfin_eval_adau1373_driver); module_platform_driver(bfin_eval_adau1373_driver);
......
...@@ -94,16 +94,7 @@ static int bfin_eval_adau1701_probe(struct platform_device *pdev) ...@@ -94,16 +94,7 @@ static int bfin_eval_adau1701_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
return snd_soc_register_card(&bfin_eval_adau1701); return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1701);
}
static int bfin_eval_adau1701_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
} }
static struct platform_driver bfin_eval_adau1701_driver = { static struct platform_driver bfin_eval_adau1701_driver = {
...@@ -112,7 +103,6 @@ static struct platform_driver bfin_eval_adau1701_driver = { ...@@ -112,7 +103,6 @@ static struct platform_driver bfin_eval_adau1701_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = bfin_eval_adau1701_probe, .probe = bfin_eval_adau1701_probe,
.remove = bfin_eval_adau1701_remove,
}; };
module_platform_driver(bfin_eval_adau1701_driver); module_platform_driver(bfin_eval_adau1701_driver);
......
...@@ -119,16 +119,7 @@ static int bfin_eval_adav80x_probe(struct platform_device *pdev) ...@@ -119,16 +119,7 @@ static int bfin_eval_adav80x_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
return snd_soc_register_card(&bfin_eval_adav80x); return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adav80x);
}
static int bfin_eval_adav80x_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
} }
static const struct platform_device_id bfin_eval_adav80x_ids[] = { static const struct platform_device_id bfin_eval_adav80x_ids[] = {
...@@ -144,7 +135,6 @@ static struct platform_driver bfin_eval_adav80x_driver = { ...@@ -144,7 +135,6 @@ static struct platform_driver bfin_eval_adav80x_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = bfin_eval_adav80x_probe, .probe = bfin_eval_adav80x_probe,
.remove = bfin_eval_adav80x_remove,
.id_table = bfin_eval_adav80x_ids, .id_table = bfin_eval_adav80x_ids,
}; };
......
...@@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS ...@@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_AK4104 if SPI_MASTER select SND_SOC_AK4104 if SPI_MASTER
select SND_SOC_AK4535 if I2C select SND_SOC_AK4535 if I2C
select SND_SOC_AK4554 select SND_SOC_AK4554
select SND_SOC_AK4613 if I2C
select SND_SOC_AK4641 if I2C select SND_SOC_AK4641 if I2C
select SND_SOC_AK4642 if I2C select SND_SOC_AK4642 if I2C
select SND_SOC_AK4671 if I2C select SND_SOC_AK4671 if I2C
...@@ -79,7 +80,6 @@ config SND_SOC_ALL_CODECS ...@@ -79,7 +80,6 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C select SND_SOC_ML26124 if I2C
select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1792A if SPI_MASTER select SND_SOC_PCM1792A if SPI_MASTER
select SND_SOC_PCM3008 select SND_SOC_PCM3008
...@@ -319,6 +319,10 @@ config SND_SOC_AK4535 ...@@ -319,6 +319,10 @@ config SND_SOC_AK4535
config SND_SOC_AK4554 config SND_SOC_AK4554
tristate "AKM AK4554 CODEC" tristate "AKM AK4554 CODEC"
config SND_SOC_AK4613
tristate "AKM AK4613 CODEC"
depends on I2C
config SND_SOC_AK4641 config SND_SOC_AK4641
tristate tristate
...@@ -442,9 +446,6 @@ config SND_SOC_BT_SCO ...@@ -442,9 +446,6 @@ config SND_SOC_BT_SCO
config SND_SOC_DMIC config SND_SOC_DMIC
tristate tristate
config SND_SOC_HDMI_CODEC
tristate "HDMI stub CODEC"
config SND_SOC_ES8328 config SND_SOC_ES8328
tristate "Everest Semi ES8328 CODEC" tristate "Everest Semi ES8328 CODEC"
......
...@@ -26,6 +26,7 @@ snd-soc-ads117x-objs := ads117x.o ...@@ -26,6 +26,7 @@ snd-soc-ads117x-objs := ads117x.o
snd-soc-ak4104-objs := ak4104.o snd-soc-ak4104-objs := ak4104.o
snd-soc-ak4535-objs := ak4535.o snd-soc-ak4535-objs := ak4535.o
snd-soc-ak4554-objs := ak4554.o snd-soc-ak4554-objs := ak4554.o
snd-soc-ak4613-objs := ak4613.o
snd-soc-ak4641-objs := ak4641.o snd-soc-ak4641-objs := ak4641.o
snd-soc-ak4642-objs := ak4642.o snd-soc-ak4642-objs := ak4642.o
snd-soc-ak4671-objs := ak4671.o snd-soc-ak4671-objs := ak4671.o
...@@ -72,7 +73,6 @@ snd-soc-max98925-objs := max98925.o ...@@ -72,7 +73,6 @@ snd-soc-max98925-objs := max98925.o
snd-soc-max9850-objs := max9850.o snd-soc-max9850-objs := max9850.o
snd-soc-mc13783-objs := mc13783.o snd-soc-mc13783-objs := mc13783.o
snd-soc-ml26124-objs := ml26124.o snd-soc-ml26124-objs := ml26124.o
snd-soc-hdmi-codec-objs := hdmi.o
snd-soc-pcm1681-objs := pcm1681.o snd-soc-pcm1681-objs := pcm1681.o
snd-soc-pcm1792a-codec-objs := pcm1792a.o snd-soc-pcm1792a-codec-objs := pcm1792a.o
snd-soc-pcm3008-objs := pcm3008.o snd-soc-pcm3008-objs := pcm3008.o
...@@ -216,6 +216,7 @@ obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o ...@@ -216,6 +216,7 @@ obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o
obj-$(CONFIG_SND_SOC_AK4613) += snd-soc-ak4613.o
obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
...@@ -264,7 +265,6 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o ...@@ -264,7 +265,6 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
......
This diff is collapsed.
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
* AK4648 is tested. * AK4648 is tested.
*/ */
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -128,11 +130,8 @@ ...@@ -128,11 +130,8 @@
#define I2S (3 << 0) #define I2S (3 << 0)
/* MD_CTL2 */ /* MD_CTL2 */
#define FS0 (1 << 0) #define FSs(val) (((val & 0x7) << 0) | ((val & 0x8) << 2))
#define FS1 (1 << 1) #define PSs(val) ((val & 0x3) << 6)
#define FS2 (1 << 2)
#define FS3 (1 << 5)
#define FS_MASK (FS0 | FS1 | FS2 | FS3)
/* MD_CTL3 */ /* MD_CTL3 */
#define BST1 (1 << 3) #define BST1 (1 << 3)
...@@ -147,6 +146,7 @@ struct ak4642_drvdata { ...@@ -147,6 +146,7 @@ struct ak4642_drvdata {
struct ak4642_priv { struct ak4642_priv {
const struct ak4642_drvdata *drvdata; const struct ak4642_drvdata *drvdata;
struct clk *mcko;
}; };
/* /*
...@@ -430,56 +430,56 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -430,56 +430,56 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0; return 0;
} }
static int ak4642_set_mcko(struct snd_soc_codec *codec,
u32 frequency)
{
u32 fs_list[] = {
[0] = 8000,
[1] = 12000,
[2] = 16000,
[3] = 24000,
[4] = 7350,
[5] = 11025,
[6] = 14700,
[7] = 22050,
[10] = 32000,
[11] = 48000,
[14] = 29400,
[15] = 44100,
};
u32 ps_list[] = {
[0] = 256,
[1] = 128,
[2] = 64,
[3] = 32
};
int ps, fs;
for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) {
for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) {
if (frequency == ps_list[ps] * fs_list[fs]) {
snd_soc_write(codec, MD_CTL2,
PSs(ps) | FSs(fs));
return 0;
}
}
}
return 0;
}
static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
u8 rate; struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
u32 rate = clk_get_rate(priv->mcko);
switch (params_rate(params)) { if (!rate)
case 7350: rate = params_rate(params) * 256;
rate = FS2;
break;
case 8000:
rate = 0;
break;
case 11025:
rate = FS2 | FS0;
break;
case 12000:
rate = FS0;
break;
case 14700:
rate = FS2 | FS1;
break;
case 16000:
rate = FS1;
break;
case 22050:
rate = FS2 | FS1 | FS0;
break;
case 24000:
rate = FS1 | FS0;
break;
case 29400:
rate = FS3 | FS2 | FS1;
break;
case 32000:
rate = FS3 | FS1;
break;
case 44100:
rate = FS3 | FS2 | FS1 | FS0;
break;
case 48000:
rate = FS3 | FS1 | FS0;
break;
default:
return -EINVAL;
}
snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
return 0; return ak4642_set_mcko(codec, rate);
} }
static int ak4642_set_bias_level(struct snd_soc_codec *codec, static int ak4642_set_bias_level(struct snd_soc_codec *codec,
...@@ -532,7 +532,18 @@ static int ak4642_resume(struct snd_soc_codec *codec) ...@@ -532,7 +532,18 @@ static int ak4642_resume(struct snd_soc_codec *codec)
return 0; return 0;
} }
static int ak4642_probe(struct snd_soc_codec *codec)
{
struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
if (priv->mcko)
ak4642_set_mcko(codec, clk_get_rate(priv->mcko));
return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
.probe = ak4642_probe,
.resume = ak4642_resume, .resume = ak4642_resume,
.set_bias_level = ak4642_set_bias_level, .set_bias_level = ak4642_set_bias_level,
.controls = ak4642_snd_controls, .controls = ak4642_snd_controls,
...@@ -580,19 +591,54 @@ static const struct ak4642_drvdata ak4648_drvdata = { ...@@ -580,19 +591,54 @@ static const struct ak4642_drvdata ak4648_drvdata = {
.extended_frequencies = 1, .extended_frequencies = 1,
}; };
#ifdef CONFIG_COMMON_CLK
static struct clk *ak4642_of_parse_mcko(struct device *dev)
{
struct device_node *np = dev->of_node;
struct clk *clk;
const char *clk_name = np->name;
const char *parent_clk_name = NULL;
u32 rate;
if (of_property_read_u32(np, "clock-frequency", &rate))
return NULL;
if (of_property_read_bool(np, "clocks"))
parent_clk_name = of_clk_get_parent_name(np, 0);
of_property_read_string(np, "clock-output-names", &clk_name);
clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name,
(parent_clk_name) ? 0 : CLK_IS_ROOT,
rate);
if (!IS_ERR(clk))
of_clk_add_provider(np, of_clk_src_simple_get, clk);
return clk;
}
#else
#define ak4642_of_parse_mcko(d) 0
#endif
static const struct of_device_id ak4642_of_match[]; static const struct of_device_id ak4642_of_match[];
static int ak4642_i2c_probe(struct i2c_client *i2c, static int ak4642_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device_node *np = i2c->dev.of_node; struct device *dev = &i2c->dev;
struct device_node *np = dev->of_node;
const struct ak4642_drvdata *drvdata = NULL; const struct ak4642_drvdata *drvdata = NULL;
struct regmap *regmap; struct regmap *regmap;
struct ak4642_priv *priv; struct ak4642_priv *priv;
struct clk *mcko = NULL;
if (np) { if (np) {
const struct of_device_id *of_id; const struct of_device_id *of_id;
of_id = of_match_device(ak4642_of_match, &i2c->dev); mcko = ak4642_of_parse_mcko(dev);
if (IS_ERR(mcko))
mcko = NULL;
of_id = of_match_device(ak4642_of_match, dev);
if (of_id) if (of_id)
drvdata = of_id->data; drvdata = of_id->data;
} else { } else {
...@@ -600,15 +646,16 @@ static int ak4642_i2c_probe(struct i2c_client *i2c, ...@@ -600,15 +646,16 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
} }
if (!drvdata) { if (!drvdata) {
dev_err(&i2c->dev, "Unknown device type\n"); dev_err(dev, "Unknown device type\n");
return -EINVAL; return -EINVAL;
} }
priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
priv->drvdata = drvdata; priv->drvdata = drvdata;
priv->mcko = mcko;
i2c_set_clientdata(i2c, priv); i2c_set_clientdata(i2c, priv);
...@@ -616,7 +663,7 @@ static int ak4642_i2c_probe(struct i2c_client *i2c, ...@@ -616,7 +663,7 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
if (IS_ERR(regmap)) if (IS_ERR(regmap))
return PTR_ERR(regmap); return PTR_ERR(regmap);
return snd_soc_register_codec(&i2c->dev, return snd_soc_register_codec(dev,
&soc_codec_dev_ak4642, &ak4642_dai, 1); &soc_codec_dev_ak4642, &ak4642_dai, 1);
} }
......
...@@ -147,6 +147,8 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, ...@@ -147,6 +147,8 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
0x4f5, 0x0da); 0x4f5, 0x0da);
} }
break; break;
default:
break;
} }
return 0; return 0;
...@@ -689,6 +691,15 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) ...@@ -689,6 +691,15 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
ARIZONA_IN_VU, val); ARIZONA_IN_VU, val);
} }
bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
{
unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
unsigned int val = snd_soc_read(codec, reg);
return !(val & ARIZONA_IN1_MODE_MASK);
}
EXPORT_SYMBOL_GPL(arizona_input_analog);
int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
int event) int event)
{ {
...@@ -725,6 +736,9 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, ...@@ -725,6 +736,9 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES); reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
if (reg == 0) if (reg == 0)
arizona_in_set_vu(codec, 0); arizona_in_set_vu(codec, 0);
break;
default:
break;
} }
return 0; return 0;
...@@ -806,6 +820,8 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, ...@@ -806,6 +820,8 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
break; break;
} }
break; break;
default:
break;
} }
return 0; return 0;
......
...@@ -294,4 +294,6 @@ extern int arizona_init_dai(struct arizona_priv *priv, int dai); ...@@ -294,4 +294,6 @@ extern int arizona_init_dai(struct arizona_priv *priv, int dai);
int arizona_set_output_mode(struct snd_soc_codec *codec, int output, int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
bool diff); bool diff);
extern bool arizona_input_analog(struct snd_soc_codec *codec, int shift);
#endif #endif
/*
* ALSA SoC codec driver for HDMI audio codecs.
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
* Author: Ricardo Neri <ricardo.neri@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/module.h>
#include <sound/soc.h>
#include <linux/of.h>
#include <linux/of_device.h>
#define DRV_NAME "hdmi-audio-codec"
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
SND_SOC_DAPM_INPUT("RX"),
SND_SOC_DAPM_OUTPUT("TX"),
};
static const struct snd_soc_dapm_route hdmi_routes[] = {
{ "Capture", NULL, "RX" },
{ "TX", NULL, "Playback" },
};
static struct snd_soc_dai_driver hdmi_codec_dai = {
.name = "hdmi-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
.sig_bits = 24,
},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE,
},
};
#ifdef CONFIG_OF
static const struct of_device_id hdmi_audio_codec_ids[] = {
{ .compatible = "linux,hdmi-audio", },
{ }
};
MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
#endif
static struct snd_soc_codec_driver hdmi_codec = {
.dapm_widgets = hdmi_widgets,
.num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
.dapm_routes = hdmi_routes,
.num_dapm_routes = ARRAY_SIZE(hdmi_routes),
.ignore_pmdown_time = true,
};
static int hdmi_codec_probe(struct platform_device *pdev)
{
return snd_soc_register_codec(&pdev->dev, &hdmi_codec,
&hdmi_codec_dai, 1);
}
static int hdmi_codec_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver hdmi_codec_driver = {
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(hdmi_audio_codec_ids),
},
.probe = hdmi_codec_probe,
.remove = hdmi_codec_remove,
};
module_platform_driver(hdmi_codec_driver);
MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
MODULE_DESCRIPTION("ASoC generic HDMI codec driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
...@@ -2829,6 +2829,9 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert) ...@@ -2829,6 +2829,9 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
rt5645->jack_type = SND_JACK_HEADPHONE; rt5645->jack_type = SND_JACK_HEADPHONE;
} }
if (rt5645->pdata.jd_invert)
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
} else { /* jack out */ } else { /* jack out */
rt5645->jack_type = 0; rt5645->jack_type = 0;
...@@ -2847,6 +2850,9 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert) ...@@ -2847,6 +2850,9 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
snd_soc_dapm_disable_pin(dapm, "LDO2"); snd_soc_dapm_disable_pin(dapm, "LDO2");
snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm);
if (rt5645->pdata.jd_invert)
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
} }
return rt5645->jack_type; return rt5645->jack_type;
...@@ -3212,6 +3218,32 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { ...@@ -3212,6 +3218,32 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
{ } { }
}; };
static struct rt5645_platform_data buddy_platform_data = {
.dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
.dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
.jd_mode = 3,
.jd_invert = true,
};
static int buddy_quirk_cb(const struct dmi_system_id *id)
{
rt5645_pdata = &buddy_platform_data;
return 1;
}
static struct dmi_system_id dmi_platform_intel_broadwell[] __initdata = {
{
.ident = "Chrome Buddy",
.callback = buddy_quirk_cb,
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
},
},
{ }
};
static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
{ {
rt5645->pdata.in2_diff = device_property_read_bool(dev, rt5645->pdata.in2_diff = device_property_read_bool(dev,
...@@ -3244,7 +3276,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, ...@@ -3244,7 +3276,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
if (pdata) if (pdata)
rt5645->pdata = *pdata; rt5645->pdata = *pdata;
else if (dmi_check_system(dmi_platform_intel_braswell)) else if (dmi_check_system(dmi_platform_intel_braswell) ||
dmi_check_system(dmi_platform_intel_broadwell))
rt5645->pdata = *rt5645_pdata; rt5645->pdata = *rt5645_pdata;
else else
rt5645_parse_dt(rt5645, &i2c->dev); rt5645_parse_dt(rt5645, &i2c->dev);
......
...@@ -779,8 +779,6 @@ ...@@ -779,8 +779,6 @@
#define RT5645_PWR_CLS_D_R_BIT 9 #define RT5645_PWR_CLS_D_R_BIT 9
#define RT5645_PWR_CLS_D_L (0x1 << 8) #define RT5645_PWR_CLS_D_L (0x1 << 8)
#define RT5645_PWR_CLS_D_L_BIT 8 #define RT5645_PWR_CLS_D_L_BIT 8
#define RT5645_PWR_ADC_R (0x1 << 1)
#define RT5645_PWR_ADC_R_BIT 1
#define RT5645_PWR_DAC_L2 (0x1 << 7) #define RT5645_PWR_DAC_L2 (0x1 << 7)
#define RT5645_PWR_DAC_L2_BIT 7 #define RT5645_PWR_DAC_L2_BIT 7
#define RT5645_PWR_DAC_R2 (0x1 << 6) #define RT5645_PWR_DAC_R2 (0x1 << 6)
...@@ -1628,6 +1626,10 @@ ...@@ -1628,6 +1626,10 @@
#define RT5645_OT_P_NOR (0x0 << 10) #define RT5645_OT_P_NOR (0x0 << 10)
#define RT5645_OT_P_INV (0x1 << 10) #define RT5645_OT_P_INV (0x1 << 10)
#define RT5645_IRQ_JD_1_1_EN (0x1 << 9) #define RT5645_IRQ_JD_1_1_EN (0x1 << 9)
#define RT5645_JD_1_1_MASK (0x1 << 7)
#define RT5645_JD_1_1_SFT 7
#define RT5645_JD_1_1_NOR (0x0 << 7)
#define RT5645_JD_1_1_INV (0x1 << 7)
/* IRQ Control 2 (0xbe) */ /* IRQ Control 2 (0xbe) */
#define RT5645_IRQ_MB1_OC_MASK (0x1 << 15) #define RT5645_IRQ_MB1_OC_MASK (0x1 << 15)
......
...@@ -80,6 +80,7 @@ struct aic3x_priv { ...@@ -80,6 +80,7 @@ struct aic3x_priv {
unsigned int sysclk; unsigned int sysclk;
unsigned int dai_fmt; unsigned int dai_fmt;
unsigned int tdm_delay; unsigned int tdm_delay;
unsigned int slot_width;
struct list_head list; struct list_head list;
int master; int master;
int gpio_reset; int gpio_reset;
...@@ -1025,10 +1026,14 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, ...@@ -1025,10 +1026,14 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
u16 d, pll_d = 1; u16 d, pll_d = 1;
int clk; int clk;
int width = aic3x->slot_width;
if (!width)
width = params_width(params);
/* select data word length */ /* select data word length */
data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4)); data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
switch (params_width(params)) { switch (width) {
case 16: case 16:
break; break;
case 20: case 20:
...@@ -1170,12 +1175,16 @@ static int aic3x_prepare(struct snd_pcm_substream *substream, ...@@ -1170,12 +1175,16 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int delay = 0; int delay = 0;
int width = aic3x->slot_width;
if (!width)
width = substream->runtime->sample_bits;
/* TDM slot selection only valid in DSP_A/_B mode */ /* TDM slot selection only valid in DSP_A/_B mode */
if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A) if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A)
delay += (aic3x->tdm_delay + 1); delay += (aic3x->tdm_delay*width + 1);
else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B) else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B)
delay += aic3x->tdm_delay; delay += aic3x->tdm_delay*width;
/* Configure data delay */ /* Configure data delay */
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay); snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
...@@ -1296,7 +1305,20 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai, ...@@ -1296,7 +1305,20 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
return -EINVAL; return -EINVAL;
} }
aic3x->tdm_delay = lsb * slot_width; switch (slot_width) {
case 16:
case 20:
case 24:
case 32:
break;
default:
dev_err(codec->dev, "Unsupported slot width %d\n", slot_width);
return -EINVAL;
}
aic3x->tdm_delay = lsb;
aic3x->slot_width = slot_width;
/* DOUT in high-impedance on inactive bit clocks */ /* DOUT in high-impedance on inactive bit clocks */
snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA, snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA,
......
...@@ -38,6 +38,12 @@ ...@@ -38,6 +38,12 @@
struct wm5110_priv { struct wm5110_priv {
struct arizona_priv core; struct arizona_priv core;
struct arizona_fll fll[2]; struct arizona_fll fll[2];
unsigned int in_value;
int in_pre_pending;
int in_post_pending;
unsigned int in_pga_cache[6];
}; };
static const struct wm_adsp_region wm5110_dsp1_regions[] = { static const struct wm_adsp_region wm5110_dsp1_regions[] = {
...@@ -428,6 +434,127 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, ...@@ -428,6 +434,127 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol,
return ret; return ret;
} }
static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_card *card = dapm->card;
int ret;
/*
* PGA Volume is also used as part of the enable sequence, so
* usage of it should be avoided whilst that is running.
*/
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_get_volsw_range(kcontrol, ucontrol);
mutex_unlock(&card->dapm_mutex);
return ret;
}
static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_card *card = dapm->card;
int ret;
/*
* PGA Volume is also used as part of the enable sequence, so
* usage of it should be avoided whilst that is running.
*/
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
ret = snd_soc_put_volsw_range(kcontrol, ucontrol);
mutex_unlock(&card->dapm_mutex);
return ret;
}
static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
unsigned int reg, mask;
struct reg_sequence analog_seq[] = {
{ 0x80, 0x3 },
{ 0x35d, 0 },
{ 0x80, 0x0 },
};
reg = ARIZONA_IN1L_CONTROL + ((w->shift ^ 0x1) * 4);
mask = ARIZONA_IN1L_PGA_VOL_MASK;
switch (event) {
case SND_SOC_DAPM_WILL_PMU:
wm5110->in_value |= 0x3 << ((w->shift ^ 0x1) * 2);
wm5110->in_pre_pending++;
wm5110->in_post_pending++;
return 0;
case SND_SOC_DAPM_PRE_PMU:
wm5110->in_pga_cache[w->shift] = snd_soc_read(codec, reg);
snd_soc_update_bits(codec, reg, mask,
0x40 << ARIZONA_IN1L_PGA_VOL_SHIFT);
wm5110->in_pre_pending--;
if (wm5110->in_pre_pending == 0) {
analog_seq[1].def = wm5110->in_value;
regmap_multi_reg_write_bypassed(arizona->regmap,
analog_seq,
ARRAY_SIZE(analog_seq));
msleep(55);
wm5110->in_value = 0;
}
break;
case SND_SOC_DAPM_POST_PMU:
snd_soc_update_bits(codec, reg, mask,
wm5110->in_pga_cache[w->shift]);
wm5110->in_post_pending--;
if (wm5110->in_post_pending == 0)
regmap_multi_reg_write_bypassed(arizona->regmap,
analog_seq,
ARRAY_SIZE(analog_seq));
break;
default:
break;
}
return 0;
}
static int wm5110_in_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
switch (arizona->rev) {
case 0 ... 4:
if (arizona_input_analog(codec, w->shift))
wm5110_in_analog_ev(w, kcontrol, event);
break;
default:
break;
}
return arizona_in_ev(w, kcontrol, event);
}
static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
...@@ -454,18 +581,24 @@ SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]), ...@@ -454,18 +581,24 @@ SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
SOC_ENUM("IN3 OSR", arizona_in_dmic_osr[2]), SOC_ENUM("IN3 OSR", arizona_in_dmic_osr[2]),
SOC_ENUM("IN4 OSR", arizona_in_dmic_osr[3]), SOC_ENUM("IN4 OSR", arizona_in_dmic_osr[3]),
SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL, SOC_SINGLE_RANGE_EXT_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL, wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), SOC_SINGLE_RANGE_EXT_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
SOC_SINGLE_RANGE_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL, ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
SOC_SINGLE_RANGE_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL, SOC_SINGLE_RANGE_EXT_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL,
ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
SOC_SINGLE_RANGE_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL, wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), SOC_SINGLE_RANGE_EXT_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL,
SOC_SINGLE_RANGE_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL, ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
SOC_SINGLE_RANGE_EXT_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL,
ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
SOC_SINGLE_RANGE_EXT_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL,
ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum), SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
...@@ -896,29 +1029,35 @@ SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"), ...@@ -896,29 +1029,35 @@ SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"), SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
0, NULL, 0, arizona_in_ev, 0, NULL, 0, wm5110_in_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_WILL_PMU),
SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
0, NULL, 0, arizona_in_ev, 0, NULL, 0, wm5110_in_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_WILL_PMU),
SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
0, NULL, 0, arizona_in_ev, 0, NULL, 0, wm5110_in_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_WILL_PMU),
SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
0, NULL, 0, arizona_in_ev, 0, NULL, 0, wm5110_in_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_WILL_PMU),
SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
0, NULL, 0, arizona_in_ev, 0, NULL, 0, wm5110_in_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_WILL_PMU),
SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
0, NULL, 0, arizona_in_ev, 0, NULL, 0, wm5110_in_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_WILL_PMU),
SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
0, NULL, 0, arizona_in_ev, 0, NULL, 0, arizona_in_ev,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
......
This diff is collapsed.
...@@ -593,6 +593,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = { ...@@ -593,6 +593,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
{ .compatible = "fsl,imx-audio-wm8960", }, { .compatible = "fsl,imx-audio-wm8960", },
{} {}
}; };
MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
static struct platform_driver fsl_asoc_card_driver = { static struct platform_driver fsl_asoc_card_driver = {
.probe = fsl_asoc_card_probe, .probe = fsl_asoc_card_probe,
......
...@@ -801,6 +801,7 @@ static const struct of_device_id fsl_sai_ids[] = { ...@@ -801,6 +801,7 @@ static const struct of_device_id fsl_sai_ids[] = {
{ .compatible = "fsl,imx6sx-sai", }, { .compatible = "fsl,imx6sx-sai", },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, fsl_sai_ids);
static struct platform_driver fsl_sai_driver = { static struct platform_driver fsl_sai_driver = {
.probe = fsl_sai_probe, .probe = fsl_sai_probe,
......
...@@ -151,7 +151,9 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, ...@@ -151,7 +151,9 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
} }
if (set->slots) { if (set->slots) {
ret = snd_soc_dai_set_tdm_slot(dai, 0, 0, ret = snd_soc_dai_set_tdm_slot(dai,
set->tx_slot_mask,
set->rx_slot_mask,
set->slots, set->slots,
set->slot_width); set->slot_width);
if (ret && ret != -ENOTSUPP) { if (ret && ret != -ENOTSUPP) {
...@@ -243,7 +245,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np, ...@@ -243,7 +245,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
return ret; return ret;
/* Parse TDM slot */ /* Parse TDM slot */
ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask,
&dai->rx_slot_mask,
&dai->slots, &dai->slot_width);
if (ret) if (ret)
return ret; return ret;
......
...@@ -368,23 +368,6 @@ static void sst_media_close(struct snd_pcm_substream *substream, ...@@ -368,23 +368,6 @@ static void sst_media_close(struct snd_pcm_substream *substream,
kfree(stream); kfree(stream);
} }
static inline unsigned int get_current_pipe_id(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream)
{
struct sst_data *sst = snd_soc_dai_get_drvdata(dai);
struct sst_dev_stream_map *map = sst->pdata->pdev_strm_map;
struct sst_runtime_stream *stream =
substream->runtime->private_data;
u32 str_id = stream->stream_info.str_id;
unsigned int pipe_id;
pipe_id = map[str_id].device_id;
dev_dbg(dai->dev, "got pipe_id = %#x for str_id = %d\n",
pipe_id, str_id);
return pipe_id;
}
static int sst_media_prepare(struct snd_pcm_substream *substream, static int sst_media_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
......
...@@ -266,18 +266,11 @@ static int broadwell_audio_probe(struct platform_device *pdev) ...@@ -266,18 +266,11 @@ static int broadwell_audio_probe(struct platform_device *pdev)
{ {
broadwell_rt286.dev = &pdev->dev; broadwell_rt286.dev = &pdev->dev;
return snd_soc_register_card(&broadwell_rt286); return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286);
}
static int broadwell_audio_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&broadwell_rt286);
return 0;
} }
static struct platform_driver broadwell_audio = { static struct platform_driver broadwell_audio = {
.probe = broadwell_audio_probe, .probe = broadwell_audio_probe,
.remove = broadwell_audio_remove,
.driver = { .driver = {
.name = "broadwell-audio", .name = "broadwell-audio",
}, },
......
...@@ -509,17 +509,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { ...@@ -509,17 +509,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
}, },
}, },
{
.name = "DMIC23 Pin",
.ops = &skl_dmic_dai_ops,
.capture = {
.stream_name = "DMIC23 Rx",
.channels_min = HDA_STEREO,
.channels_max = HDA_STEREO,
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
},
},
{ {
.name = "HD-Codec Pin", .name = "HD-Codec Pin",
.ops = &skl_link_dai_ops, .ops = &skl_link_dai_ops,
...@@ -538,28 +527,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { ...@@ -538,28 +527,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.formats = SNDRV_PCM_FMTBIT_S16_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE,
}, },
}, },
{
.name = "HD-Codec-SPK Pin",
.ops = &skl_link_dai_ops,
.playback = {
.stream_name = "HD-Codec-SPK Tx",
.channels_min = HDA_STEREO,
.channels_max = HDA_STEREO,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
},
{
.name = "HD-Codec-AMIC Pin",
.ops = &skl_link_dai_ops,
.capture = {
.stream_name = "HD-Codec-AMIC Rx",
.channels_min = HDA_STEREO,
.channels_max = HDA_STEREO,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
},
}; };
static int skl_platform_open(struct snd_pcm_substream *substream) static int skl_platform_open(struct snd_pcm_substream *substream)
......
...@@ -485,6 +485,7 @@ static const struct of_device_id jz4740_of_matches[] = { ...@@ -485,6 +485,7 @@ static const struct of_device_id jz4740_of_matches[] = {
{ .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 }, { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, jz4740_of_matches);
#endif #endif
static int jz4740_i2s_dev_probe(struct platform_device *pdev) static int jz4740_i2s_dev_probe(struct platform_device *pdev)
......
...@@ -130,6 +130,7 @@ static const struct of_device_id a370db_dt_ids[] = { ...@@ -130,6 +130,7 @@ static const struct of_device_id a370db_dt_ids[] = {
{ .compatible = "marvell,a370db-audio" }, { .compatible = "marvell,a370db-audio" },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, a370db_dt_ids);
static struct platform_driver a370db_driver = { static struct platform_driver a370db_driver = {
.driver = { .driver = {
......
...@@ -179,21 +179,13 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev) ...@@ -179,21 +179,13 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
} }
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) if (ret)
dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
static int mt8173_max98090_dev_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static const struct of_device_id mt8173_max98090_dt_match[] = { static const struct of_device_id mt8173_max98090_dt_match[] = {
{ .compatible = "mediatek,mt8173-max98090", }, { .compatible = "mediatek,mt8173-max98090", },
{ } { }
...@@ -209,7 +201,6 @@ static struct platform_driver mt8173_max98090_driver = { ...@@ -209,7 +201,6 @@ static struct platform_driver mt8173_max98090_driver = {
#endif #endif
}, },
.probe = mt8173_max98090_dev_probe, .probe = mt8173_max98090_dev_probe,
.remove = mt8173_max98090_dev_remove,
}; };
module_platform_driver(mt8173_max98090_driver); module_platform_driver(mt8173_max98090_driver);
......
...@@ -246,21 +246,13 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) ...@@ -246,21 +246,13 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
platform_set_drvdata(pdev, card); platform_set_drvdata(pdev, card);
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) if (ret)
dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
static int mt8173_rt5650_rt5676_dev_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = { static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = {
{ .compatible = "mediatek,mt8173-rt5650-rt5676", }, { .compatible = "mediatek,mt8173-rt5650-rt5676", },
{ } { }
...@@ -276,7 +268,6 @@ static struct platform_driver mt8173_rt5650_rt5676_driver = { ...@@ -276,7 +268,6 @@ static struct platform_driver mt8173_rt5650_rt5676_driver = {
#endif #endif
}, },
.probe = mt8173_rt5650_rt5676_dev_probe, .probe = mt8173_rt5650_rt5676_dev_probe,
.remove = mt8173_rt5650_rt5676_dev_remove,
}; };
module_platform_driver(mt8173_rt5650_rt5676_driver); module_platform_driver(mt8173_rt5650_rt5676_driver);
......
...@@ -142,7 +142,7 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev) ...@@ -142,7 +142,7 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
platform_set_drvdata(pdev, card); platform_set_drvdata(pdev, card);
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
ret); ret);
...@@ -154,12 +154,8 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev) ...@@ -154,12 +154,8 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
static int mxs_sgtl5000_remove(struct platform_device *pdev) static int mxs_sgtl5000_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev);
mxs_saif_put_mclk(0); mxs_saif_put_mclk(0);
snd_soc_unregister_card(card);
return 0; return 0;
} }
......
...@@ -116,26 +116,19 @@ static int brownstone_probe(struct platform_device *pdev) ...@@ -116,26 +116,19 @@ static int brownstone_probe(struct platform_device *pdev)
int ret; int ret;
brownstone.dev = &pdev->dev; brownstone.dev = &pdev->dev;
ret = snd_soc_register_card(&brownstone); ret = devm_snd_soc_register_card(&pdev->dev, &brownstone);
if (ret) if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret; return ret;
} }
static int brownstone_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&brownstone);
return 0;
}
static struct platform_driver mmp_driver = { static struct platform_driver mmp_driver = {
.driver = { .driver = {
.name = "brownstone-audio", .name = "brownstone-audio",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = brownstone_probe, .probe = brownstone_probe,
.remove = brownstone_remove,
}; };
module_platform_driver(mmp_driver); module_platform_driver(mmp_driver);
......
...@@ -295,28 +295,19 @@ static int corgi_probe(struct platform_device *pdev) ...@@ -295,28 +295,19 @@ static int corgi_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret; return ret;
} }
static int corgi_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static struct platform_driver corgi_driver = { static struct platform_driver corgi_driver = {
.driver = { .driver = {
.name = "corgi-audio", .name = "corgi-audio",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = corgi_probe, .probe = corgi_probe,
.remove = corgi_remove,
}; };
module_platform_driver(corgi_driver); module_platform_driver(corgi_driver);
......
...@@ -138,7 +138,7 @@ static int e740_probe(struct platform_device *pdev) ...@@ -138,7 +138,7 @@ static int e740_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
...@@ -149,10 +149,7 @@ static int e740_probe(struct platform_device *pdev) ...@@ -149,10 +149,7 @@ static int e740_probe(struct platform_device *pdev)
static int e740_remove(struct platform_device *pdev) static int e740_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev);
gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios)); gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios));
snd_soc_unregister_card(card);
return 0; return 0;
} }
......
...@@ -120,7 +120,7 @@ static int e750_probe(struct platform_device *pdev) ...@@ -120,7 +120,7 @@ static int e750_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
...@@ -131,10 +131,7 @@ static int e750_probe(struct platform_device *pdev) ...@@ -131,10 +131,7 @@ static int e750_probe(struct platform_device *pdev)
static int e750_remove(struct platform_device *pdev) static int e750_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev);
gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios)); gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios));
snd_soc_unregister_card(card);
return 0; return 0;
} }
......
...@@ -119,7 +119,7 @@ static int e800_probe(struct platform_device *pdev) ...@@ -119,7 +119,7 @@ static int e800_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
...@@ -130,10 +130,7 @@ static int e800_probe(struct platform_device *pdev) ...@@ -130,10 +130,7 @@ static int e800_probe(struct platform_device *pdev)
static int e800_remove(struct platform_device *pdev) static int e800_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev);
gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios)); gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios));
snd_soc_unregister_card(card);
return 0; return 0;
} }
......
...@@ -193,7 +193,7 @@ static int hx4700_audio_probe(struct platform_device *pdev) ...@@ -193,7 +193,7 @@ static int hx4700_audio_probe(struct platform_device *pdev)
return ret; return ret;
snd_soc_card_hx4700.dev = &pdev->dev; snd_soc_card_hx4700.dev = &pdev->dev;
ret = snd_soc_register_card(&snd_soc_card_hx4700); ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_hx4700);
if (ret) if (ret)
gpio_free_array(hx4700_audio_gpios, gpio_free_array(hx4700_audio_gpios,
ARRAY_SIZE(hx4700_audio_gpios)); ARRAY_SIZE(hx4700_audio_gpios));
...@@ -203,8 +203,6 @@ static int hx4700_audio_probe(struct platform_device *pdev) ...@@ -203,8 +203,6 @@ static int hx4700_audio_probe(struct platform_device *pdev)
static int hx4700_audio_remove(struct platform_device *pdev) static int hx4700_audio_remove(struct platform_device *pdev)
{ {
snd_soc_unregister_card(&snd_soc_card_hx4700);
gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0); gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
gpio_set_value(GPIO107_HX4700_SPK_nSD, 0); gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
......
...@@ -72,28 +72,19 @@ static int imote2_probe(struct platform_device *pdev) ...@@ -72,28 +72,19 @@ static int imote2_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret; return ret;
} }
static int imote2_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static struct platform_driver imote2_driver = { static struct platform_driver imote2_driver = {
.driver = { .driver = {
.name = "imote2-audio", .name = "imote2-audio",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = imote2_probe, .probe = imote2_probe,
.remove = imote2_remove,
}; };
module_platform_driver(imote2_driver); module_platform_driver(imote2_driver);
......
...@@ -181,7 +181,7 @@ static int mioa701_wm9713_probe(struct platform_device *pdev) ...@@ -181,7 +181,7 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
mioa701.dev = &pdev->dev; mioa701.dev = &pdev->dev;
rc = snd_soc_register_card(&mioa701); rc = devm_snd_soc_register_card(&pdev->dev, &mioa701);
if (!rc) if (!rc)
dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will" dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
"lead to overheating and possible destruction of your device." "lead to overheating and possible destruction of your device."
...@@ -189,17 +189,8 @@ static int mioa701_wm9713_probe(struct platform_device *pdev) ...@@ -189,17 +189,8 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
return rc; return rc;
} }
static int mioa701_wm9713_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static struct platform_driver mioa701_wm9713_driver = { static struct platform_driver mioa701_wm9713_driver = {
.probe = mioa701_wm9713_probe, .probe = mioa701_wm9713_probe,
.remove = mioa701_wm9713_remove,
.driver = { .driver = {
.name = "mioa701-wm9713", .name = "mioa701-wm9713",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
......
...@@ -140,22 +140,15 @@ static int palm27x_asoc_probe(struct platform_device *pdev) ...@@ -140,22 +140,15 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
palm27x_asoc.dev = &pdev->dev; palm27x_asoc.dev = &pdev->dev;
ret = snd_soc_register_card(&palm27x_asoc); ret = devm_snd_soc_register_card(&pdev->dev, &palm27x_asoc);
if (ret) if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret; return ret;
} }
static int palm27x_asoc_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&palm27x_asoc);
return 0;
}
static struct platform_driver palm27x_wm9712_driver = { static struct platform_driver palm27x_wm9712_driver = {
.probe = palm27x_asoc_probe, .probe = palm27x_asoc_probe,
.remove = palm27x_asoc_remove,
.driver = { .driver = {
.name = "palm27x-asoc", .name = "palm27x-asoc",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
......
...@@ -267,28 +267,19 @@ static int poodle_probe(struct platform_device *pdev) ...@@ -267,28 +267,19 @@ static int poodle_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret; return ret;
} }
static int poodle_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static struct platform_driver poodle_driver = { static struct platform_driver poodle_driver = {
.driver = { .driver = {
.name = "poodle-audio", .name = "poodle-audio",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = poodle_probe, .probe = poodle_probe,
.remove = poodle_remove,
}; };
module_platform_driver(poodle_driver); module_platform_driver(poodle_driver);
......
...@@ -809,6 +809,7 @@ static const struct of_device_id pxa_ssp_of_ids[] = { ...@@ -809,6 +809,7 @@ static const struct of_device_id pxa_ssp_of_ids[] = {
{ .compatible = "mrvl,pxa-ssp-dai" }, { .compatible = "mrvl,pxa-ssp-dai" },
{} {}
}; };
MODULE_DEVICE_TABLE(of, pxa_ssp_of_ids);
#endif #endif
static int asoc_ssp_probe(struct platform_device *pdev) static int asoc_ssp_probe(struct platform_device *pdev)
......
...@@ -132,6 +132,7 @@ static const struct of_device_id snd_soc_pxa_audio_match[] = { ...@@ -132,6 +132,7 @@ static const struct of_device_id snd_soc_pxa_audio_match[] = {
{ .compatible = "mrvl,pxa-pcm-audio" }, { .compatible = "mrvl,pxa-pcm-audio" },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, snd_soc_pxa_audio_match);
#endif #endif
static struct platform_driver pxa_pcm_driver = { static struct platform_driver pxa_pcm_driver = {
......
...@@ -305,7 +305,7 @@ static int spitz_probe(struct platform_device *pdev) ...@@ -305,7 +305,7 @@ static int spitz_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
...@@ -322,9 +322,6 @@ static int spitz_probe(struct platform_device *pdev) ...@@ -322,9 +322,6 @@ static int spitz_probe(struct platform_device *pdev)
static int spitz_remove(struct platform_device *pdev) static int spitz_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
gpio_free(spitz_mic_gpio); gpio_free(spitz_mic_gpio);
return 0; return 0;
} }
......
...@@ -233,7 +233,7 @@ static int tosa_probe(struct platform_device *pdev) ...@@ -233,7 +233,7 @@ static int tosa_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
...@@ -244,10 +244,7 @@ static int tosa_probe(struct platform_device *pdev) ...@@ -244,10 +244,7 @@ static int tosa_probe(struct platform_device *pdev)
static int tosa_remove(struct platform_device *pdev) static int tosa_remove(struct platform_device *pdev)
{ {
struct snd_soc_card *card = platform_get_drvdata(pdev);
gpio_free(TOSA_GPIO_L_MUTE); gpio_free(TOSA_GPIO_L_MUTE);
snd_soc_unregister_card(card);
return 0; return 0;
} }
......
...@@ -128,7 +128,7 @@ static int ttc_dkb_probe(struct platform_device *pdev) ...@@ -128,7 +128,7 @@ static int ttc_dkb_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
...@@ -136,22 +136,12 @@ static int ttc_dkb_probe(struct platform_device *pdev) ...@@ -136,22 +136,12 @@ static int ttc_dkb_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int ttc_dkb_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
return 0;
}
static struct platform_driver ttc_dkb_driver = { static struct platform_driver ttc_dkb_driver = {
.driver = { .driver = {
.name = "ttc-dkb-audio", .name = "ttc-dkb-audio",
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = ttc_dkb_probe, .probe = ttc_dkb_probe,
.remove = ttc_dkb_remove,
}; };
module_platform_driver(ttc_dkb_driver); module_platform_driver(ttc_dkb_driver);
......
...@@ -438,7 +438,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) ...@@ -438,7 +438,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"%s() error getting mi2s-bit-clk: %ld\n", "%s() error getting mi2s-bit-clk: %ld\n",
__func__, PTR_ERR(drvdata->mi2s_bit_clk[i])); __func__,
PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
} }
} }
......
...@@ -17,7 +17,7 @@ config SND_SOC_ROCKCHIP_I2S ...@@ -17,7 +17,7 @@ config SND_SOC_ROCKCHIP_I2S
config SND_SOC_ROCKCHIP_MAX98090 config SND_SOC_ROCKCHIP_MAX98090
tristate "ASoC support for Rockchip boards using a MAX98090 codec" tristate "ASoC support for Rockchip boards using a MAX98090 codec"
depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
select SND_SOC_ROCKCHIP_I2S select SND_SOC_ROCKCHIP_I2S
select SND_SOC_MAX98090 select SND_SOC_MAX98090
select SND_SOC_TS3A227E select SND_SOC_TS3A227E
...@@ -27,7 +27,7 @@ config SND_SOC_ROCKCHIP_MAX98090 ...@@ -27,7 +27,7 @@ config SND_SOC_ROCKCHIP_MAX98090
config SND_SOC_ROCKCHIP_RT5645 config SND_SOC_ROCKCHIP_RT5645
tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec" tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec"
depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
select SND_SOC_ROCKCHIP_I2S select SND_SOC_ROCKCHIP_I2S
select SND_SOC_RT5645 select SND_SOC_RT5645
help help
......
...@@ -37,6 +37,7 @@ config SND_SOC_SH4_SIU ...@@ -37,6 +37,7 @@ config SND_SOC_SH4_SIU
config SND_SOC_RCAR config SND_SOC_RCAR
tristate "R-Car series SRU/SCU/SSIU/SSI support" tristate "R-Car series SRU/SCU/SSIU/SSI support"
depends on DMA_OF depends on DMA_OF
depends on COMMON_CLK
select SND_SIMPLE_CARD select SND_SIMPLE_CARD
select REGMAP_MMIO select REGMAP_MMIO
help help
......
This diff is collapsed.
...@@ -110,6 +110,7 @@ static const struct rsnd_of_data rsnd_of_data_gen2 = { ...@@ -110,6 +110,7 @@ static const struct rsnd_of_data rsnd_of_data_gen2 = {
static const struct of_device_id rsnd_of_match[] = { static const struct of_device_id rsnd_of_match[] = {
{ .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
{ .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
{ .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */
{}, {},
}; };
MODULE_DEVICE_TABLE(of, rsnd_of_match); MODULE_DEVICE_TABLE(of, rsnd_of_match);
...@@ -126,6 +127,17 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match); ...@@ -126,6 +127,17 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
#define rsnd_info_id(priv, io, name) \ #define rsnd_info_id(priv, io, name) \
((io)->info->name - priv->info->name##_info) ((io)->info->name - priv->info->name##_info)
void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
{
if (mod->type != type) {
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct device *dev = rsnd_priv_to_dev(priv);
dev_warn(dev, "%s[%d] is not your expected module\n",
rsnd_mod_name(mod), rsnd_mod_id(mod));
}
}
/* /*
* rsnd_mod functions * rsnd_mod functions
*/ */
......
...@@ -66,7 +66,7 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id) ...@@ -66,7 +66,7 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv))) if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
id = 0; id = 0;
return &((struct rsnd_ctu *)(priv->ctu) + id)->mod; return rsnd_mod_get((struct rsnd_ctu *)(priv->ctu) + id);
} }
static void rsnd_of_parse_ctu(struct platform_device *pdev, static void rsnd_of_parse_ctu(struct platform_device *pdev,
...@@ -150,7 +150,7 @@ int rsnd_ctu_probe(struct platform_device *pdev, ...@@ -150,7 +150,7 @@ int rsnd_ctu_probe(struct platform_device *pdev,
ctu->info = &info->ctu_info[i]; ctu->info = &info->ctu_info[i];
ret = rsnd_mod_init(priv, &ctu->mod, &rsnd_ctu_ops, ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
clk, RSND_MOD_CTU, i); clk, RSND_MOD_CTU, i);
if (ret) if (ret)
return ret; return ret;
...@@ -166,6 +166,6 @@ void rsnd_ctu_remove(struct platform_device *pdev, ...@@ -166,6 +166,6 @@ void rsnd_ctu_remove(struct platform_device *pdev,
int i; int i;
for_each_rsnd_ctu(ctu, priv, i) { for_each_rsnd_ctu(ctu, priv, i) {
rsnd_mod_quit(&ctu->mod); rsnd_mod_quit(rsnd_mod_get(ctu));
} }
} }
...@@ -282,7 +282,7 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) ...@@ -282,7 +282,7 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
id = 0; id = 0;
return &((struct rsnd_dvc *)(priv->dvc) + id)->mod; return rsnd_mod_get((struct rsnd_dvc *)(priv->dvc) + id);
} }
static void rsnd_of_parse_dvc(struct platform_device *pdev, static void rsnd_of_parse_dvc(struct platform_device *pdev,
...@@ -361,7 +361,7 @@ int rsnd_dvc_probe(struct platform_device *pdev, ...@@ -361,7 +361,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
dvc->info = &info->dvc_info[i]; dvc->info = &info->dvc_info[i];
ret = rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
clk, RSND_MOD_DVC, i); clk, RSND_MOD_DVC, i);
if (ret) if (ret)
return ret; return ret;
...@@ -377,6 +377,6 @@ void rsnd_dvc_remove(struct platform_device *pdev, ...@@ -377,6 +377,6 @@ void rsnd_dvc_remove(struct platform_device *pdev,
int i; int i;
for_each_rsnd_dvc(dvc, priv, i) { for_each_rsnd_dvc(dvc, priv, i) {
rsnd_mod_quit(&dvc->mod); rsnd_mod_quit(rsnd_mod_get(dvc));
} }
} }
...@@ -99,7 +99,7 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id) ...@@ -99,7 +99,7 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv))) if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
id = 0; id = 0;
return &((struct rsnd_mix *)(priv->mix) + id)->mod; return rsnd_mod_get((struct rsnd_mix *)(priv->mix) + id);
} }
static void rsnd_of_parse_mix(struct platform_device *pdev, static void rsnd_of_parse_mix(struct platform_device *pdev,
...@@ -179,7 +179,7 @@ int rsnd_mix_probe(struct platform_device *pdev, ...@@ -179,7 +179,7 @@ int rsnd_mix_probe(struct platform_device *pdev,
mix->info = &info->mix_info[i]; mix->info = &info->mix_info[i];
ret = rsnd_mod_init(priv, &mix->mod, &rsnd_mix_ops, ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
clk, RSND_MOD_MIX, i); clk, RSND_MOD_MIX, i);
if (ret) if (ret)
return ret; return ret;
...@@ -195,6 +195,6 @@ void rsnd_mix_remove(struct platform_device *pdev, ...@@ -195,6 +195,6 @@ void rsnd_mix_remove(struct platform_device *pdev,
int i; int i;
for_each_rsnd_mix(mix, priv, i) { for_each_rsnd_mix(mix, priv, i) {
rsnd_mod_quit(&mix->mod); rsnd_mod_quit(rsnd_mod_get(mix));
} }
} }
...@@ -214,6 +214,7 @@ struct rsnd_dma { ...@@ -214,6 +214,7 @@ struct rsnd_dma {
}; };
#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
...@@ -225,8 +226,6 @@ int rsnd_dma_probe(struct platform_device *pdev, ...@@ -225,8 +226,6 @@ int rsnd_dma_probe(struct platform_device *pdev,
struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
struct rsnd_mod *mod, char *name); struct rsnd_mod *mod, char *name);
#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
/* /*
* R-Car sound mod * R-Car sound mod
*/ */
...@@ -332,6 +331,7 @@ struct rsnd_mod { ...@@ -332,6 +331,7 @@ struct rsnd_mod {
#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1) #define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) #define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) #define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk)
#define rsnd_mod_get(ip) (&(ip)->mod)
int rsnd_mod_init(struct rsnd_priv *priv, int rsnd_mod_init(struct rsnd_priv *priv,
struct rsnd_mod *mod, struct rsnd_mod *mod,
...@@ -627,4 +627,15 @@ void rsnd_dvc_remove(struct platform_device *pdev, ...@@ -627,4 +627,15 @@ void rsnd_dvc_remove(struct platform_device *pdev,
struct rsnd_priv *priv); struct rsnd_priv *priv);
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
#ifdef DEBUG
void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI)
#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC)
#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC)
#else
#define rsnd_mod_confirm_ssi(mssi)
#define rsnd_mod_confirm_src(msrc)
#define rsnd_mod_confirm_dvc(mdvc)
#endif
#endif #endif
...@@ -918,11 +918,10 @@ static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io, ...@@ -918,11 +918,10 @@ static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
rsnd_mod_write(mod, SRC_IFSVR, fsrate); rsnd_mod_write(mod, SRC_IFSVR, fsrate);
} }
static int rsnd_src_pcm_new(struct rsnd_mod *mod, static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
struct snd_soc_pcm_runtime *rtd) struct snd_soc_pcm_runtime *rtd)
{ {
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
struct rsnd_src *src = rsnd_mod_to_src(mod); struct rsnd_src *src = rsnd_mod_to_src(mod);
int ret; int ret;
...@@ -931,12 +930,6 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod, ...@@ -931,12 +930,6 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
* enable SRC sync convert if possible * enable SRC sync convert if possible
*/ */
/*
* Gen1 is not supported
*/
if (rsnd_is_gen1(priv))
return 0;
/* /*
* SRC sync convert needs clock master * SRC sync convert needs clock master
*/ */
...@@ -975,7 +968,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = { ...@@ -975,7 +968,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = {
.start = rsnd_src_start_gen2, .start = rsnd_src_start_gen2,
.stop = rsnd_src_stop_gen2, .stop = rsnd_src_stop_gen2,
.hw_params = rsnd_src_hw_params, .hw_params = rsnd_src_hw_params,
.pcm_new = rsnd_src_pcm_new, .pcm_new = rsnd_src_pcm_new_gen2,
}; };
struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
...@@ -983,7 +976,7 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) ...@@ -983,7 +976,7 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
id = 0; id = 0;
return &((struct rsnd_src *)(priv->src) + id)->mod; return rsnd_mod_get((struct rsnd_src *)(priv->src) + id);
} }
static void rsnd_of_parse_src(struct platform_device *pdev, static void rsnd_of_parse_src(struct platform_device *pdev,
...@@ -1078,7 +1071,7 @@ int rsnd_src_probe(struct platform_device *pdev, ...@@ -1078,7 +1071,7 @@ int rsnd_src_probe(struct platform_device *pdev,
src->info = &info->src_info[i]; src->info = &info->src_info[i];
ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i); ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -1093,6 +1086,6 @@ void rsnd_src_remove(struct platform_device *pdev, ...@@ -1093,6 +1086,6 @@ void rsnd_src_remove(struct platform_device *pdev,
int i; int i;
for_each_rsnd_src(src, priv, i) { for_each_rsnd_src(src, priv, i) {
rsnd_mod_quit(&src->mod); rsnd_mod_quit(rsnd_mod_get(src));
} }
} }
...@@ -128,10 +128,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, ...@@ -128,10 +128,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
struct rsnd_priv *priv = rsnd_io_to_priv(io); struct rsnd_priv *priv = rsnd_io_to_priv(io);
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
int i, j, ret; struct rsnd_mod *mod = rsnd_mod_get(ssi);
int adg_clk_div_table[] = { int j, ret;
1, 6, /* see adg.c */
};
int ssi_clk_mul_table[] = { int ssi_clk_mul_table[] = {
1, 2, 4, 8, 16, 6, 12, 1, 2, 4, 8, 16, 6, 12,
}; };
...@@ -141,28 +139,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, ...@@ -141,28 +139,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
/* /*
* Find best clock, and try to start ADG * Find best clock, and try to start ADG
*/ */
for (i = 0; i < ARRAY_SIZE(adg_clk_div_table); i++) { for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
/*
/* * this driver is assuming that
* this driver is assuming that * system word is 64fs (= 2 x 32bit)
* system word is 64fs (= 2 x 32bit) * see rsnd_ssi_init()
* see rsnd_ssi_init() */
*/ main_rate = rate * 32 * 2 * ssi_clk_mul_table[j];
main_rate = rate / adg_clk_div_table[i]
* 32 * 2 * ssi_clk_mul_table[j]; ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
if (0 == ret) {
ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); ssi->cr_clk = FORCE | SWL_32 |
if (0 == ret) { SCKD | SWSD | CKDV(j);
ssi->cr_clk = FORCE | SWL_32 |
SCKD | SWSD | CKDV(j); dev_dbg(dev, "%s[%d] outputs %u Hz\n",
rsnd_mod_name(mod),
dev_dbg(dev, "%s[%d] outputs %u Hz\n", rsnd_mod_id(mod), rate);
rsnd_mod_name(&ssi->mod),
rsnd_mod_id(&ssi->mod), rate); return 0;
return 0;
}
} }
} }
...@@ -172,8 +167,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, ...@@ -172,8 +167,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi)
{ {
struct rsnd_mod *mod = rsnd_mod_get(ssi);
ssi->cr_clk = 0; ssi->cr_clk = 0;
rsnd_adg_ssi_clk_stop(&ssi->mod); rsnd_adg_ssi_clk_stop(mod);
} }
static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
...@@ -182,11 +179,12 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, ...@@ -182,11 +179,12 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
struct rsnd_priv *priv = rsnd_io_to_priv(io); struct rsnd_priv *priv = rsnd_io_to_priv(io);
struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct rsnd_mod *mod = rsnd_mod_get(ssi);
u32 cr_mode; u32 cr_mode;
u32 cr; u32 cr;
if (0 == ssi->usrcnt) { if (0 == ssi->usrcnt) {
rsnd_mod_hw_start(&ssi->mod); rsnd_mod_hw_start(mod);
if (rsnd_rdai_is_clk_master(rdai)) { if (rsnd_rdai_is_clk_master(rdai)) {
struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
...@@ -198,7 +196,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, ...@@ -198,7 +196,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
} }
} }
if (rsnd_ssi_is_dma_mode(&ssi->mod)) { if (rsnd_ssi_is_dma_mode(mod)) {
cr_mode = UIEN | OIEN | /* over/under run */ cr_mode = UIEN | OIEN | /* over/under run */
DMEN; /* DMA : enable DMA */ DMEN; /* DMA : enable DMA */
} else { } else {
...@@ -210,24 +208,25 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, ...@@ -210,24 +208,25 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
cr_mode | cr_mode |
EN; EN;
rsnd_mod_write(&ssi->mod, SSICR, cr); rsnd_mod_write(mod, SSICR, cr);
/* enable WS continue */ /* enable WS continue */
if (rsnd_rdai_is_clk_master(rdai)) if (rsnd_rdai_is_clk_master(rdai))
rsnd_mod_write(&ssi->mod, SSIWSR, CONT); rsnd_mod_write(mod, SSIWSR, CONT);
/* clear error status */ /* clear error status */
rsnd_mod_write(&ssi->mod, SSISR, 0); rsnd_mod_write(mod, SSISR, 0);
ssi->usrcnt++; ssi->usrcnt++;
dev_dbg(dev, "%s[%d] hw started\n", dev_dbg(dev, "%s[%d] hw started\n",
rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); rsnd_mod_name(mod), rsnd_mod_id(mod));
} }
static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
{ {
struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); struct rsnd_mod *mod = rsnd_mod_get(ssi);
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
u32 cr; u32 cr;
...@@ -247,15 +246,15 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) ...@@ -247,15 +246,15 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
cr = ssi->cr_own | cr = ssi->cr_own |
ssi->cr_clk; ssi->cr_clk;
rsnd_mod_write(&ssi->mod, SSICR, cr | EN); rsnd_mod_write(mod, SSICR, cr | EN);
rsnd_ssi_status_check(&ssi->mod, DIRQ); rsnd_ssi_status_check(mod, DIRQ);
/* /*
* disable SSI, * disable SSI,
* and, wait idle state * and, wait idle state
*/ */
rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ rsnd_mod_write(mod, SSICR, cr); /* disabled all */
rsnd_ssi_status_check(&ssi->mod, IIRQ); rsnd_ssi_status_check(mod, IIRQ);
if (rsnd_rdai_is_clk_master(rdai)) { if (rsnd_rdai_is_clk_master(rdai)) {
struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
...@@ -266,13 +265,13 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) ...@@ -266,13 +265,13 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
rsnd_ssi_master_clk_stop(ssi); rsnd_ssi_master_clk_stop(ssi);
} }
rsnd_mod_hw_stop(&ssi->mod); rsnd_mod_hw_stop(mod);
ssi->chan = 0; ssi->chan = 0;
} }
dev_dbg(dev, "%s[%d] hw stopped\n", dev_dbg(dev, "%s[%d] hw stopped\n",
rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); rsnd_mod_name(mod), rsnd_mod_id(mod));
} }
/* /*
...@@ -371,7 +370,7 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod, ...@@ -371,7 +370,7 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
/* It will be removed on rsnd_ssi_hw_stop */ /* It will be removed on rsnd_ssi_hw_stop */
ssi->chan = chan; ssi->chan = chan;
if (ssi_parent) if (ssi_parent)
return rsnd_ssi_hw_params(&ssi_parent->mod, io, return rsnd_ssi_hw_params(rsnd_mod_get(ssi_parent), io,
substream, params); substream, params);
return 0; return 0;
...@@ -379,12 +378,14 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod, ...@@ -379,12 +378,14 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
{ {
struct rsnd_mod *mod = rsnd_mod_get(ssi);
/* under/over flow error */ /* under/over flow error */
if (status & (UIRQ | OIRQ)) { if (status & (UIRQ | OIRQ)) {
ssi->err++; ssi->err++;
/* clear error status */ /* clear error status */
rsnd_mod_write(&ssi->mod, SSISR, 0); rsnd_mod_write(mod, SSISR, 0);
} }
} }
...@@ -656,7 +657,7 @@ struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) ...@@ -656,7 +657,7 @@ struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
id = 0; id = 0;
return &((struct rsnd_ssi *)(priv->ssi) + id)->mod; return rsnd_mod_get((struct rsnd_ssi *)(priv->ssi) + id);
} }
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
...@@ -668,10 +669,12 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) ...@@ -668,10 +669,12 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
{ {
if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) struct rsnd_mod *mod = rsnd_mod_get(ssi);
if (!rsnd_ssi_is_pin_sharing(mod))
return; return;
switch (rsnd_mod_id(&ssi->mod)) { switch (rsnd_mod_id(mod)) {
case 1: case 1:
case 2: case 2:
ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0)); ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0));
...@@ -794,7 +797,8 @@ int rsnd_ssi_probe(struct platform_device *pdev, ...@@ -794,7 +797,8 @@ int rsnd_ssi_probe(struct platform_device *pdev,
else if (rsnd_ssi_pio_available(ssi)) else if (rsnd_ssi_pio_available(ssi))
ops = &rsnd_ssi_pio_ops; ops = &rsnd_ssi_pio_ops;
ret = rsnd_mod_init(priv, &ssi->mod, ops, clk, RSND_MOD_SSI, i); ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
RSND_MOD_SSI, i);
if (ret) if (ret)
return ret; return ret;
...@@ -811,6 +815,6 @@ void rsnd_ssi_remove(struct platform_device *pdev, ...@@ -811,6 +815,6 @@ void rsnd_ssi_remove(struct platform_device *pdev,
int i; int i;
for_each_rsnd_ssi(ssi, priv, i) { for_each_rsnd_ssi(ssi, priv, i) {
rsnd_mod_quit(&ssi->mod); rsnd_mod_quit(rsnd_mod_get(ssi));
} }
} }
...@@ -738,7 +738,7 @@ static int siu_probe(struct platform_device *pdev) ...@@ -738,7 +738,7 @@ static int siu_probe(struct platform_device *pdev)
struct siu_info *info; struct siu_info *info;
int ret; int ret;
info = kmalloc(sizeof(*info), GFP_KERNEL); info = devm_kmalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
siu_i2s_data = info; siu_i2s_data = info;
...@@ -746,7 +746,7 @@ static int siu_probe(struct platform_device *pdev) ...@@ -746,7 +746,7 @@ static int siu_probe(struct platform_device *pdev)
ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev); ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
if (ret) if (ret)
goto ereqfw; return ret;
/* /*
* Loaded firmware is "const" - read only, but we have to modify it in * Loaded firmware is "const" - read only, but we have to modify it in
...@@ -757,89 +757,52 @@ static int siu_probe(struct platform_device *pdev) ...@@ -757,89 +757,52 @@ static int siu_probe(struct platform_device *pdev)
release_firmware(fw_entry); release_firmware(fw_entry);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { if (!res)
ret = -ENODEV; return -ENODEV;
goto egetres;
}
region = request_mem_region(res->start, resource_size(res), region = devm_request_mem_region(&pdev->dev, res->start,
pdev->name); resource_size(res), pdev->name);
if (!region) { if (!region) {
dev_err(&pdev->dev, "SIU region already claimed\n"); dev_err(&pdev->dev, "SIU region already claimed\n");
ret = -EBUSY; return -EBUSY;
goto ereqmemreg;
} }
ret = -ENOMEM; info->pram = devm_ioremap(&pdev->dev, res->start, PRAM_SIZE);
info->pram = ioremap(res->start, PRAM_SIZE);
if (!info->pram) if (!info->pram)
goto emappram; return -ENOMEM;
info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE); info->xram = devm_ioremap(&pdev->dev, res->start + XRAM_OFFSET,
XRAM_SIZE);
if (!info->xram) if (!info->xram)
goto emapxram; return -ENOMEM;
info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE); info->yram = devm_ioremap(&pdev->dev, res->start + YRAM_OFFSET,
YRAM_SIZE);
if (!info->yram) if (!info->yram)
goto emapyram; return -ENOMEM;
info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) - info->reg = devm_ioremap(&pdev->dev, res->start + REG_OFFSET,
REG_OFFSET); resource_size(res) - REG_OFFSET);
if (!info->reg) if (!info->reg)
goto emapreg; return -ENOMEM;
dev_set_drvdata(&pdev->dev, info); dev_set_drvdata(&pdev->dev, info);
/* register using ARRAY version so we can keep dai name */ /* register using ARRAY version so we can keep dai name */
ret = snd_soc_register_component(&pdev->dev, &siu_i2s_component, ret = devm_snd_soc_register_component(&pdev->dev, &siu_i2s_component,
&siu_i2s_dai, 1); &siu_i2s_dai, 1);
if (ret < 0) if (ret < 0)
goto edaiinit; return ret;
ret = snd_soc_register_platform(&pdev->dev, &siu_platform); ret = devm_snd_soc_register_platform(&pdev->dev, &siu_platform);
if (ret < 0) if (ret < 0)
goto esocregp; return ret;
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
return ret; return 0;
esocregp:
snd_soc_unregister_component(&pdev->dev);
edaiinit:
iounmap(info->reg);
emapreg:
iounmap(info->yram);
emapyram:
iounmap(info->xram);
emapxram:
iounmap(info->pram);
emappram:
release_mem_region(res->start, resource_size(res));
ereqmemreg:
egetres:
ereqfw:
kfree(info);
return ret;
} }
static int siu_remove(struct platform_device *pdev) static int siu_remove(struct platform_device *pdev)
{ {
struct siu_info *info = dev_get_drvdata(&pdev->dev);
struct resource *res;
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
snd_soc_unregister_platform(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
iounmap(info->reg);
iounmap(info->yram);
iounmap(info->xram);
iounmap(info->pram);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
release_mem_region(res->start, resource_size(res));
kfree(info);
return 0; return 0;
} }
......
...@@ -3291,13 +3291,38 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, ...@@ -3291,13 +3291,38 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
} }
EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets); EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
static int snd_soc_of_get_slot_mask(struct device_node *np,
const char *prop_name,
unsigned int *mask)
{
u32 val;
const __be32 *of_slot_mask = of_get_property(np, prop_name, &val);
int i;
if (!of_slot_mask)
return 0;
val /= sizeof(u32);
for (i = 0; i < val; i++)
if (be32_to_cpup(&of_slot_mask[i]))
*mask |= (1 << i);
return val;
}
int snd_soc_of_parse_tdm_slot(struct device_node *np, int snd_soc_of_parse_tdm_slot(struct device_node *np,
unsigned int *tx_mask,
unsigned int *rx_mask,
unsigned int *slots, unsigned int *slots,
unsigned int *slot_width) unsigned int *slot_width)
{ {
u32 val; u32 val;
int ret; int ret;
if (tx_mask)
snd_soc_of_get_slot_mask(np, "dai-tdm-slot-tx-mask", tx_mask);
if (rx_mask)
snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask);
if (of_property_read_bool(np, "dai-tdm-slot-num")) { if (of_property_read_bool(np, "dai-tdm-slot-num")) {
ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
if (ret) if (ret)
......
...@@ -34,6 +34,24 @@ ...@@ -34,6 +34,24 @@
#define DPCM_MAX_BE_USERS 8 #define DPCM_MAX_BE_USERS 8
/*
* snd_soc_dai_stream_valid() - check if a DAI supports the given stream
*
* Returns true if the DAI supports the indicated stream type.
*/
static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
{
struct snd_soc_pcm_stream *codec_stream;
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
codec_stream = &dai->driver->playback;
else
codec_stream = &dai->driver->capture;
/* If the codec specifies any rate at all, it supports the stream. */
return codec_stream->rates;
}
/** /**
* snd_soc_runtime_activate() - Increment active count for PCM runtime components * snd_soc_runtime_activate() - Increment active count for PCM runtime components
* @rtd: ASoC PCM runtime that is activated * @rtd: ASoC PCM runtime that is activated
...@@ -371,6 +389,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream) ...@@ -371,6 +389,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
/* first calculate min/max only for CODECs in the DAI link */ /* first calculate min/max only for CODECs in the DAI link */
for (i = 0; i < rtd->num_codecs; i++) { for (i = 0; i < rtd->num_codecs; i++) {
/*
* Skip CODECs which don't support the current stream type.
* Otherwise, since the rate, channel, and format values will
* zero in that case, we would have no usable settings left,
* causing the resulting setup to fail.
* At least one CODEC should match, otherwise we should have
* bailed out on a higher level, since there would be no
* CODEC to support the transfer direction in that case.
*/
if (!snd_soc_dai_stream_valid(rtd->codec_dais[i],
substream->stream))
continue;
codec_dai_drv = rtd->codec_dais[i]->driver; codec_dai_drv = rtd->codec_dais[i]->driver;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
codec_stream = &codec_dai_drv->playback; codec_stream = &codec_dai_drv->playback;
...@@ -827,6 +859,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -827,6 +859,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
struct snd_pcm_hw_params codec_params; struct snd_pcm_hw_params codec_params;
/*
* Skip CODECs which don't support the current stream type,
* the idea being that if a CODEC is not used for the currently
* set up transfer direction, it should not need to be
* configured, especially since the configuration used might
* not even be supported by that CODEC. There may be cases
* however where a CODEC needs to be set up although it is
* actually not being used for the transfer, e.g. if a
* capture-only CODEC is acting as an LRCLK and/or BCLK master
* for the DAI link including a playback-only CODEC.
* If this becomes necessary, we will have to augment the
* machine driver setup with information on how to act, so
* we can do the right thing here.
*/
if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
continue;
/* copy params for each codec */ /* copy params for each codec */
codec_params = *params; codec_params = *params;
......
menu "Allwinner SoC Audio support"
config SND_SUN4I_CODEC
tristate "Allwinner A10 Codec Support"
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
help
Select Y or M to add support for the Codec embedded in the Allwinner
A10 and affiliated SoCs.
endmenu
obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
This diff is collapsed.
...@@ -152,6 +152,7 @@ static const struct of_device_id snd_soc_mop500_match[] = { ...@@ -152,6 +152,7 @@ static const struct of_device_id snd_soc_mop500_match[] = {
{ .compatible = "stericsson,snd-soc-mop500", }, { .compatible = "stericsson,snd-soc-mop500", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, snd_soc_mop500_match);
static struct platform_driver snd_soc_mop500_driver = { static struct platform_driver snd_soc_mop500_driver = {
.driver = { .driver = {
......
...@@ -843,6 +843,7 @@ static const struct of_device_id ux500_msp_i2s_match[] = { ...@@ -843,6 +843,7 @@ static const struct of_device_id ux500_msp_i2s_match[] = {
{ .compatible = "stericsson,ux500-msp-i2s", }, { .compatible = "stericsson,ux500-msp-i2s", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, ux500_msp_i2s_match);
static struct platform_driver msp_i2s_driver = { static struct platform_driver msp_i2s_driver = {
.driver = { .driver = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment