Merge remote-tracking branches 'asoc/topic/nuc900', 'asoc/topic/omap', 'asoc/topic/pxa', 'asoc/topic/rcar', 'asoc/topic/rt5640' and 'asoc/topic/rt5645' into asoc-next
This commit is contained in:
commit
6f821c6449
|
@ -0,0 +1,27 @@
|
|||
* Nokia N900 audio setup
|
||||
|
||||
Required properties:
|
||||
- compatible: Should contain "nokia,n900-audio"
|
||||
- nokia,cpu-dai: phandle for the McBSP node
|
||||
- nokia,audio-codec: phandles for the main TLV320AIC3X node and the
|
||||
auxiliary TLV320AIC3X node (in this order)
|
||||
- nokia,headphone-amplifier: phandle for the TPA6130A2 node
|
||||
- tvout-selection-gpios: GPIO for tvout selection
|
||||
- jack-detection-gpios: GPIO for jack detection
|
||||
- eci-switch-gpios: GPIO for ECI (Enhancement Control Interface) switch
|
||||
- speaker-amplifier-gpios: GPIO for speaker amplifier
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "nokia,n900-audio";
|
||||
|
||||
nokia,cpu-dai = <&mcbsp2>;
|
||||
nokia,audio-codec = <&tlv320aic3x>, <&tlv320aic3x_aux>;
|
||||
nokia,headphone-amplifier = <&tpa6130a2>;
|
||||
|
||||
tvout-selection-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */
|
||||
jack-detection-gpios = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */
|
||||
eci-switch-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */
|
||||
speaker-amplifier-gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>;
|
||||
};
|
|
@ -1,10 +1,10 @@
|
|||
RT5640 audio CODEC
|
||||
RT5640/RT5639 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "realtek,rt5640".
|
||||
- compatible : One of "realtek,rt5640" or "realtek,rt5639".
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
|
@ -18,7 +18,7 @@ Optional properties:
|
|||
|
||||
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
|
||||
Pins on the device (for linking into audio routes):
|
||||
Pins on the device (for linking into audio routes) for RT5639/RT5640:
|
||||
|
||||
* DMIC1
|
||||
* DMIC2
|
||||
|
@ -31,13 +31,16 @@ Pins on the device (for linking into audio routes):
|
|||
* HPOR
|
||||
* LOUTL
|
||||
* LOUTR
|
||||
* MONOP
|
||||
* MONON
|
||||
* SPOLP
|
||||
* SPOLN
|
||||
* SPORP
|
||||
* SPORN
|
||||
|
||||
Additional pins on the device for RT5640:
|
||||
|
||||
* MONOP
|
||||
* MONON
|
||||
|
||||
Example:
|
||||
|
||||
rt5640 {
|
||||
|
|
|
@ -673,7 +673,7 @@
|
|||
renesas,clock-indices = <
|
||||
R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2
|
||||
R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1
|
||||
R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_RT R8A7790_CLK_VSP1_SY
|
||||
R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_R R8A7790_CLK_VSP1_S
|
||||
>;
|
||||
clock-output-names =
|
||||
"tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
|
||||
|
|
|
@ -688,7 +688,7 @@
|
|||
renesas,clock-indices = <
|
||||
R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2
|
||||
R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1
|
||||
R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_SY
|
||||
R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_S
|
||||
>;
|
||||
clock-output-names =
|
||||
"tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
|
||||
|
|
|
@ -21,8 +21,8 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o
|
|||
obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o
|
||||
|
||||
# Clock objects
|
||||
ifndef CONFIG_COMMON_CLK
|
||||
obj-y += clock.o
|
||||
ifndef CONFIG_COMMON_CLK
|
||||
obj-$(CONFIG_ARCH_SH7372) += clock-sh7372.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += clock-sh73a0.o
|
||||
obj-$(CONFIG_ARCH_R8A73A4) += clock-r8a73a4.o
|
||||
|
|
|
@ -345,24 +345,39 @@ static struct rsnd_ssi_platform_info rsnd_ssi[] = {
|
|||
RSND_SSI_UNUSED, /* SSI 0 */
|
||||
RSND_SSI_UNUSED, /* SSI 1 */
|
||||
RSND_SSI_UNUSED, /* SSI 2 */
|
||||
RSND_SSI_SET(1, HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), RSND_SSI_PLAY),
|
||||
RSND_SSI_SET(2, HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE),
|
||||
RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), RSND_SSI_PLAY),
|
||||
RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0),
|
||||
RSND_SSI_SET(3, HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), RSND_SSI_PLAY),
|
||||
RSND_SSI_SET(4, HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE),
|
||||
RSND_SSI(HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), 0),
|
||||
RSND_SSI(HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE),
|
||||
RSND_SSI(HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), 0),
|
||||
RSND_SSI(HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0),
|
||||
RSND_SSI(HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), 0),
|
||||
RSND_SSI(HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE),
|
||||
};
|
||||
|
||||
static struct rsnd_scu_platform_info rsnd_scu[9] = {
|
||||
{ .flags = 0, }, /* SRU 0 */
|
||||
{ .flags = 0, }, /* SRU 1 */
|
||||
{ .flags = 0, }, /* SRU 2 */
|
||||
{ .flags = RSND_SCU_USE_HPBIF, },
|
||||
{ .flags = RSND_SCU_USE_HPBIF, },
|
||||
{ .flags = RSND_SCU_USE_HPBIF, },
|
||||
{ .flags = RSND_SCU_USE_HPBIF, },
|
||||
{ .flags = RSND_SCU_USE_HPBIF, },
|
||||
{ .flags = RSND_SCU_USE_HPBIF, },
|
||||
static struct rsnd_src_platform_info rsnd_src[9] = {
|
||||
RSND_SRC_UNUSED, /* SRU 0 */
|
||||
RSND_SRC_UNUSED, /* SRU 1 */
|
||||
RSND_SRC_UNUSED, /* SRU 2 */
|
||||
RSND_SRC(0, 0),
|
||||
RSND_SRC(0, 0),
|
||||
RSND_SRC(0, 0),
|
||||
RSND_SRC(0, 0),
|
||||
RSND_SRC(0, 0),
|
||||
RSND_SRC(0, 0),
|
||||
};
|
||||
|
||||
static struct rsnd_dai_platform_info rsnd_dai[] = {
|
||||
{
|
||||
.playback = { .ssi = &rsnd_ssi[5], .src = &rsnd_src[5] },
|
||||
.capture = { .ssi = &rsnd_ssi[6], .src = &rsnd_src[6] },
|
||||
}, {
|
||||
.playback = { .ssi = &rsnd_ssi[3], .src = &rsnd_src[3] },
|
||||
}, {
|
||||
.capture = { .ssi = &rsnd_ssi[4], .src = &rsnd_src[4] },
|
||||
}, {
|
||||
.playback = { .ssi = &rsnd_ssi[7], .src = &rsnd_src[7] },
|
||||
}, {
|
||||
.capture = { .ssi = &rsnd_ssi[8], .src = &rsnd_src[8] },
|
||||
},
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -437,8 +452,10 @@ static struct rcar_snd_info rsnd_info = {
|
|||
.flags = RSND_GEN1,
|
||||
.ssi_info = rsnd_ssi,
|
||||
.ssi_info_nr = ARRAY_SIZE(rsnd_ssi),
|
||||
.scu_info = rsnd_scu,
|
||||
.scu_info_nr = ARRAY_SIZE(rsnd_scu),
|
||||
.src_info = rsnd_src,
|
||||
.src_info_nr = ARRAY_SIZE(rsnd_src),
|
||||
.dai_info = rsnd_dai,
|
||||
.dai_info_nr = ARRAY_SIZE(rsnd_dai),
|
||||
.start = rsnd_start,
|
||||
.stop = rsnd_stop,
|
||||
};
|
||||
|
@ -591,6 +608,7 @@ static void __init bockw_init(void)
|
|||
{
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
struct platform_device *pdev;
|
||||
int i;
|
||||
|
||||
r8a7778_clock_init();
|
||||
|
@ -673,9 +691,6 @@ static void __init bockw_init(void)
|
|||
}
|
||||
|
||||
/* for Audio */
|
||||
clk = clk_get(NULL, "audio_clk_b");
|
||||
clk_set_rate(clk, 24576000);
|
||||
clk_put(clk);
|
||||
rsnd_codec_power(5, 1); /* enable ak4642 */
|
||||
|
||||
platform_device_register_simple(
|
||||
|
@ -684,11 +699,15 @@ static void __init bockw_init(void)
|
|||
platform_device_register_simple(
|
||||
"ak4554-adc-dac", 1, NULL, 0);
|
||||
|
||||
platform_device_register_resndata(
|
||||
pdev = platform_device_register_resndata(
|
||||
&platform_bus, "rcar_sound", -1,
|
||||
rsnd_resources, ARRAY_SIZE(rsnd_resources),
|
||||
&rsnd_info, sizeof(rsnd_info));
|
||||
|
||||
clk = clk_get(&pdev->dev, "clk_b");
|
||||
clk_set_rate(clk, 24576000);
|
||||
clk_put(clk);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) {
|
||||
struct platform_device_info cardinfo = {
|
||||
.parent = &platform_bus,
|
||||
|
|
|
@ -19,12 +19,11 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_data/rcar-du.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/rcar-gen2.h>
|
||||
|
@ -82,49 +81,50 @@ static void __init koelsch_add_du_device(void)
|
|||
platform_device_register_full(&info);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a really crude hack to provide clkdev support to platform
|
||||
* devices until they get moved to DT.
|
||||
*/
|
||||
static const struct clk_name clk_names[] __initconst = {
|
||||
{ "cmt0", NULL, "sh_cmt.0" },
|
||||
{ "scifa0", NULL, "sh-sci.0" },
|
||||
{ "scifa1", NULL, "sh-sci.1" },
|
||||
{ "scifb0", NULL, "sh-sci.2" },
|
||||
{ "scifb1", NULL, "sh-sci.3" },
|
||||
{ "scifb2", NULL, "sh-sci.4" },
|
||||
{ "scifa2", NULL, "sh-sci.5" },
|
||||
{ "scif0", NULL, "sh-sci.6" },
|
||||
{ "scif1", NULL, "sh-sci.7" },
|
||||
{ "scif2", NULL, "sh-sci.8" },
|
||||
{ "scif3", NULL, "sh-sci.9" },
|
||||
{ "scif4", NULL, "sh-sci.10" },
|
||||
{ "scif5", NULL, "sh-sci.11" },
|
||||
{ "scifa3", NULL, "sh-sci.12" },
|
||||
{ "scifa4", NULL, "sh-sci.13" },
|
||||
{ "scifa5", NULL, "sh-sci.14" },
|
||||
{ "du0", "du.0", "rcar-du-r8a7791" },
|
||||
{ "du1", "du.1", "rcar-du-r8a7791" },
|
||||
{ "lvds0", "lvds.0", "rcar-du-r8a7791" },
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a really crude hack to work around core platform clock issues
|
||||
*/
|
||||
static const struct clk_name clk_enables[] __initconst = {
|
||||
{ "ether", NULL, "ee700000.ethernet" },
|
||||
{ "i2c2", NULL, "e6530000.i2c" },
|
||||
{ "msiof0", NULL, "e6e20000.spi" },
|
||||
{ "qspi_mod", NULL, "e6b10000.spi" },
|
||||
{ "sdhi0", NULL, "ee100000.sd" },
|
||||
{ "sdhi1", NULL, "ee140000.sd" },
|
||||
{ "sdhi2", NULL, "ee160000.sd" },
|
||||
{ "thermal", NULL, "e61f0000.thermal" },
|
||||
};
|
||||
|
||||
static void __init koelsch_add_standard_devices(void)
|
||||
{
|
||||
/*
|
||||
* This is a really crude hack to provide clkdev support to the CMT and
|
||||
* DU devices until they get moved to DT.
|
||||
*/
|
||||
static const struct clk_name {
|
||||
const char *clk;
|
||||
const char *con_id;
|
||||
const char *dev_id;
|
||||
} clk_names[] = {
|
||||
{ "cmt0", NULL, "sh_cmt.0" },
|
||||
{ "scifa0", NULL, "sh-sci.0" },
|
||||
{ "scifa1", NULL, "sh-sci.1" },
|
||||
{ "scifb0", NULL, "sh-sci.2" },
|
||||
{ "scifb1", NULL, "sh-sci.3" },
|
||||
{ "scifb2", NULL, "sh-sci.4" },
|
||||
{ "scifa2", NULL, "sh-sci.5" },
|
||||
{ "scif0", NULL, "sh-sci.6" },
|
||||
{ "scif1", NULL, "sh-sci.7" },
|
||||
{ "scif2", NULL, "sh-sci.8" },
|
||||
{ "scif3", NULL, "sh-sci.9" },
|
||||
{ "scif4", NULL, "sh-sci.10" },
|
||||
{ "scif5", NULL, "sh-sci.11" },
|
||||
{ "scifa3", NULL, "sh-sci.12" },
|
||||
{ "scifa4", NULL, "sh-sci.13" },
|
||||
{ "scifa5", NULL, "sh-sci.14" },
|
||||
{ "du0", "du.0", "rcar-du-r8a7791" },
|
||||
{ "du1", "du.1", "rcar-du-r8a7791" },
|
||||
{ "lvds0", "lvds.0", "rcar-du-r8a7791" },
|
||||
};
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk_names); ++i) {
|
||||
clk = clk_get(NULL, clk_names[i].clk);
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_register_clkdev(clk, clk_names[i].con_id,
|
||||
clk_names[i].dev_id);
|
||||
clk_put(clk);
|
||||
}
|
||||
}
|
||||
|
||||
shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false);
|
||||
shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true);
|
||||
r8a7791_add_dt_devices();
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ static const struct spi_board_info spi_info[] __initconst = {
|
|||
{
|
||||
.modalias = "m25p80",
|
||||
.platform_data = &spi_flash_data,
|
||||
.mode = SPI_MODE_0,
|
||||
.mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD,
|
||||
.max_speed_hz = 30000000,
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
|
|
|
@ -18,12 +18,11 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_data/rcar-du.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/rcar-gen2.h>
|
||||
|
@ -86,46 +85,46 @@ static void __init lager_add_du_device(void)
|
|||
platform_device_register_full(&info);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a really crude hack to provide clkdev support to platform
|
||||
* devices until they get moved to DT.
|
||||
*/
|
||||
static const struct clk_name clk_names[] __initconst = {
|
||||
{ "cmt0", NULL, "sh_cmt.0" },
|
||||
{ "scifa0", NULL, "sh-sci.0" },
|
||||
{ "scifa1", NULL, "sh-sci.1" },
|
||||
{ "scifb0", NULL, "sh-sci.2" },
|
||||
{ "scifb1", NULL, "sh-sci.3" },
|
||||
{ "scifb2", NULL, "sh-sci.4" },
|
||||
{ "scifa2", NULL, "sh-sci.5" },
|
||||
{ "scif0", NULL, "sh-sci.6" },
|
||||
{ "scif1", NULL, "sh-sci.7" },
|
||||
{ "hscif0", NULL, "sh-sci.8" },
|
||||
{ "hscif1", NULL, "sh-sci.9" },
|
||||
{ "du0", "du.0", "rcar-du-r8a7790" },
|
||||
{ "du1", "du.1", "rcar-du-r8a7790" },
|
||||
{ "du2", "du.2", "rcar-du-r8a7790" },
|
||||
{ "lvds0", "lvds.0", "rcar-du-r8a7790" },
|
||||
{ "lvds1", "lvds.1", "rcar-du-r8a7790" },
|
||||
};
|
||||
|
||||
/*
|
||||
* This is a really crude hack to work around core platform clock issues
|
||||
*/
|
||||
static const struct clk_name clk_enables[] __initconst = {
|
||||
{ "ether", NULL, "ee700000.ethernet" },
|
||||
{ "msiof1", NULL, "e6e10000.spi" },
|
||||
{ "mmcif1", NULL, "ee220000.mmc" },
|
||||
{ "qspi_mod", NULL, "e6b10000.spi" },
|
||||
{ "sdhi0", NULL, "ee100000.sd" },
|
||||
{ "sdhi2", NULL, "ee140000.sd" },
|
||||
{ "thermal", NULL, "e61f0000.thermal" },
|
||||
};
|
||||
|
||||
static void __init lager_add_standard_devices(void)
|
||||
{
|
||||
/*
|
||||
* This is a really crude hack to provide clkdev support to platform
|
||||
* devices until they get moved to DT.
|
||||
*/
|
||||
static const struct clk_name {
|
||||
const char *clk;
|
||||
const char *con_id;
|
||||
const char *dev_id;
|
||||
} clk_names[] = {
|
||||
{ "cmt0", NULL, "sh_cmt.0" },
|
||||
{ "scifa0", NULL, "sh-sci.0" },
|
||||
{ "scifa1", NULL, "sh-sci.1" },
|
||||
{ "scifb0", NULL, "sh-sci.2" },
|
||||
{ "scifb1", NULL, "sh-sci.3" },
|
||||
{ "scifb2", NULL, "sh-sci.4" },
|
||||
{ "scifa2", NULL, "sh-sci.5" },
|
||||
{ "scif0", NULL, "sh-sci.6" },
|
||||
{ "scif1", NULL, "sh-sci.7" },
|
||||
{ "hscif0", NULL, "sh-sci.8" },
|
||||
{ "hscif1", NULL, "sh-sci.9" },
|
||||
{ "du0", "du.0", "rcar-du-r8a7790" },
|
||||
{ "du1", "du.1", "rcar-du-r8a7790" },
|
||||
{ "du2", "du.2", "rcar-du-r8a7790" },
|
||||
{ "lvds0", "lvds.0", "rcar-du-r8a7790" },
|
||||
{ "lvds1", "lvds.1", "rcar-du-r8a7790" },
|
||||
};
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk_names); ++i) {
|
||||
clk = clk_get(NULL, clk_names[i].clk);
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_register_clkdev(clk, clk_names[i].con_id,
|
||||
clk_names[i].dev_id);
|
||||
clk_put(clk);
|
||||
}
|
||||
}
|
||||
|
||||
shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false);
|
||||
shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true);
|
||||
r8a7790_add_dt_devices();
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
|
|
|
@ -325,12 +325,12 @@ static const struct rspi_plat_data qspi_pdata __initconst = {
|
|||
|
||||
static const struct spi_board_info spi_info[] __initconst = {
|
||||
{
|
||||
.modalias = "m25p80",
|
||||
.platform_data = &spi_flash_data,
|
||||
.mode = SPI_MODE_0,
|
||||
.max_speed_hz = 30000000,
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
.modalias = "m25p80",
|
||||
.platform_data = &spi_flash_data,
|
||||
.mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD,
|
||||
.max_speed_hz = 30000000,
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -567,20 +567,27 @@ static struct resource rsnd_resources[] __initdata = {
|
|||
};
|
||||
|
||||
static struct rsnd_ssi_platform_info rsnd_ssi[] = {
|
||||
RSND_SSI_SET(0, 0, gic_spi(370), RSND_SSI_PLAY),
|
||||
RSND_SSI_SET(0, 0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE),
|
||||
RSND_SSI(0, gic_spi(370), 0),
|
||||
RSND_SSI(0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE),
|
||||
};
|
||||
|
||||
static struct rsnd_scu_platform_info rsnd_scu[2] = {
|
||||
static struct rsnd_src_platform_info rsnd_src[2] = {
|
||||
/* no member at this point */
|
||||
};
|
||||
|
||||
static struct rsnd_dai_platform_info rsnd_dai = {
|
||||
.playback = { .ssi = &rsnd_ssi[0], },
|
||||
.capture = { .ssi = &rsnd_ssi[1], },
|
||||
};
|
||||
|
||||
static struct rcar_snd_info rsnd_info = {
|
||||
.flags = RSND_GEN2,
|
||||
.ssi_info = rsnd_ssi,
|
||||
.ssi_info_nr = ARRAY_SIZE(rsnd_ssi),
|
||||
.scu_info = rsnd_scu,
|
||||
.scu_info_nr = ARRAY_SIZE(rsnd_scu),
|
||||
.src_info = rsnd_src,
|
||||
.src_info_nr = ARRAY_SIZE(rsnd_src),
|
||||
.dai_info = &rsnd_dai,
|
||||
.dai_info_nr = 1,
|
||||
};
|
||||
|
||||
static struct asoc_simple_card_info rsnd_card_info = {
|
||||
|
|
|
@ -175,10 +175,6 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
|
||||
static struct clk_lookup lookups[] = {
|
||||
/* main */
|
||||
CLKDEV_CON_ID("audio_clk_a", &audio_clk_a),
|
||||
CLKDEV_CON_ID("audio_clk_b", &audio_clk_b),
|
||||
CLKDEV_CON_ID("audio_clk_c", &audio_clk_c),
|
||||
CLKDEV_CON_ID("audio_clk_internal", &s1_clk),
|
||||
CLKDEV_CON_ID("shyway_clk", &s_clk),
|
||||
CLKDEV_CON_ID("peripheral_clk", &p_clk),
|
||||
|
||||
|
@ -234,15 +230,15 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]),
|
||||
CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]),
|
||||
CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]),
|
||||
CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP531]),
|
||||
CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP530]),
|
||||
CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP529]),
|
||||
CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP528]),
|
||||
CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP527]),
|
||||
CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP526]),
|
||||
CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP525]),
|
||||
CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP524]),
|
||||
CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP523]),
|
||||
CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]),
|
||||
CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]),
|
||||
CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]),
|
||||
CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]),
|
||||
CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]),
|
||||
CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]),
|
||||
CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]),
|
||||
CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]),
|
||||
CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]),
|
||||
};
|
||||
|
||||
void __init r8a7778_clock_init(void)
|
||||
|
|
|
@ -249,10 +249,10 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
[MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */
|
||||
[MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */
|
||||
[MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */
|
||||
[MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
|
||||
[MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
|
||||
[MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
|
||||
[MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
|
||||
[MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
|
||||
[MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
|
||||
[MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
|
||||
[MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
|
||||
[MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
|
||||
[MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
|
||||
[MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
|
||||
|
@ -294,10 +294,6 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
static struct clk_lookup lookups[] = {
|
||||
|
||||
/* main clocks */
|
||||
CLKDEV_CON_ID("audio_clk_a", &audio_clk_a),
|
||||
CLKDEV_CON_ID("audio_clk_b", &audio_clk_b),
|
||||
CLKDEV_CON_ID("audio_clk_c", &audio_clk_c),
|
||||
CLKDEV_CON_ID("audio_clk_internal", &m2_clk),
|
||||
CLKDEV_CON_ID("extal", &extal_clk),
|
||||
CLKDEV_CON_ID("extal_div2", &extal_div2_clk),
|
||||
CLKDEV_CON_ID("main", &main_clk),
|
||||
|
@ -381,16 +377,16 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
|
||||
CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
|
||||
CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk),
|
||||
CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP1031]),
|
||||
CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP1030]),
|
||||
CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP1029]),
|
||||
CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP1028]),
|
||||
CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP1027]),
|
||||
CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP1026]),
|
||||
CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP1025]),
|
||||
CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP1024]),
|
||||
CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP1023]),
|
||||
CLKDEV_ICK_ID("scu.9", "rcar_sound", &mstp_clks[MSTP1022]),
|
||||
CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP1031]),
|
||||
CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP1030]),
|
||||
CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP1029]),
|
||||
CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP1028]),
|
||||
CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP1027]),
|
||||
CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP1026]),
|
||||
CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP1025]),
|
||||
CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP1024]),
|
||||
CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP1023]),
|
||||
CLKDEV_ICK_ID("src.9", "rcar_sound", &mstp_clks[MSTP1022]),
|
||||
CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]),
|
||||
CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]),
|
||||
CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]),
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/clkdev.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/rcar-gen2.h>
|
||||
|
||||
/*
|
||||
* MD EXTAL PLL0 PLL1 PLL3
|
||||
|
@ -43,8 +44,6 @@
|
|||
* see "p1 / 2" on R8A7791_CLOCK_ROOT() below
|
||||
*/
|
||||
|
||||
#define MD(nr) (1 << nr)
|
||||
|
||||
#define CPG_BASE 0xe6150000
|
||||
#define CPG_LEN 0x1000
|
||||
|
||||
|
@ -68,7 +67,6 @@
|
|||
#define MSTPSR9 IOMEM(0xe61509a4)
|
||||
#define MSTPSR11 IOMEM(0xe61509ac)
|
||||
|
||||
#define MODEMR 0xE6160060
|
||||
#define SDCKCR 0xE6150074
|
||||
#define SD1CKCR 0xE6150078
|
||||
#define SD2CKCR 0xE615026c
|
||||
|
@ -190,12 +188,12 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
[MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */
|
||||
[MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */
|
||||
[MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */
|
||||
[MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
|
||||
[MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
|
||||
[MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
|
||||
[MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
|
||||
[MSTP927] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */
|
||||
[MSTP925] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */
|
||||
[MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
|
||||
[MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
|
||||
[MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
|
||||
[MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
|
||||
[MSTP927] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */
|
||||
[MSTP925] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */
|
||||
[MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
|
||||
[MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
|
||||
[MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
|
||||
|
@ -295,14 +293,9 @@ static struct clk_lookup lookups[] = {
|
|||
|
||||
void __init r8a7791_clock_init(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
|
||||
u32 mode;
|
||||
u32 mode = rcar_gen2_read_mode_pins();
|
||||
int k, ret = 0;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
switch (mode & (MD(14) | MD(13))) {
|
||||
case 0:
|
||||
R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
|
||||
|
|
|
@ -21,6 +21,32 @@
|
|||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <mach/clock.h>
|
||||
|
||||
void __init shmobile_clk_workaround(const struct clk_name *clks,
|
||||
int nr_clks, bool enable)
|
||||
{
|
||||
const struct clk_name *clkn;
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nr_clks; ++i) {
|
||||
clkn = clks + i;
|
||||
clk = clk_get(NULL, clkn->clk);
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_register_clkdev(clk, clkn->con_id, clkn->dev_id);
|
||||
if (enable)
|
||||
clk_prepare_enable(clk);
|
||||
clk_put(clk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else /* CONFIG_COMMON_CLK */
|
||||
#include <linux/sh_clk.h>
|
||||
#include <linux/export.h>
|
||||
#include <mach/clock.h>
|
||||
|
@ -58,3 +84,5 @@ void __clk_put(struct clk *clk)
|
|||
{
|
||||
}
|
||||
EXPORT_SYMBOL(__clk_put);
|
||||
|
||||
#endif /* CONFIG_COMMON_CLK */
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
#ifndef CLOCK_H
|
||||
#define CLOCK_H
|
||||
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
/* temporary clock configuration helper for platform devices */
|
||||
|
||||
struct clk_name {
|
||||
const char *clk;
|
||||
const char *con_id;
|
||||
const char *dev_id;
|
||||
};
|
||||
|
||||
void shmobile_clk_workaround(const struct clk_name *clks, int nr_clks,
|
||||
bool enable);
|
||||
|
||||
#else /* CONFIG_COMMON_CLK */
|
||||
/* legacy clock implementation */
|
||||
|
||||
unsigned long shmobile_fixed_ratio_clk_recalc(struct clk *clk);
|
||||
extern struct sh_clk_ops shmobile_fixed_ratio_clk_ops;
|
||||
|
||||
|
@ -36,4 +51,5 @@ do { \
|
|||
(p)->div = d; \
|
||||
} while (0)
|
||||
|
||||
#endif /* CONFIG_COMMON_CLK */
|
||||
#endif
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
#define R8A7790_CLK_TMU0 25
|
||||
#define R8A7790_CLK_VSP1_DU1 27
|
||||
#define R8A7790_CLK_VSP1_DU0 28
|
||||
#define R8A7790_CLK_VSP1_RT 30
|
||||
#define R8A7790_CLK_VSP1_SY 31
|
||||
#define R8A7790_CLK_VSP1_R 30
|
||||
#define R8A7790_CLK_VSP1_S 31
|
||||
|
||||
/* MSTP2 */
|
||||
#define R8A7790_CLK_SCIFA2 2
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#define R8A7791_CLK_TMU0 25
|
||||
#define R8A7791_CLK_VSP1_DU1 27
|
||||
#define R8A7791_CLK_VSP1_DU0 28
|
||||
#define R8A7791_CLK_VSP1_SY 31
|
||||
#define R8A7791_CLK_VSP1_S 31
|
||||
|
||||
/* MSTP2 */
|
||||
#define R8A7791_CLK_SCIFA2 2
|
||||
|
|
|
@ -34,47 +34,39 @@
|
|||
* B : SSI direction
|
||||
*/
|
||||
#define RSND_SSI_CLK_PIN_SHARE (1 << 31)
|
||||
#define RSND_SSI_PLAY (1 << 24)
|
||||
|
||||
#define RSND_SSI(_dma_id, _pio_irq, _flags) \
|
||||
{ .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags }
|
||||
#define RSND_SSI_SET(_dai_id, _dma_id, _pio_irq, _flags) \
|
||||
{ .dai_id = _dai_id, .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags }
|
||||
#define RSND_SSI_UNUSED \
|
||||
{ .dai_id = -1, .dma_id = -1, .pio_irq = -1, .flags = 0 }
|
||||
{ .dma_id = -1, .pio_irq = -1, .flags = 0 }
|
||||
|
||||
struct rsnd_ssi_platform_info {
|
||||
int dai_id; /* will be removed */
|
||||
int dma_id;
|
||||
int pio_irq;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
#define RSND_SRC(rate, _dma_id) \
|
||||
{ .convert_rate = rate, .dma_id = _dma_id, }
|
||||
#define RSND_SRC_UNUSED \
|
||||
{ .convert_rate = 0, .dma_id = -1, }
|
||||
|
||||
struct rsnd_src_platform_info {
|
||||
u32 convert_rate; /* sampling rate convert */
|
||||
int dma_id; /* for Gen2 SCU */
|
||||
};
|
||||
|
||||
/*
|
||||
* flags
|
||||
*/
|
||||
#define RSND_SCU_USE_HPBIF (1 << 31) /* it needs RSND_SSI_DEPENDENT */
|
||||
|
||||
#define RSND_SRC(rate, _dma_id) \
|
||||
{ .flags = RSND_SCU_USE_HPBIF, .convert_rate = rate, .dma_id = _dma_id, }
|
||||
#define RSND_SRC_SET(rate, _dma_id) \
|
||||
{ .flags = RSND_SCU_USE_HPBIF, .convert_rate = rate, .dma_id = _dma_id, }
|
||||
#define RSND_SRC_UNUSED \
|
||||
{ .flags = 0, .convert_rate = 0, .dma_id = 0, }
|
||||
|
||||
#define rsnd_scu_platform_info rsnd_src_platform_info
|
||||
#define src_info scu_info
|
||||
#define src_info_nr scu_info_nr
|
||||
|
||||
struct rsnd_src_platform_info {
|
||||
struct rsnd_dvc_platform_info {
|
||||
u32 flags;
|
||||
u32 convert_rate; /* sampling rate convert */
|
||||
int dma_id; /* for Gen2 SCU */
|
||||
};
|
||||
|
||||
struct rsnd_dai_path_info {
|
||||
struct rsnd_ssi_platform_info *ssi;
|
||||
struct rsnd_src_platform_info *src;
|
||||
struct rsnd_dvc_platform_info *dvc;
|
||||
};
|
||||
|
||||
struct rsnd_dai_platform_info {
|
||||
|
@ -99,6 +91,8 @@ struct rcar_snd_info {
|
|||
int ssi_info_nr;
|
||||
struct rsnd_src_platform_info *src_info;
|
||||
int src_info_nr;
|
||||
struct rsnd_dvc_platform_info *dvc_info;
|
||||
int dvc_info_nr;
|
||||
struct rsnd_dai_platform_info *dai_info;
|
||||
int dai_info_nr;
|
||||
int (*start)(int id);
|
||||
|
|
|
@ -16,6 +16,10 @@ struct rt5640_platform_data {
|
|||
bool in1_diff;
|
||||
bool in2_diff;
|
||||
|
||||
bool dmic_en;
|
||||
bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
|
||||
bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */
|
||||
|
||||
int ldo1_en; /* GPIO for LDO1_EN */
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* linux/sound/rt5645.h -- Platform data for RT5645
|
||||
*
|
||||
* Copyright 2013 Realtek Microelectronics
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_RT5645_H
|
||||
#define __LINUX_SND_RT5645_H
|
||||
|
||||
struct rt5645_platform_data {
|
||||
/* IN2 can optionally be differential */
|
||||
bool in2_diff;
|
||||
|
||||
bool dmic_en;
|
||||
unsigned int dmic1_data_pin;
|
||||
/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
|
||||
unsigned int dmic2_data_pin;
|
||||
/* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* linux/sound/rt286.h -- Platform data for RT286
|
||||
*
|
||||
* Copyright 2013 Realtek Microelectronics
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_RT5651_H
|
||||
#define __LINUX_SND_RT5651_H
|
||||
|
||||
struct rt5651_platform_data {
|
||||
/* IN2 can optionally be differential */
|
||||
bool in2_diff;
|
||||
|
||||
bool dmic_en;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -14,6 +14,8 @@
|
|||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dmaengine.h>
|
||||
|
||||
#include <mach/dma.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
|
|
@ -9,12 +9,11 @@
|
|||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <mach/dma.h>
|
||||
|
||||
struct pxa2xx_runtime_data {
|
||||
int dma_ch;
|
||||
struct snd_dmaengine_dai_dma_data *params;
|
||||
pxa_dma_desc *dma_desc_array;
|
||||
struct pxa_dma_desc *dma_desc_array;
|
||||
dma_addr_t dma_desc_array_phys;
|
||||
};
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_PCM512x_SPI if SPI_MASTER
|
||||
select SND_SOC_RT5631 if I2C
|
||||
select SND_SOC_RT5640 if I2C
|
||||
select SND_SOC_RT5645 if I2C
|
||||
select SND_SOC_RT5651 if I2C
|
||||
select SND_SOC_SGTL5000 if I2C
|
||||
select SND_SOC_SI476X if MFD_SI476X_CORE
|
||||
select SND_SOC_SIRF_AUDIO_CODEC
|
||||
|
@ -406,6 +408,12 @@ config SND_SOC_RT5631
|
|||
config SND_SOC_RT5640
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT5645
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT5651
|
||||
tristate
|
||||
|
||||
#Freescale sgtl5000 codec
|
||||
config SND_SOC_SGTL5000
|
||||
tristate "Freescale SGTL5000 CODEC"
|
||||
|
|
|
@ -62,6 +62,8 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
|
|||
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
|
||||
snd-soc-rt5631-objs := rt5631.o
|
||||
snd-soc-rt5640-objs := rt5640.o
|
||||
snd-soc-rt5645-objs := rt5645.o
|
||||
snd-soc-rt5651-objs := rt5651.o
|
||||
snd-soc-sgtl5000-objs := sgtl5000.o
|
||||
snd-soc-alc5623-objs := alc5623.o
|
||||
snd-soc-alc5632-objs := alc5632.o
|
||||
|
@ -216,6 +218,8 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
|
|||
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
|
||||
obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
|
||||
obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
|
||||
obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
|
||||
obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
|
||||
obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
|
||||
obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
|
||||
obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* rt5640.c -- RT5640 ALSA SoC audio codec driver
|
||||
* rt5640.c -- RT5640/RT5639 ALSA SoC audio codec driver
|
||||
*
|
||||
* Copyright 2011 Realtek Semiconductor Corp.
|
||||
* Author: Johnny Hsu <johnnyhsu@realtek.com>
|
||||
|
@ -60,7 +60,7 @@ static struct reg_default init_list[] = {
|
|||
};
|
||||
#define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list)
|
||||
|
||||
static const struct reg_default rt5640_reg[RT5640_VENDOR_ID2 + 1] = {
|
||||
static const struct reg_default rt5640_reg[] = {
|
||||
{ 0x00, 0x000e },
|
||||
{ 0x01, 0xc8c8 },
|
||||
{ 0x02, 0xc8c8 },
|
||||
|
@ -399,18 +399,13 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = {
|
|||
RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
|
||||
SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT,
|
||||
RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
|
||||
/* MONO Output Control */
|
||||
SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT,
|
||||
RT5640_L_MUTE_SFT, 1, 1),
|
||||
|
||||
/* DAC Digital Volume */
|
||||
SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL,
|
||||
RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1),
|
||||
SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL,
|
||||
RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
|
||||
175, 0, dac_vol_tlv),
|
||||
SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL,
|
||||
RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
|
||||
175, 0, dac_vol_tlv),
|
||||
/* IN1/IN2 Control */
|
||||
SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2,
|
||||
RT5640_BST_SFT1, 8, 0, bst_tlv),
|
||||
|
@ -442,6 +437,15 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = {
|
|||
SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = {
|
||||
/* MONO Output Control */
|
||||
SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, RT5640_L_MUTE_SFT,
|
||||
1, 1),
|
||||
|
||||
SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL,
|
||||
RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 175, 0, dac_vol_tlv),
|
||||
};
|
||||
|
||||
/**
|
||||
* set_dmic_clk - Set parameter of dmic.
|
||||
*
|
||||
|
@ -481,14 +485,14 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
|||
return idx;
|
||||
}
|
||||
|
||||
static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
|
||||
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = snd_soc_read(source->codec, RT5640_GLB_CLK);
|
||||
val &= RT5640_SCLK_SRC_MASK;
|
||||
if (val == RT5640_SCLK_SRC_PLL1 || val == RT5640_SCLK_SRC_PLL1T)
|
||||
if (val == RT5640_SCLK_SRC_PLL1)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
@ -555,6 +559,20 @@ static const struct snd_kcontrol_new rt5640_sto_dac_r_mix[] = {
|
|||
RT5640_M_ANC_DAC_R_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5639_sto_dac_l_mix[] = {
|
||||
SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_STO_DAC_MIXER,
|
||||
RT5640_M_DAC_L1_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_STO_DAC_MIXER,
|
||||
RT5640_M_DAC_L2_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5639_sto_dac_r_mix[] = {
|
||||
SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_STO_DAC_MIXER,
|
||||
RT5640_M_DAC_R1_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_STO_DAC_MIXER,
|
||||
RT5640_M_DAC_R2_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = {
|
||||
SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER,
|
||||
RT5640_M_DAC_L1_MONO_L_SFT, 1, 1),
|
||||
|
@ -677,6 +695,30 @@ static const struct snd_kcontrol_new rt5640_out_r_mix[] = {
|
|||
RT5640_M_DAC_R1_OM_R_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5639_out_l_mix[] = {
|
||||
SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_L3_MIXER,
|
||||
RT5640_M_BST1_OM_L_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("INL Switch", RT5640_OUT_L3_MIXER,
|
||||
RT5640_M_IN_L_OM_L_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_OUT_L3_MIXER,
|
||||
RT5640_M_RM_L_OM_L_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_OUT_L3_MIXER,
|
||||
RT5640_M_DAC_L1_OM_L_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5639_out_r_mix[] = {
|
||||
SOC_DAPM_SINGLE("BST2 Switch", RT5640_OUT_R3_MIXER,
|
||||
RT5640_M_BST4_OM_R_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_R3_MIXER,
|
||||
RT5640_M_BST1_OM_R_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("INR Switch", RT5640_OUT_R3_MIXER,
|
||||
RT5640_M_IN_R_OM_R_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_OUT_R3_MIXER,
|
||||
RT5640_M_RM_R_OM_R_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_OUT_R3_MIXER,
|
||||
RT5640_M_DAC_R1_OM_R_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5640_spo_l_mix[] = {
|
||||
SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER,
|
||||
RT5640_M_DAC_R1_SPM_L_SFT, 1, 1),
|
||||
|
@ -708,6 +750,13 @@ static const struct snd_kcontrol_new rt5640_hpo_mix[] = {
|
|||
RT5640_M_HPVOL_HM_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5639_hpo_mix[] = {
|
||||
SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5640_HPO_MIXER,
|
||||
RT5640_M_DAC1_HM_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5640_HPO_MIXER,
|
||||
RT5640_M_HPVOL_HM_SFT, 1, 1),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt5640_lout_mix[] = {
|
||||
SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER,
|
||||
RT5640_M_DAC_L1_LM_SFT, 1, 1),
|
||||
|
@ -873,54 +922,6 @@ static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP,
|
|||
static const struct snd_kcontrol_new rt5640_sdi_mux =
|
||||
SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
|
||||
|
||||
static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_update_bits(codec, RT5640_GPIO_CTRL1,
|
||||
RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK,
|
||||
RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP3_PIN_DMIC1_SDA);
|
||||
snd_soc_update_bits(codec, RT5640_DMIC,
|
||||
RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK |
|
||||
RT5640_DMIC_1_DP_MASK,
|
||||
RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING |
|
||||
RT5640_DMIC_1_DP_IN1P);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_update_bits(codec, RT5640_GPIO_CTRL1,
|
||||
RT5640_GP2_PIN_MASK | RT5640_GP4_PIN_MASK,
|
||||
RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP4_PIN_DMIC2_SDA);
|
||||
snd_soc_update_bits(codec, RT5640_DMIC,
|
||||
RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK |
|
||||
RT5640_DMIC_2_DP_MASK,
|
||||
RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING |
|
||||
RT5640_DMIC_2_DP_IN1N);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hp_amp_power_on(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
|
||||
|
@ -1055,12 +1056,10 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
|
|||
|
||||
SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
|
||||
set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
|
||||
SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC,
|
||||
RT5640_DMIC_1_EN_SFT, 0, rt5640_set_dmic1_event,
|
||||
SND_SOC_DAPM_PRE_PMU),
|
||||
SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC,
|
||||
RT5640_DMIC_2_EN_SFT, 0, rt5640_set_dmic2_event,
|
||||
SND_SOC_DAPM_PRE_PMU),
|
||||
SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC, RT5640_DMIC_1_EN_SFT, 0,
|
||||
NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC, RT5640_DMIC_2_EN_SFT, 0,
|
||||
NULL, 0),
|
||||
/* Boost */
|
||||
SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2,
|
||||
RT5640_PWR_BST1_BIT, 0, NULL, 0),
|
||||
|
@ -1147,26 +1146,15 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
/* Audio DSP */
|
||||
SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
/* ANC */
|
||||
SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
|
||||
/* Output Side */
|
||||
/* DAC mixer before sound effect */
|
||||
SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)),
|
||||
/* DAC2 channel Mux */
|
||||
SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
|
||||
&rt5640_dac_l2_mux),
|
||||
SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0,
|
||||
&rt5640_dac_r2_mux),
|
||||
|
||||
/* DAC Mixer */
|
||||
SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)),
|
||||
SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
|
||||
|
@ -1178,21 +1166,14 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
|
|||
/* DACs */
|
||||
SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1,
|
||||
RT5640_PWR_DAC_L1_BIT, 0),
|
||||
SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1,
|
||||
RT5640_PWR_DAC_L2_BIT, 0),
|
||||
SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1,
|
||||
RT5640_PWR_DAC_R1_BIT, 0),
|
||||
SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1,
|
||||
RT5640_PWR_DAC_R2_BIT, 0),
|
||||
|
||||
/* SPK/OUT Mixer */
|
||||
SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,
|
||||
0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT,
|
||||
0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)),
|
||||
SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,
|
||||
0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT,
|
||||
0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)),
|
||||
/* Ouput Volume */
|
||||
SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL,
|
||||
RT5640_PWR_SV_L_BIT, 0, NULL, 0),
|
||||
|
@ -1211,16 +1192,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
|
|||
0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0,
|
||||
0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)),
|
||||
SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
|
||||
SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
|
||||
SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0,
|
||||
rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)),
|
||||
SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0,
|
||||
rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
|
||||
SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
|
||||
RT5640_PWR_MA_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM,
|
||||
0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
|
||||
|
@ -1252,10 +1225,69 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_OUTPUT("HPOR"),
|
||||
SND_SOC_DAPM_OUTPUT("LOUTL"),
|
||||
SND_SOC_DAPM_OUTPUT("LOUTR"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = {
|
||||
/* Audio DSP */
|
||||
SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
/* ANC */
|
||||
SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
|
||||
/* DAC2 channel Mux */
|
||||
SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_l2_mux),
|
||||
SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_r2_mux),
|
||||
|
||||
SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)),
|
||||
|
||||
SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_R2_BIT,
|
||||
0),
|
||||
SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_L2_BIT,
|
||||
0),
|
||||
|
||||
SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,
|
||||
0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT,
|
||||
0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)),
|
||||
|
||||
SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
|
||||
SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0,
|
||||
rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
|
||||
|
||||
SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0,
|
||||
rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
|
||||
SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
|
||||
RT5640_PWR_MA_BIT, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("MONOP"),
|
||||
SND_SOC_DAPM_OUTPUT("MONON"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
|
||||
rt5639_sto_dac_l_mix, ARRAY_SIZE(rt5639_sto_dac_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
|
||||
rt5639_sto_dac_r_mix, ARRAY_SIZE(rt5639_sto_dac_r_mix)),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY("DAC L2 Filter", RT5640_PWR_DIG1,
|
||||
RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DAC R2 Filter", RT5640_PWR_DIG1,
|
||||
RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,
|
||||
0, rt5639_out_l_mix, ARRAY_SIZE(rt5639_out_l_mix)),
|
||||
SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT,
|
||||
0, rt5639_out_r_mix, ARRAY_SIZE(rt5639_out_r_mix)),
|
||||
|
||||
SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0,
|
||||
rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)),
|
||||
SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0,
|
||||
rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
|
||||
{"IN1P", NULL, "LDO2"},
|
||||
{"IN2P", NULL, "LDO2"},
|
||||
|
@ -1324,22 +1356,22 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
|
|||
{"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"},
|
||||
{"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"},
|
||||
{"Stereo ADC MIXL", NULL, "Stereo Filter"},
|
||||
{"Stereo Filter", NULL, "PLL1", check_sysclk1_source},
|
||||
{"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
|
||||
{"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"},
|
||||
{"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"},
|
||||
{"Stereo ADC MIXR", NULL, "Stereo Filter"},
|
||||
{"Stereo Filter", NULL, "PLL1", check_sysclk1_source},
|
||||
{"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
|
||||
{"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"},
|
||||
{"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"},
|
||||
{"Mono ADC MIXL", NULL, "Mono Left Filter"},
|
||||
{"Mono Left Filter", NULL, "PLL1", check_sysclk1_source},
|
||||
{"Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
|
||||
{"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"},
|
||||
{"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"},
|
||||
{"Mono ADC MIXR", NULL, "Mono Right Filter"},
|
||||
{"Mono Right Filter", NULL, "PLL1", check_sysclk1_source},
|
||||
{"Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
|
||||
{"IF2 ADC L", NULL, "Mono ADC MIXL"},
|
||||
{"IF2 ADC R", NULL, "Mono ADC MIXR"},
|
||||
|
@ -1397,71 +1429,38 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
|
|||
{"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"},
|
||||
{"DAC MIXR", "INF1 Switch", "IF1 DAC R"},
|
||||
|
||||
{"ANC", NULL, "Stereo ADC MIXL"},
|
||||
{"ANC", NULL, "Stereo ADC MIXR"},
|
||||
|
||||
{"Audio DSP", NULL, "DAC MIXL"},
|
||||
{"Audio DSP", NULL, "DAC MIXR"},
|
||||
|
||||
{"DAC L2 Mux", "IF2", "IF2 DAC L"},
|
||||
{"DAC L2 Mux", "Base L/R", "Audio DSP"},
|
||||
|
||||
{"DAC R2 Mux", "IF2", "IF2 DAC R"},
|
||||
|
||||
{"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"},
|
||||
{"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
{"Stereo DAC MIXL", "ANC Switch", "ANC"},
|
||||
{"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"},
|
||||
{"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
{"Stereo DAC MIXR", "ANC Switch", "ANC"},
|
||||
|
||||
{"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"},
|
||||
{"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
{"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
{"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"},
|
||||
{"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
{"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
|
||||
{"DIG MIXL", "DAC L1 Switch", "DAC MIXL"},
|
||||
{"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
{"DIG MIXR", "DAC R1 Switch", "DAC MIXR"},
|
||||
{"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
|
||||
{"DAC L1", NULL, "Stereo DAC MIXL"},
|
||||
{"DAC L1", NULL, "PLL1", check_sysclk1_source},
|
||||
{"DAC L1", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
{"DAC R1", NULL, "Stereo DAC MIXR"},
|
||||
{"DAC R1", NULL, "PLL1", check_sysclk1_source},
|
||||
{"DAC L2", NULL, "Mono DAC MIXL"},
|
||||
{"DAC L2", NULL, "PLL1", check_sysclk1_source},
|
||||
{"DAC R2", NULL, "Mono DAC MIXR"},
|
||||
{"DAC R2", NULL, "PLL1", check_sysclk1_source},
|
||||
{"DAC R1", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
|
||||
{"SPK MIXL", "REC MIXL Switch", "RECMIXL"},
|
||||
{"SPK MIXL", "INL Switch", "INL VOL"},
|
||||
{"SPK MIXL", "DAC L1 Switch", "DAC L1"},
|
||||
{"SPK MIXL", "DAC L2 Switch", "DAC L2"},
|
||||
{"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"},
|
||||
{"SPK MIXR", "REC MIXR Switch", "RECMIXR"},
|
||||
{"SPK MIXR", "INR Switch", "INR VOL"},
|
||||
{"SPK MIXR", "DAC R1 Switch", "DAC R1"},
|
||||
{"SPK MIXR", "DAC R2 Switch", "DAC R2"},
|
||||
{"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"},
|
||||
|
||||
{"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"},
|
||||
{"OUT MIXL", "BST1 Switch", "BST1"},
|
||||
{"OUT MIXL", "INL Switch", "INL VOL"},
|
||||
{"OUT MIXL", "REC MIXL Switch", "RECMIXL"},
|
||||
{"OUT MIXL", "DAC R2 Switch", "DAC R2"},
|
||||
{"OUT MIXL", "DAC L2 Switch", "DAC L2"},
|
||||
{"OUT MIXL", "DAC L1 Switch", "DAC L1"},
|
||||
|
||||
{"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"},
|
||||
{"OUT MIXR", "BST2 Switch", "BST2"},
|
||||
{"OUT MIXR", "BST1 Switch", "BST1"},
|
||||
{"OUT MIXR", "INR Switch", "INR VOL"},
|
||||
{"OUT MIXR", "REC MIXR Switch", "RECMIXR"},
|
||||
{"OUT MIXR", "DAC L2 Switch", "DAC L2"},
|
||||
{"OUT MIXR", "DAC R2 Switch", "DAC R2"},
|
||||
{"OUT MIXR", "DAC R1 Switch", "DAC R1"},
|
||||
|
||||
{"SPKVOL L", NULL, "SPK MIXL"},
|
||||
|
@ -1480,11 +1479,9 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
|
|||
{"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"},
|
||||
{"SPOR MIX", "BST1 Switch", "BST1"},
|
||||
|
||||
{"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"},
|
||||
{"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"},
|
||||
{"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"},
|
||||
{"HPO MIX L", NULL, "HP L Amp"},
|
||||
{"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"},
|
||||
{"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"},
|
||||
{"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"},
|
||||
{"HPO MIX R", NULL, "HP R Amp"},
|
||||
|
@ -1494,12 +1491,6 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
|
|||
{"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"},
|
||||
{"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"},
|
||||
|
||||
{"Mono MIX", "DAC R2 Switch", "DAC R2"},
|
||||
{"Mono MIX", "DAC L2 Switch", "DAC L2"},
|
||||
{"Mono MIX", "OUTVOL R Switch", "OUTVOL R"},
|
||||
{"Mono MIX", "OUTVOL L Switch", "OUTVOL L"},
|
||||
{"Mono MIX", "BST1 Switch", "BST1"},
|
||||
|
||||
{"HP Amp", NULL, "HPO MIX L"},
|
||||
{"HP Amp", NULL, "HPO MIX R"},
|
||||
|
||||
|
@ -1524,11 +1515,82 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
|
|||
{"HPOR", NULL, "HP R Playback"},
|
||||
{"LOUTL", NULL, "LOUT MIX"},
|
||||
{"LOUTR", NULL, "LOUT MIX"},
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = {
|
||||
{"ANC", NULL, "Stereo ADC MIXL"},
|
||||
{"ANC", NULL, "Stereo ADC MIXR"},
|
||||
|
||||
{"Audio DSP", NULL, "DAC MIXL"},
|
||||
{"Audio DSP", NULL, "DAC MIXR"},
|
||||
|
||||
{"DAC L2 Mux", "IF2", "IF2 DAC L"},
|
||||
{"DAC L2 Mux", "Base L/R", "Audio DSP"},
|
||||
|
||||
{"DAC R2 Mux", "IF2", "IF2 DAC R"},
|
||||
|
||||
{"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
{"Stereo DAC MIXL", "ANC Switch", "ANC"},
|
||||
{"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
{"Stereo DAC MIXR", "ANC Switch", "ANC"},
|
||||
|
||||
{"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
{"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
|
||||
{"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
{"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
|
||||
{"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"},
|
||||
{"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"},
|
||||
|
||||
{"DAC L2", NULL, "Mono DAC MIXL"},
|
||||
{"DAC L2", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
{"DAC R2", NULL, "Mono DAC MIXR"},
|
||||
{"DAC R2", NULL, "PLL1", is_sys_clk_from_pll},
|
||||
|
||||
{"SPK MIXL", "DAC L2 Switch", "DAC L2"},
|
||||
{"SPK MIXR", "DAC R2 Switch", "DAC R2"},
|
||||
|
||||
{"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"},
|
||||
{"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"},
|
||||
|
||||
{"OUT MIXL", "DAC R2 Switch", "DAC R2"},
|
||||
{"OUT MIXL", "DAC L2 Switch", "DAC L2"},
|
||||
|
||||
{"OUT MIXR", "DAC L2 Switch", "DAC L2"},
|
||||
{"OUT MIXR", "DAC R2 Switch", "DAC R2"},
|
||||
|
||||
{"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"},
|
||||
{"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"},
|
||||
|
||||
{"Mono MIX", "DAC R2 Switch", "DAC R2"},
|
||||
{"Mono MIX", "DAC L2 Switch", "DAC L2"},
|
||||
{"Mono MIX", "OUTVOL R Switch", "OUTVOL R"},
|
||||
{"Mono MIX", "OUTVOL L Switch", "OUTVOL L"},
|
||||
{"Mono MIX", "BST1 Switch", "BST1"},
|
||||
|
||||
{"MONOP", NULL, "Mono MIX"},
|
||||
{"MONON", NULL, "Mono MIX"},
|
||||
{"MONOP", NULL, "Improve MONO Amp Drv"},
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt5639_specific_dapm_routes[] = {
|
||||
{"Stereo DAC MIXL", "DAC L2 Switch", "IF2 DAC L"},
|
||||
{"Stereo DAC MIXR", "DAC R2 Switch", "IF2 DAC R"},
|
||||
|
||||
{"Mono DAC MIXL", "DAC L2 Switch", "IF2 DAC L"},
|
||||
{"Mono DAC MIXL", "DAC R2 Switch", "IF2 DAC R"},
|
||||
|
||||
{"Mono DAC MIXR", "DAC R2 Switch", "IF2 DAC R"},
|
||||
{"Mono DAC MIXR", "DAC L2 Switch", "IF2 DAC L"},
|
||||
|
||||
{"DIG MIXL", "DAC L2 Switch", "IF2 DAC L"},
|
||||
{"DIG MIXR", "DAC R2 Switch", "IF2 DAC R"},
|
||||
|
||||
{"IF2 DAC L", NULL, "DAC L2 Filter"},
|
||||
{"IF2 DAC R", NULL, "DAC R2 Filter"},
|
||||
};
|
||||
|
||||
static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
|
||||
{
|
||||
int ret = 0, val;
|
||||
|
@ -1623,16 +1685,16 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,
|
|||
dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
|
||||
bclk_ms, pre_div, dai->id);
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
switch (params_width(params)) {
|
||||
case 16:
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
case 20:
|
||||
val_len |= RT5640_I2S_DL_20;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
case 24:
|
||||
val_len |= RT5640_I2S_DL_24;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S8:
|
||||
case 8:
|
||||
val_len |= RT5640_I2S_DL_8;
|
||||
break;
|
||||
default:
|
||||
|
@ -1745,12 +1807,6 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
|
|||
case RT5640_SCLK_S_PLL1:
|
||||
reg_val |= RT5640_SCLK_SRC_PLL1;
|
||||
break;
|
||||
case RT5640_SCLK_S_PLL1_TK:
|
||||
reg_val |= RT5640_SCLK_SRC_PLL1T;
|
||||
break;
|
||||
case RT5640_SCLK_S_RCCLK:
|
||||
reg_val |= RT5640_SCLK_SRC_RCCLK;
|
||||
break;
|
||||
default:
|
||||
dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
|
||||
return -EINVAL;
|
||||
|
@ -1891,11 +1947,9 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
|
|||
static int rt5640_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
|
||||
regcache_cache_only(rt5640->regmap, false);
|
||||
snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
|
||||
RT5640_PWR_VREF1 | RT5640_PWR_MB |
|
||||
RT5640_PWR_BG | RT5640_PWR_VREF2,
|
||||
|
@ -1905,7 +1959,6 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
|
|||
snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
|
||||
RT5640_PWR_FV1 | RT5640_PWR_FV2,
|
||||
RT5640_PWR_FV1 | RT5640_PWR_FV2);
|
||||
regcache_sync(rt5640->regmap);
|
||||
snd_soc_update_bits(codec, RT5640_DUMMY1,
|
||||
0x0301, 0x0301);
|
||||
snd_soc_update_bits(codec, RT5640_MICBIAS,
|
||||
|
@ -1939,13 +1992,39 @@ static int rt5640_probe(struct snd_soc_codec *codec)
|
|||
|
||||
rt5640->codec = codec;
|
||||
|
||||
codec->dapm.idle_bias_off = 1;
|
||||
rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
|
||||
snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
|
||||
snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
|
||||
snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
|
||||
|
||||
switch (snd_soc_read(codec, RT5640_RESET) & RT5640_ID_MASK) {
|
||||
case RT5640_ID_5640:
|
||||
case RT5640_ID_5642:
|
||||
snd_soc_add_codec_controls(codec,
|
||||
rt5640_specific_snd_controls,
|
||||
ARRAY_SIZE(rt5640_specific_snd_controls));
|
||||
snd_soc_dapm_new_controls(&codec->dapm,
|
||||
rt5640_specific_dapm_widgets,
|
||||
ARRAY_SIZE(rt5640_specific_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(&codec->dapm,
|
||||
rt5640_specific_dapm_routes,
|
||||
ARRAY_SIZE(rt5640_specific_dapm_routes));
|
||||
break;
|
||||
case RT5640_ID_5639:
|
||||
snd_soc_dapm_new_controls(&codec->dapm,
|
||||
rt5639_specific_dapm_widgets,
|
||||
ARRAY_SIZE(rt5639_specific_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(&codec->dapm,
|
||||
rt5639_specific_dapm_routes,
|
||||
ARRAY_SIZE(rt5639_specific_dapm_routes));
|
||||
break;
|
||||
default:
|
||||
dev_err(codec->dev,
|
||||
"The driver is for RT5639 RT5640 or RT5642 only\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1980,6 +2059,9 @@ static int rt5640_resume(struct snd_soc_codec *codec)
|
|||
msleep(400);
|
||||
}
|
||||
|
||||
regcache_cache_only(rt5640->regmap, false);
|
||||
regcache_sync(rt5640->regmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
@ -2045,6 +2127,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = {
|
|||
.suspend = rt5640_suspend,
|
||||
.resume = rt5640_resume,
|
||||
.set_bias_level = rt5640_set_bias_level,
|
||||
.idle_bias_off = true,
|
||||
.controls = rt5640_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(rt5640_snd_controls),
|
||||
.dapm_widgets = rt5640_dapm_widgets,
|
||||
|
@ -2071,12 +2154,15 @@ static const struct regmap_config rt5640_regmap = {
|
|||
|
||||
static const struct i2c_device_id rt5640_i2c_id[] = {
|
||||
{ "rt5640", 0 },
|
||||
{ "rt5639", 0 },
|
||||
{ "rt5642", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id);
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id rt5640_of_match[] = {
|
||||
{ .compatible = "realtek,rt5639", },
|
||||
{ .compatible = "realtek,rt5640", },
|
||||
{},
|
||||
};
|
||||
|
@ -2167,7 +2253,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
|
|||
}
|
||||
|
||||
regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val);
|
||||
if ((val != RT5640_DEVICE_ID)) {
|
||||
if (val != RT5640_DEVICE_ID) {
|
||||
dev_err(&i2c->dev,
|
||||
"Device with ID register %x is not rt5640/39\n", val);
|
||||
return -ENODEV;
|
||||
|
@ -2188,6 +2274,25 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
|
|||
regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
|
||||
RT5640_IN_DF2, RT5640_IN_DF2);
|
||||
|
||||
if (rt5640->pdata.dmic_en) {
|
||||
regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
|
||||
RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL);
|
||||
|
||||
if (rt5640->pdata.dmic1_data_pin) {
|
||||
regmap_update_bits(rt5640->regmap, RT5640_DMIC,
|
||||
RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3);
|
||||
regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
|
||||
RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA);
|
||||
}
|
||||
|
||||
if (rt5640->pdata.dmic2_data_pin) {
|
||||
regmap_update_bits(rt5640->regmap, RT5640_DMIC,
|
||||
RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4);
|
||||
regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
|
||||
RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA);
|
||||
}
|
||||
}
|
||||
|
||||
rt5640->hp_mute = 1;
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
|
||||
|
@ -2220,6 +2325,6 @@ static struct i2c_driver rt5640_i2c_driver = {
|
|||
};
|
||||
module_i2c_driver(rt5640_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC RT5640 driver");
|
||||
MODULE_DESCRIPTION("ASoC RT5640/RT5639 driver");
|
||||
MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -192,6 +192,13 @@
|
|||
#define RT5640_R_VOL_MASK (0x3f)
|
||||
#define RT5640_R_VOL_SFT 0
|
||||
|
||||
/* SW Reset & Device ID (0x00) */
|
||||
#define RT5640_ID_MASK (0x3 << 1)
|
||||
#define RT5640_ID_5639 (0x0 << 1)
|
||||
#define RT5640_ID_5640 (0x2 << 1)
|
||||
#define RT5640_ID_5642 (0x3 << 1)
|
||||
|
||||
|
||||
/* IN1 and IN2 Control (0x0d) */
|
||||
/* IN3 and IN4 Control (0x0e) */
|
||||
#define RT5640_BST_SFT1 12
|
||||
|
@ -976,8 +983,6 @@
|
|||
#define RT5640_SCLK_SRC_SFT 14
|
||||
#define RT5640_SCLK_SRC_MCLK (0x0 << 14)
|
||||
#define RT5640_SCLK_SRC_PLL1 (0x1 << 14)
|
||||
#define RT5640_SCLK_SRC_PLL1T (0x2 << 14)
|
||||
#define RT5640_SCLK_SRC_RCCLK (0x3 << 14) /* 15MHz */
|
||||
#define RT5640_PLL1_SRC_MASK (0x3 << 12)
|
||||
#define RT5640_PLL1_SRC_SFT 12
|
||||
#define RT5640_PLL1_SRC_MCLK (0x0 << 12)
|
||||
|
@ -2097,7 +2102,6 @@ struct rt5640_priv {
|
|||
int pll_in;
|
||||
int pll_out;
|
||||
|
||||
int dmic_en;
|
||||
bool hp_mute;
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@
|
|||
config SND_SOC_NUC900
|
||||
tristate "SoC Audio for NUC900 series"
|
||||
depends on ARCH_W90X900
|
||||
select SND_SOC_NUC900_AC97
|
||||
help
|
||||
This option enables support for AC97 mode on the NUC900 SoC.
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
static DEFINE_MUTEX(ac97_mutex);
|
||||
struct nuc900_audio *nuc900_ac97_data;
|
||||
EXPORT_SYMBOL_GPL(nuc900_ac97_data);
|
||||
|
||||
static int nuc900_checkready(void)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ config SND_OMAP_SOC_N810
|
|||
|
||||
config SND_OMAP_SOC_RX51
|
||||
tristate "SoC Audio support for Nokia RX-51"
|
||||
depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST)
|
||||
depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST) && I2C
|
||||
select SND_OMAP_SOC_MCBSP
|
||||
select SND_SOC_TLV320AIC3X
|
||||
select SND_SOC_TPA6130A2
|
||||
|
@ -37,7 +37,7 @@ config SND_OMAP_SOC_RX51
|
|||
|
||||
config SND_OMAP_SOC_AMS_DELTA
|
||||
tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
|
||||
depends on SND_OMAP_SOC && MACH_AMS_DELTA
|
||||
depends on SND_OMAP_SOC && MACH_AMS_DELTA && TTY
|
||||
select SND_OMAP_SOC_MCBSP
|
||||
select SND_SOC_CX20442
|
||||
help
|
||||
|
|
|
@ -77,7 +77,7 @@ static struct snd_soc_dai_link am3517evm_dai = {
|
|||
.stream_name = "AIC23",
|
||||
.cpu_dai_name = "omap-mcbsp.1",
|
||||
.codec_dai_name = "tlv320aic23-hifi",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.1",
|
||||
.codec_name = "tlv320aic23-codec.2-001a",
|
||||
.dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
|
|
|
@ -534,7 +534,7 @@ static struct snd_soc_dai_link ams_delta_dai_link = {
|
|||
.cpu_dai_name = "omap-mcbsp.1",
|
||||
.codec_dai_name = "cx20442-voice",
|
||||
.init = ams_delta_cx20442_init,
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.1",
|
||||
.codec_name = "cx20442-codec",
|
||||
.ops = &ams_delta_ops,
|
||||
};
|
||||
|
|
|
@ -278,7 +278,7 @@ static struct snd_soc_dai_link n810_dai = {
|
|||
.name = "TLV320AIC33",
|
||||
.stream_name = "AIC33",
|
||||
.cpu_dai_name = "omap-mcbsp.2",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.2",
|
||||
.codec_name = "tlv320aic3x-codec.2-0018",
|
||||
.codec_dai_name = "tlv320aic3x-hifi",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
|
|
|
@ -47,8 +47,7 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_card *card = codec->card;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
|
||||
int clk_id, freq;
|
||||
int ret;
|
||||
|
@ -168,7 +167,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
|||
static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_card *card = codec->card;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
|
||||
int hs_trim;
|
||||
int ret = 0;
|
||||
|
@ -214,9 +213,7 @@ static struct snd_soc_dai_link abe_twl6040_dai_links[] = {
|
|||
{
|
||||
.name = "TWL6040",
|
||||
.stream_name = "TWL6040",
|
||||
.cpu_dai_name = "omap-mcpdm",
|
||||
.codec_dai_name = "twl6040-legacy",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.codec_name = "twl6040-codec",
|
||||
.init = omap_abe_twl6040_init,
|
||||
.ops = &omap_abe_ops,
|
||||
|
@ -224,9 +221,7 @@ static struct snd_soc_dai_link abe_twl6040_dai_links[] = {
|
|||
{
|
||||
.name = "DMIC",
|
||||
.stream_name = "DMIC Capture",
|
||||
.cpu_dai_name = "omap-dmic",
|
||||
.codec_dai_name = "dmic-hifi",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.codec_name = "dmic-codec",
|
||||
.init = omap_abe_dmic_init,
|
||||
.ops = &omap_abe_dmic_ops,
|
||||
|
@ -281,14 +276,14 @@ static int omap_abe_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "McPDM node is not provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
abe_twl6040_dai_links[0].cpu_dai_name = NULL;
|
||||
abe_twl6040_dai_links[0].cpu_of_node = dai_node;
|
||||
abe_twl6040_dai_links[0].platform_of_node = dai_node;
|
||||
|
||||
dai_node = of_parse_phandle(node, "ti,dmic", 0);
|
||||
if (dai_node) {
|
||||
num_links = 2;
|
||||
abe_twl6040_dai_links[1].cpu_dai_name = NULL;
|
||||
abe_twl6040_dai_links[1].cpu_of_node = dai_node;
|
||||
abe_twl6040_dai_links[1].platform_of_node = dai_node;
|
||||
|
||||
priv->dmic_codec_dev = platform_device_register_simple(
|
||||
"dmic-codec", -1, NULL, 0);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "omap-dmic.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
struct omap_dmic {
|
||||
struct device *dev;
|
||||
|
@ -113,7 +114,6 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
|
|||
|
||||
mutex_unlock(&dmic->mutex);
|
||||
|
||||
snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -417,6 +417,9 @@ static int omap_dmic_probe(struct snd_soc_dai *dai)
|
|||
|
||||
/* Configure DMIC threshold value */
|
||||
dmic->threshold = OMAP_DMIC_THRES_MAX - 3;
|
||||
|
||||
snd_soc_dai_init_dma_data(dai, NULL, &dmic->dma_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -492,6 +495,10 @@ static int asoc_dmic_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto err_put_clk;
|
||||
|
||||
ret = omap_pcm_platform_register(&pdev->dev);
|
||||
if (ret)
|
||||
goto err_put_clk;
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_clk:
|
||||
|
|
|
@ -33,7 +33,7 @@ static struct snd_soc_dai_link omap_hdmi_dai = {
|
|||
.name = "HDMI",
|
||||
.stream_name = "HDMI",
|
||||
.cpu_dai_name = "omap-hdmi-audio-dai",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-hdmi-audio-dai",
|
||||
.codec_name = "hdmi-audio-codec",
|
||||
.codec_dai_name = "hdmi-hifi",
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <video/omapdss.h>
|
||||
|
||||
#include "omap-hdmi.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#define DRV_NAME "omap-hdmi-audio-dai"
|
||||
|
||||
|
@ -324,7 +325,10 @@ static int omap_hdmi_probe(struct platform_device *pdev)
|
|||
ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component,
|
||||
&omap_hdmi_dai, 1);
|
||||
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return omap_pcm_platform_register(&pdev->dev);
|
||||
}
|
||||
|
||||
static int omap_hdmi_remove(struct platform_device *pdev)
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <linux/platform_data/asoc-ti-mcbsp.h>
|
||||
#include "mcbsp.h"
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
|
||||
|
||||
|
@ -149,9 +150,6 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
|
|||
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
|
||||
}
|
||||
|
||||
snd_soc_dai_set_dma_data(cpu_dai, substream,
|
||||
&mcbsp->dma_data[substream->stream]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -559,6 +557,10 @@ static int omap_mcbsp_probe(struct snd_soc_dai *dai)
|
|||
|
||||
pm_runtime_enable(mcbsp->dev);
|
||||
|
||||
snd_soc_dai_init_dma_data(dai,
|
||||
&mcbsp->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
|
||||
&mcbsp->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -691,7 +693,7 @@ OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
|
|||
OMAP_MCBSP_ST_CONTROLS(2);
|
||||
OMAP_MCBSP_ST_CONTROLS(3);
|
||||
|
||||
int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
|
||||
int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id)
|
||||
{
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
|
@ -701,7 +703,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
switch (mcbsp->id) {
|
||||
switch (port_id) {
|
||||
case 2: /* McBSP 2 */
|
||||
return snd_soc_add_dai_controls(cpu_dai,
|
||||
omap_mcbsp2_st_controls,
|
||||
|
@ -711,6 +713,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
|
|||
omap_mcbsp3_st_controls,
|
||||
ARRAY_SIZE(omap_mcbsp3_st_controls));
|
||||
default:
|
||||
dev_err(mcbsp->dev, "Port %d not supported\n", port_id);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -799,11 +802,15 @@ static int asoc_mcbsp_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, mcbsp);
|
||||
|
||||
ret = omap_mcbsp_init(pdev);
|
||||
if (!ret)
|
||||
return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component,
|
||||
&omap_mcbsp_dai, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
ret = snd_soc_register_component(&pdev->dev, &omap_mcbsp_component,
|
||||
&omap_mcbsp_dai, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return omap_pcm_platform_register(&pdev->dev);
|
||||
}
|
||||
|
||||
static int asoc_mcbsp_remove(struct platform_device *pdev)
|
||||
|
|
|
@ -39,6 +39,6 @@ enum omap_mcbsp_div {
|
|||
OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
|
||||
};
|
||||
|
||||
int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
|
||||
int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "omap-mcpdm.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
struct mcpdm_link_config {
|
||||
u32 link_mask; /* channel mask for the direction */
|
||||
|
@ -265,9 +266,6 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
|
|||
}
|
||||
mutex_unlock(&mcpdm->mutex);
|
||||
|
||||
snd_soc_dai_set_dma_data(dai, substream,
|
||||
&mcpdm->dma_data[substream->stream]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -406,6 +404,11 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
|
|||
mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2;
|
||||
mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold =
|
||||
MCPDM_UP_THRES_MAX - 3;
|
||||
|
||||
snd_soc_dai_init_dma_data(dai,
|
||||
&mcpdm->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
|
||||
&mcpdm->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -460,6 +463,7 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct omap_mcpdm *mcpdm;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL);
|
||||
if (!mcpdm)
|
||||
|
@ -490,9 +494,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
|
|||
|
||||
mcpdm->dev = &pdev->dev;
|
||||
|
||||
return devm_snd_soc_register_component(&pdev->dev,
|
||||
ret = devm_snd_soc_register_component(&pdev->dev,
|
||||
&omap_mcpdm_component,
|
||||
&omap_mcpdm_dai, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return omap_pcm_platform_register(&pdev->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id omap_mcpdm_of_match[] = {
|
||||
|
|
|
@ -238,31 +238,6 @@ int omap_pcm_platform_register(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(omap_pcm_platform_register);
|
||||
|
||||
static int omap_pcm_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_platform(&pdev->dev,
|
||||
&omap_soc_platform);
|
||||
}
|
||||
|
||||
static int omap_pcm_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_platform(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver omap_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "omap-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
.probe = omap_pcm_probe,
|
||||
.remove = omap_pcm_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(omap_pcm_driver);
|
||||
|
||||
MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
|
||||
MODULE_DESCRIPTION("OMAP PCM DMA module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:omap-pcm-audio");
|
||||
|
|
|
@ -55,8 +55,7 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_card *card = codec->card;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
unsigned int fmt;
|
||||
int ret;
|
||||
|
||||
|
@ -179,7 +178,7 @@ static inline void twl4030_disconnect_pin(struct snd_soc_dapm_context *dapm,
|
|||
static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_card *card = codec->card;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
struct omap_tw4030_pdata *pdata = dev_get_platdata(card->dev);
|
||||
struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card);
|
||||
|
@ -239,7 +238,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = {
|
|||
.stream_name = "TWL4030 HiFi",
|
||||
.cpu_dai_name = "omap-mcbsp.2",
|
||||
.codec_dai_name = "twl4030-hifi",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.2",
|
||||
.codec_name = "twl4030-codec",
|
||||
.init = omap_twl4030_init,
|
||||
.ops = &omap_twl4030_ops,
|
||||
|
@ -249,7 +248,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = {
|
|||
.stream_name = "TWL4030 Voice",
|
||||
.cpu_dai_name = "omap-mcbsp.3",
|
||||
.codec_dai_name = "twl4030-voice",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.2",
|
||||
.codec_name = "twl4030-codec",
|
||||
.dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
|
@ -299,12 +298,18 @@ static int omap_twl4030_probe(struct platform_device *pdev)
|
|||
omap_twl4030_dai_links[0].cpu_dai_name = NULL;
|
||||
omap_twl4030_dai_links[0].cpu_of_node = dai_node;
|
||||
|
||||
omap_twl4030_dai_links[0].platform_name = NULL;
|
||||
omap_twl4030_dai_links[0].platform_of_node = dai_node;
|
||||
|
||||
dai_node = of_parse_phandle(node, "ti,mcbsp-voice", 0);
|
||||
if (!dai_node) {
|
||||
card->num_links = 1;
|
||||
} else {
|
||||
omap_twl4030_dai_links[1].cpu_dai_name = NULL;
|
||||
omap_twl4030_dai_links[1].cpu_of_node = dai_node;
|
||||
|
||||
omap_twl4030_dai_links[1].platform_name = NULL;
|
||||
omap_twl4030_dai_links[1].platform_of_node = dai_node;
|
||||
}
|
||||
|
||||
priv->jack_detect = of_get_named_gpio(node,
|
||||
|
|
|
@ -197,7 +197,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
|
|||
.stream_name = "HiFi Out",
|
||||
.cpu_dai_name = "omap-mcbsp.2",
|
||||
.codec_dai_name = "twl4030-hifi",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.2",
|
||||
.codec_name = "twl4030-codec",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
|
@ -208,7 +208,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
|
|||
.stream_name = "Line/Mic In",
|
||||
.cpu_dai_name = "omap-mcbsp.4",
|
||||
.codec_dai_name = "twl4030-hifi",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.4",
|
||||
.codec_name = "twl4030-codec",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
|
|
|
@ -96,7 +96,7 @@ static struct snd_soc_dai_link osk_dai = {
|
|||
.stream_name = "AIC23",
|
||||
.cpu_dai_name = "omap-mcbsp.1",
|
||||
.codec_dai_name = "tlv320aic23-hifi",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.1",
|
||||
.codec_name = "tlv320aic23-codec",
|
||||
.dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/jack.h>
|
||||
|
@ -38,15 +39,6 @@
|
|||
|
||||
#include "omap-mcbsp.h"
|
||||
|
||||
#define RX51_TVOUT_SEL_GPIO 40
|
||||
#define RX51_JACK_DETECT_GPIO 177
|
||||
#define RX51_ECI_SW_GPIO 182
|
||||
/*
|
||||
* REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
|
||||
* gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
|
||||
*/
|
||||
#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7)
|
||||
|
||||
enum {
|
||||
RX51_JACK_DISABLED,
|
||||
RX51_JACK_TVOUT, /* tv-out with stereo output */
|
||||
|
@ -54,12 +46,21 @@ enum {
|
|||
RX51_JACK_HS, /* headset: stereo output with mic */
|
||||
};
|
||||
|
||||
struct rx51_audio_pdata {
|
||||
struct gpio_desc *tvout_selection_gpio;
|
||||
struct gpio_desc *jack_detection_gpio;
|
||||
struct gpio_desc *eci_sw_gpio;
|
||||
struct gpio_desc *speaker_amp_gpio;
|
||||
};
|
||||
|
||||
static int rx51_spk_func;
|
||||
static int rx51_dmic_func;
|
||||
static int rx51_jack_func;
|
||||
|
||||
static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
struct snd_soc_card *card = dapm->card;
|
||||
struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
|
||||
int hp = 0, hs = 0, tvout = 0;
|
||||
|
||||
switch (rx51_jack_func) {
|
||||
|
@ -93,7 +94,7 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
|
|||
else
|
||||
snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic");
|
||||
|
||||
gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout);
|
||||
gpiod_set_value(pdata->tvout_selection_gpio, tvout);
|
||||
|
||||
snd_soc_dapm_sync_unlocked(dapm);
|
||||
|
||||
|
@ -154,10 +155,12 @@ static int rx51_set_spk(struct snd_kcontrol *kcontrol,
|
|||
static int rx51_spk_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
if (SND_SOC_DAPM_EVENT_ON(event))
|
||||
gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 1);
|
||||
else
|
||||
gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 0);
|
||||
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||
struct snd_soc_card *card = dapm->card;
|
||||
struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
|
||||
|
||||
gpiod_set_raw_value_cansleep(pdata->speaker_amp_gpio,
|
||||
!!SND_SOC_DAPM_EVENT_ON(event));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -223,7 +226,6 @@ static struct snd_soc_jack rx51_av_jack;
|
|||
|
||||
static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
|
||||
{
|
||||
.gpio = RX51_JACK_DETECT_GPIO,
|
||||
.name = "avdet-gpio",
|
||||
.report = SND_JACK_HEADSET,
|
||||
.invert = 1,
|
||||
|
@ -258,9 +260,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
|||
{"b Mic Bias", NULL, "HS Mic"}
|
||||
};
|
||||
|
||||
static const char *spk_function[] = {"Off", "On"};
|
||||
static const char *input_function[] = {"ADC", "Digital Mic"};
|
||||
static const char *jack_function[] = {"Off", "TV-OUT", "Headphone", "Headset"};
|
||||
static const char * const spk_function[] = {"Off", "On"};
|
||||
static const char * const input_function[] = {"ADC", "Digital Mic"};
|
||||
static const char * const jack_function[] = {
|
||||
"Off", "TV-OUT", "Headphone", "Headset"
|
||||
};
|
||||
|
||||
static const struct soc_enum rx51_enum[] = {
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
|
||||
|
@ -282,6 +286,9 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
|
|||
static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
|
||||
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
int err;
|
||||
|
||||
|
@ -291,23 +298,38 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
|
|||
snd_soc_dapm_nc_pin(dapm, "LINE1R");
|
||||
|
||||
err = tpa6130a2_add_controls(codec);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
|
||||
return err;
|
||||
}
|
||||
snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
|
||||
|
||||
err = omap_mcbsp_st_add_controls(rtd);
|
||||
if (err < 0)
|
||||
err = omap_mcbsp_st_add_controls(rtd, 2);
|
||||
if (err < 0) {
|
||||
dev_err(card->dev, "Failed to add MCBSP controls\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* AV jack detection */
|
||||
err = snd_soc_jack_new(codec, "AV Jack",
|
||||
SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
|
||||
&rx51_av_jack);
|
||||
if (err)
|
||||
if (err) {
|
||||
dev_err(card->dev, "Failed to add AV Jack\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* prepare gpio for snd_soc_jack_add_gpios */
|
||||
rx51_av_jack_gpios[0].gpio = desc_to_gpio(pdata->jack_detection_gpio);
|
||||
devm_gpiod_put(card->dev, pdata->jack_detection_gpio);
|
||||
|
||||
err = snd_soc_jack_add_gpios(&rx51_av_jack,
|
||||
ARRAY_SIZE(rx51_av_jack_gpios),
|
||||
rx51_av_jack_gpios);
|
||||
if (err) {
|
||||
dev_err(card->dev, "Failed to add GPIOs\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -319,7 +341,7 @@ static struct snd_soc_dai_link rx51_dai[] = {
|
|||
.stream_name = "AIC34",
|
||||
.cpu_dai_name = "omap-mcbsp.2",
|
||||
.codec_dai_name = "tlv320aic3x-hifi",
|
||||
.platform_name = "omap-pcm-audio",
|
||||
.platform_name = "omap-mcbsp.2",
|
||||
.codec_name = "tlv320aic3x-codec.2-0018",
|
||||
.dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
|
@ -361,61 +383,151 @@ static struct snd_soc_card rx51_sound_card = {
|
|||
.num_dapm_routes = ARRAY_SIZE(audio_map),
|
||||
};
|
||||
|
||||
static struct platform_device *rx51_snd_device;
|
||||
|
||||
static int __init rx51_soc_init(void)
|
||||
static int rx51_soc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rx51_audio_pdata *pdata;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct snd_soc_card *card = &rx51_sound_card;
|
||||
int err;
|
||||
|
||||
if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900"))
|
||||
return -ENODEV;
|
||||
|
||||
err = gpio_request_one(RX51_TVOUT_SEL_GPIO,
|
||||
GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel");
|
||||
if (err)
|
||||
goto err_gpio_tvout_sel;
|
||||
err = gpio_request_one(RX51_ECI_SW_GPIO,
|
||||
GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw");
|
||||
if (err)
|
||||
goto err_gpio_eci_sw;
|
||||
card->dev = &pdev->dev;
|
||||
|
||||
rx51_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!rx51_snd_device) {
|
||||
err = -ENOMEM;
|
||||
goto err1;
|
||||
if (np) {
|
||||
struct device_node *dai_node;
|
||||
|
||||
dai_node = of_parse_phandle(np, "nokia,cpu-dai", 0);
|
||||
if (!dai_node) {
|
||||
dev_err(&pdev->dev, "McBSP node is not provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rx51_dai[0].cpu_dai_name = NULL;
|
||||
rx51_dai[0].platform_name = NULL;
|
||||
rx51_dai[0].cpu_of_node = dai_node;
|
||||
rx51_dai[0].platform_of_node = dai_node;
|
||||
|
||||
dai_node = of_parse_phandle(np, "nokia,audio-codec", 0);
|
||||
if (!dai_node) {
|
||||
dev_err(&pdev->dev, "Codec node is not provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rx51_dai[0].codec_name = NULL;
|
||||
rx51_dai[0].codec_of_node = dai_node;
|
||||
|
||||
dai_node = of_parse_phandle(np, "nokia,audio-codec", 1);
|
||||
if (!dai_node) {
|
||||
dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rx51_aux_dev[0].codec_name = NULL;
|
||||
rx51_aux_dev[0].codec_of_node = dai_node;
|
||||
rx51_codec_conf[0].dev_name = NULL;
|
||||
rx51_codec_conf[0].of_node = dai_node;
|
||||
|
||||
dai_node = of_parse_phandle(np, "nokia,headphone-amplifier", 0);
|
||||
if (!dai_node) {
|
||||
dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: tpa6130a2a driver supports only a single instance, so
|
||||
* this driver ignores the headphone-amplifier node for now.
|
||||
* It's already mandatory in the DT binding to be future proof.
|
||||
*/
|
||||
}
|
||||
|
||||
platform_set_drvdata(rx51_snd_device, &rx51_sound_card);
|
||||
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (pdata == NULL) {
|
||||
dev_err(card->dev, "failed to create private data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
snd_soc_card_set_drvdata(card, pdata);
|
||||
|
||||
err = platform_device_add(rx51_snd_device);
|
||||
if (err)
|
||||
goto err2;
|
||||
pdata->tvout_selection_gpio = devm_gpiod_get(card->dev,
|
||||
"tvout-selection");
|
||||
if (IS_ERR(pdata->tvout_selection_gpio)) {
|
||||
dev_err(card->dev, "could not get tvout selection gpio\n");
|
||||
return PTR_ERR(pdata->tvout_selection_gpio);
|
||||
}
|
||||
|
||||
err = gpiod_direction_output(pdata->tvout_selection_gpio, 0);
|
||||
if (err) {
|
||||
dev_err(card->dev, "could not setup tvout selection gpio\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
pdata->jack_detection_gpio = devm_gpiod_get(card->dev,
|
||||
"jack-detection");
|
||||
if (IS_ERR(pdata->jack_detection_gpio)) {
|
||||
dev_err(card->dev, "could not get jack detection gpio\n");
|
||||
return PTR_ERR(pdata->jack_detection_gpio);
|
||||
}
|
||||
|
||||
pdata->eci_sw_gpio = devm_gpiod_get(card->dev, "eci-switch");
|
||||
if (IS_ERR(pdata->eci_sw_gpio)) {
|
||||
dev_err(card->dev, "could not get eci switch gpio\n");
|
||||
return PTR_ERR(pdata->eci_sw_gpio);
|
||||
}
|
||||
|
||||
err = gpiod_direction_output(pdata->eci_sw_gpio, 1);
|
||||
if (err) {
|
||||
dev_err(card->dev, "could not setup eci switch gpio\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
pdata->speaker_amp_gpio = devm_gpiod_get(card->dev,
|
||||
"speaker-amplifier");
|
||||
if (IS_ERR(pdata->speaker_amp_gpio)) {
|
||||
dev_err(card->dev, "could not get speaker enable gpio\n");
|
||||
return PTR_ERR(pdata->speaker_amp_gpio);
|
||||
}
|
||||
|
||||
err = gpiod_direction_output(pdata->speaker_amp_gpio, 0);
|
||||
if (err) {
|
||||
dev_err(card->dev, "could not setup speaker enable gpio\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = devm_snd_soc_register_card(card->dev, card);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err2:
|
||||
platform_device_put(rx51_snd_device);
|
||||
err1:
|
||||
gpio_free(RX51_ECI_SW_GPIO);
|
||||
err_gpio_eci_sw:
|
||||
gpio_free(RX51_TVOUT_SEL_GPIO);
|
||||
err_gpio_tvout_sel:
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit rx51_soc_exit(void)
|
||||
static int rx51_soc_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios),
|
||||
rx51_av_jack_gpios);
|
||||
|
||||
platform_device_unregister(rx51_snd_device);
|
||||
gpio_free(RX51_ECI_SW_GPIO);
|
||||
gpio_free(RX51_TVOUT_SEL_GPIO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(rx51_soc_init);
|
||||
module_exit(rx51_soc_exit);
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id rx51_audio_of_match[] = {
|
||||
{ .compatible = "nokia,n900-audio", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rx51_audio_of_match);
|
||||
#endif
|
||||
|
||||
static struct platform_driver rx51_soc_driver = {
|
||||
.driver = {
|
||||
.name = "rx51-audio",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(rx51_audio_of_match),
|
||||
},
|
||||
.probe = rx51_soc_probe,
|
||||
.remove = rx51_soc_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(rx51_soc_driver);
|
||||
|
||||
MODULE_AUTHOR("Nokia Corporation");
|
||||
MODULE_DESCRIPTION("ALSA SoC Nokia RX-51");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:rx51-audio");
|
||||
|
|
|
@ -140,7 +140,7 @@ config SND_PXA910_SOC
|
|||
|
||||
config SND_SOC_TTC_DKB
|
||||
bool "SoC Audio support for TTC DKB"
|
||||
depends on SND_PXA910_SOC && MACH_TTC_DKB
|
||||
depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y
|
||||
select PXA_SSP
|
||||
select SND_PXA_SOC_SSP
|
||||
select SND_MMP_SOC
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include <sound/pxa2xx-lib.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include "../../arm/pxa2xx-pcm.h"
|
||||
#include "pxa-ssp.h"
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <linux/dmaengine.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <mach/dma.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o
|
||||
snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o
|
||||
obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
|
|
@ -57,6 +57,24 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
|
|||
return (0x6 + ws) << 8;
|
||||
}
|
||||
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
int id = rsnd_mod_id(mod);
|
||||
int shift = (id % 2) ? 16 : 0;
|
||||
u32 mask, val;
|
||||
|
||||
val = rsnd_adg_ssi_ws_timing_gen2(io);
|
||||
|
||||
val = val << shift;
|
||||
mask = 0xffff << shift;
|
||||
|
||||
rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io,
|
||||
|
@ -397,9 +415,8 @@ int rsnd_adg_probe(struct platform_device *pdev,
|
|||
{
|
||||
struct rsnd_adg *adg;
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct clk *clk, *clk_orig;
|
||||
struct clk *clk;
|
||||
int i;
|
||||
bool use_old_style = false;
|
||||
|
||||
adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
|
||||
if (!adg) {
|
||||
|
@ -407,45 +424,13 @@ int rsnd_adg_probe(struct platform_device *pdev,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_orig = devm_clk_get(dev, NULL);
|
||||
adg->clk[CLKA] = devm_clk_get(dev, "clk_a");
|
||||
adg->clk[CLKB] = devm_clk_get(dev, "clk_b");
|
||||
adg->clk[CLKC] = devm_clk_get(dev, "clk_c");
|
||||
adg->clk[CLKI] = devm_clk_get(dev, "clk_i");
|
||||
|
||||
/*
|
||||
* It request device dependent audio clock.
|
||||
* But above all clks will indicate rsnd module clock
|
||||
* if platform doesn't it
|
||||
*/
|
||||
for_each_rsnd_clk(clk, adg, i) {
|
||||
if (clk_orig == clk) {
|
||||
dev_warn(dev,
|
||||
"doesn't have device dependent clock, use independent clock\n");
|
||||
use_old_style = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* note:
|
||||
* these exist in order to keep compatible with
|
||||
* platform which has device independent audio clock,
|
||||
* but will be removed soon
|
||||
*/
|
||||
if (use_old_style) {
|
||||
adg->clk[CLKA] = devm_clk_get(NULL, "audio_clk_a");
|
||||
adg->clk[CLKB] = devm_clk_get(NULL, "audio_clk_b");
|
||||
adg->clk[CLKC] = devm_clk_get(NULL, "audio_clk_c");
|
||||
adg->clk[CLKI] = devm_clk_get(NULL, "audio_clk_internal");
|
||||
}
|
||||
|
||||
for_each_rsnd_clk(clk, adg, i) {
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "Audio clock failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
for_each_rsnd_clk(clk, adg, i)
|
||||
dev_dbg(dev, "clk %d : %p\n", i, clk);
|
||||
|
||||
rsnd_adg_ssi_clk_init(priv, adg);
|
||||
|
||||
|
|
|
@ -308,24 +308,50 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
|
|||
dma->chan = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* settting function
|
||||
*/
|
||||
u32 rsnd_get_adinr(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
u32 adinr = runtime->channels;
|
||||
|
||||
switch (runtime->sample_bits) {
|
||||
case 16:
|
||||
adinr |= (8 << 16);
|
||||
break;
|
||||
case 32:
|
||||
adinr |= (0 << 16);
|
||||
break;
|
||||
default:
|
||||
dev_warn(dev, "not supported sample bits\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return adinr;
|
||||
}
|
||||
|
||||
/*
|
||||
* rsnd_dai functions
|
||||
*/
|
||||
#define __rsnd_mod_call(mod, func, rdai, io) \
|
||||
#define __rsnd_mod_call(mod, func, rdai...) \
|
||||
({ \
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
|
||||
struct device *dev = rsnd_priv_to_dev(priv); \
|
||||
dev_dbg(dev, "%s [%d] %s\n", \
|
||||
rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \
|
||||
(mod)->ops->func(mod, rdai, io); \
|
||||
(mod)->ops->func(mod, rdai); \
|
||||
})
|
||||
|
||||
#define rsnd_mod_call(mod, func, rdai, io) \
|
||||
#define rsnd_mod_call(mod, func, rdai...) \
|
||||
(!(mod) ? -ENODEV : \
|
||||
!((mod)->ops->func) ? 0 : \
|
||||
__rsnd_mod_call(mod, func, (rdai), (io)))
|
||||
__rsnd_mod_call(mod, func, rdai))
|
||||
|
||||
#define rsnd_dai_call(rdai, io, fn) \
|
||||
#define rsnd_dai_call(fn, io, rdai...) \
|
||||
({ \
|
||||
struct rsnd_mod *mod; \
|
||||
int ret = 0, i; \
|
||||
|
@ -333,7 +359,7 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
|
|||
mod = (io)->mod[i]; \
|
||||
if (!mod) \
|
||||
continue; \
|
||||
ret = rsnd_mod_call(mod, fn, (rdai), (io)); \
|
||||
ret = rsnd_mod_call(mod, fn, rdai); \
|
||||
if (ret < 0) \
|
||||
break; \
|
||||
} \
|
||||
|
@ -467,10 +493,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
|
||||
struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
|
||||
struct rsnd_mod *mod = rsnd_ssi_mod_get_frm_dai(priv,
|
||||
rsnd_dai_id(priv, rdai),
|
||||
rsnd_dai_is_play(rdai, io));
|
||||
int ssi_id = rsnd_mod_id(mod);
|
||||
int ssi_id = rsnd_mod_id(rsnd_io_to_mod_ssi(io));
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -486,20 +509,20 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(rdai, io, init);
|
||||
ret = rsnd_dai_call(init, io, rdai);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(rdai, io, start);
|
||||
ret = rsnd_dai_call(start, io, rdai);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
ret = rsnd_dai_call(rdai, io, stop);
|
||||
ret = rsnd_dai_call(stop, io, rdai);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(rdai, io, quit);
|
||||
ret = rsnd_dai_call(quit, io, rdai);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
|
@ -578,15 +601,27 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
|
|||
.set_fmt = rsnd_soc_dai_set_fmt,
|
||||
};
|
||||
|
||||
#define rsnd_path_parse(priv, io, type) \
|
||||
({ \
|
||||
struct rsnd_mod *mod; \
|
||||
int ret = 0; \
|
||||
int id = -1; \
|
||||
\
|
||||
if (rsnd_is_enable_path(io, type)) { \
|
||||
id = rsnd_info_id(priv, io, type); \
|
||||
if (id >= 0) { \
|
||||
mod = rsnd_##type##_mod_get(priv, id); \
|
||||
ret = rsnd_dai_connect(mod, io); \
|
||||
} \
|
||||
} \
|
||||
ret; \
|
||||
})
|
||||
|
||||
static int rsnd_path_init(struct rsnd_priv *priv,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
struct rsnd_mod *mod;
|
||||
struct rsnd_dai_platform_info *dai_info = rdai->info;
|
||||
int ret;
|
||||
int ssi_id = -1;
|
||||
int src_id = -1;
|
||||
|
||||
/*
|
||||
* Gen1 is created by SRU/SSI, and this SRU is base module of
|
||||
|
@ -598,38 +633,21 @@ static int rsnd_path_init(struct rsnd_priv *priv,
|
|||
* Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
|
||||
* using fixed path.
|
||||
*/
|
||||
if (dai_info) {
|
||||
if (rsnd_is_enable_path(io, ssi))
|
||||
ssi_id = rsnd_info_id(priv, io, ssi);
|
||||
if (rsnd_is_enable_path(io, src))
|
||||
src_id = rsnd_info_id(priv, io, src);
|
||||
} else {
|
||||
/* get SSI's ID */
|
||||
mod = rsnd_ssi_mod_get_frm_dai(priv,
|
||||
rsnd_dai_id(priv, rdai),
|
||||
rsnd_dai_is_play(rdai, io));
|
||||
if (!mod)
|
||||
return 0;
|
||||
ssi_id = src_id = rsnd_mod_id(mod);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
/* SRC */
|
||||
if (src_id >= 0) {
|
||||
mod = rsnd_src_mod_get(priv, src_id);
|
||||
ret = rsnd_dai_connect(mod, io);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = rsnd_path_parse(priv, io, src);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* SSI */
|
||||
if (ssi_id >= 0) {
|
||||
mod = rsnd_ssi_mod_get(priv, ssi_id);
|
||||
ret = rsnd_dai_connect(mod, io);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = rsnd_path_parse(priv, io, ssi);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* DVC */
|
||||
ret = rsnd_path_parse(priv, io, dvc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -725,29 +743,14 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
|||
struct snd_soc_dai_driver *drv;
|
||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||
struct rsnd_dai *rdai;
|
||||
struct rsnd_mod *pmod, *cmod;
|
||||
struct rsnd_ssi_platform_info *pmod, *cmod;
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int dai_nr;
|
||||
int i;
|
||||
|
||||
rsnd_of_parse_dai(pdev, of_data, priv);
|
||||
|
||||
/*
|
||||
* dai_nr should be set via dai_info_nr,
|
||||
* but allow it to keeping compatible
|
||||
*/
|
||||
dai_nr = info->dai_info_nr;
|
||||
if (!dai_nr) {
|
||||
/* get max dai nr */
|
||||
for (dai_nr = 0; dai_nr < 32; dai_nr++) {
|
||||
pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1);
|
||||
cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0);
|
||||
|
||||
if (!pmod && !cmod)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dai_nr) {
|
||||
dev_err(dev, "no dai\n");
|
||||
return -EIO;
|
||||
|
@ -765,11 +768,10 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
|||
priv->rdai = rdai;
|
||||
|
||||
for (i = 0; i < dai_nr; i++) {
|
||||
if (info->dai_info)
|
||||
rdai[i].info = &info->dai_info[i];
|
||||
rdai[i].info = &info->dai_info[i];
|
||||
|
||||
pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1);
|
||||
cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0);
|
||||
pmod = rdai[i].info->playback.ssi;
|
||||
cmod = rdai[i].info->capture.ssi;
|
||||
|
||||
/*
|
||||
* init rsnd_dai
|
||||
|
@ -787,8 +789,7 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
|||
drv[i].playback.channels_min = 2;
|
||||
drv[i].playback.channels_max = 2;
|
||||
|
||||
if (info->dai_info)
|
||||
rdai[i].playback.info = &info->dai_info[i].playback;
|
||||
rdai[i].playback.info = &info->dai_info[i].playback;
|
||||
rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
|
||||
}
|
||||
if (cmod) {
|
||||
|
@ -797,8 +798,7 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
|||
drv[i].capture.channels_min = 2;
|
||||
drv[i].capture.channels_max = 2;
|
||||
|
||||
if (info->dai_info)
|
||||
rdai[i].capture.info = &info->dai_info[i].capture;
|
||||
rdai[i].capture.info = &info->dai_info[i].capture;
|
||||
rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
|
||||
}
|
||||
|
||||
|
@ -873,6 +873,20 @@ static struct snd_pcm_ops rsnd_pcm_ops = {
|
|||
|
||||
static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct rsnd_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
|
||||
struct rsnd_dai *rdai;
|
||||
int i, ret;
|
||||
|
||||
for_each_rsnd_dai(rdai, priv, i) {
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return snd_pcm_lib_preallocate_pages_for_all(
|
||||
rtd->pcm,
|
||||
SNDRV_DMA_TYPE_DEV,
|
||||
|
@ -912,6 +926,7 @@ static int rsnd_probe(struct platform_device *pdev)
|
|||
rsnd_gen_probe,
|
||||
rsnd_ssi_probe,
|
||||
rsnd_src_probe,
|
||||
rsnd_dvc_probe,
|
||||
rsnd_adg_probe,
|
||||
rsnd_dai_probe,
|
||||
};
|
||||
|
@ -955,11 +970,11 @@ static int rsnd_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
for_each_rsnd_dai(rdai, priv, i) {
|
||||
ret = rsnd_dai_call(rdai, &rdai->playback, probe);
|
||||
ret = rsnd_dai_call(probe, &rdai->playback, rdai);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_dai_call(rdai, &rdai->capture, probe);
|
||||
ret = rsnd_dai_call(probe, &rdai->capture, rdai);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1002,11 +1017,11 @@ static int rsnd_remove(struct platform_device *pdev)
|
|||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
for_each_rsnd_dai(rdai, priv, i) {
|
||||
ret = rsnd_dai_call(rdai, &rdai->playback, remove);
|
||||
ret = rsnd_dai_call(remove, &rdai->playback, rdai);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_dai_call(rdai, &rdai->capture, remove);
|
||||
ret = rsnd_dai_call(remove, &rdai->capture, rdai);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Renesas R-Car DVC support
|
||||
*
|
||||
* Copyright (C) 2014 Renesas Solutions Corp.
|
||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.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.
|
||||
*/
|
||||
#include "rsnd.h"
|
||||
|
||||
#define RSND_DVC_NAME_SIZE 16
|
||||
#define RSND_DVC_VOLUME_MAX 100
|
||||
#define RSND_DVC_VOLUME_NUM 2
|
||||
struct rsnd_dvc {
|
||||
struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
|
||||
struct rsnd_mod mod;
|
||||
struct clk *clk;
|
||||
long volume[RSND_DVC_VOLUME_NUM];
|
||||
};
|
||||
|
||||
#define rsnd_mod_to_dvc(_mod) \
|
||||
container_of((_mod), struct rsnd_dvc, mod)
|
||||
|
||||
#define for_each_rsnd_dvc(pos, priv, i) \
|
||||
for ((i) = 0; \
|
||||
((i) < rsnd_dvc_nr(priv)) && \
|
||||
((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
|
||||
i++)
|
||||
|
||||
static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
u32 max = (0x00800000 - 1);
|
||||
u32 vol[RSND_DVC_VOLUME_NUM];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++)
|
||||
vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i];
|
||||
|
||||
rsnd_mod_write(mod, DVC_VOL0R, vol[0]);
|
||||
rsnd_mod_write(mod, DVC_VOL1R, vol[1]);
|
||||
}
|
||||
|
||||
static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(dvc_mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(dvc_mod);
|
||||
struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int dvc_id = rsnd_mod_id(dvc_mod);
|
||||
int src_id = rsnd_mod_id(src_mod);
|
||||
u32 route[] = {
|
||||
[0] = 0x30000,
|
||||
[1] = 0x30001,
|
||||
[2] = 0x40000,
|
||||
[3] = 0x10000,
|
||||
[4] = 0x20000,
|
||||
[5] = 0x40100
|
||||
};
|
||||
|
||||
if (src_id >= ARRAY_SIZE(route)) {
|
||||
dev_err(dev, "DVC%d isn't connected to SRC%d\n", dvc_id, src_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
clk_prepare_enable(dvc->clk);
|
||||
|
||||
/*
|
||||
* fixme
|
||||
* it doesn't support CTU/MIX
|
||||
*/
|
||||
rsnd_mod_write(dvc_mod, CMD_ROUTE_SLCT, route[src_id]);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_SWRSR, 0);
|
||||
rsnd_mod_write(dvc_mod, DVC_SWRSR, 1);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUIR, 1);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod));
|
||||
|
||||
/* enable Volume */
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x100);
|
||||
|
||||
/* ch0/ch1 Volume */
|
||||
rsnd_dvc_volume_update(dvc_mod);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUER, 1);
|
||||
|
||||
rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_quit(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
|
||||
clk_disable_unprepare(dvc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
rsnd_mod_write(mod, CMD_CTRL, 0x10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
rsnd_mod_write(mod, CMD_CTRL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = RSND_DVC_VOLUME_NUM;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = RSND_DVC_VOLUME_MAX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++)
|
||||
ucontrol->value.integer.value[i] = dvc->volume[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
int i, change = 0;
|
||||
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) {
|
||||
if (ucontrol->value.integer.value[i] < 0 ||
|
||||
ucontrol->value.integer.value[i] > RSND_DVC_VOLUME_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
change |= (ucontrol->value.integer.value[i] != dvc->volume[i]);
|
||||
}
|
||||
|
||||
if (change) {
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++)
|
||||
dvc->volume[i] = ucontrol->value.integer.value[i];
|
||||
|
||||
rsnd_dvc_volume_update(mod);
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct snd_card *card = rtd->card->snd_card;
|
||||
struct snd_kcontrol *kctrl;
|
||||
static struct snd_kcontrol_new knew = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Playback Volume",
|
||||
.info = rsnd_dvc_volume_info,
|
||||
.get = rsnd_dvc_volume_get,
|
||||
.put = rsnd_dvc_volume_put,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!rsnd_dai_is_play(rdai, io)) {
|
||||
dev_err(dev, "DVC%d is connected to Capture DAI\n",
|
||||
rsnd_mod_id(mod));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kctrl = snd_ctl_new1(&knew, mod);
|
||||
if (!kctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = snd_ctl_add(card, kctrl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rsnd_mod_ops rsnd_dvc_ops = {
|
||||
.name = "dvc (gen2)",
|
||||
.init = rsnd_dvc_init,
|
||||
.quit = rsnd_dvc_quit,
|
||||
.start = rsnd_dvc_start,
|
||||
.stop = rsnd_dvc_stop,
|
||||
.pcm_new = rsnd_dvc_pcm_new,
|
||||
};
|
||||
|
||||
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
|
||||
{
|
||||
if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
|
||||
id = 0;
|
||||
|
||||
return &((struct rsnd_dvc *)(priv->dvc) + id)->mod;
|
||||
}
|
||||
|
||||
int rsnd_dvc_probe(struct platform_device *pdev,
|
||||
const struct rsnd_of_data *of_data,
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct rsnd_dvc *dvc;
|
||||
struct clk *clk;
|
||||
char name[RSND_DVC_NAME_SIZE];
|
||||
int i, nr;
|
||||
|
||||
nr = info->dvc_info_nr;
|
||||
if (!nr)
|
||||
return 0;
|
||||
|
||||
/* This driver doesn't support Gen1 at this point */
|
||||
if (rsnd_is_gen1(priv)) {
|
||||
dev_warn(dev, "CMD is not supported on Gen1\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
|
||||
if (!dvc) {
|
||||
dev_err(dev, "CMD allocate failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->dvc_nr = nr;
|
||||
priv->dvc = dvc;
|
||||
|
||||
for_each_rsnd_dvc(dvc, priv, i) {
|
||||
snprintf(name, RSND_DVC_NAME_SIZE, "dvc.%d", i);
|
||||
|
||||
clk = devm_clk_get(dev, name);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
dvc->info = &info->dvc_info[i];
|
||||
dvc->clk = clk;
|
||||
|
||||
rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, RSND_MOD_DVC, i);
|
||||
|
||||
dev_dbg(dev, "CMD%d probed\n", i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -181,6 +181,8 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
|
|||
RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, CMD_ROUTE_SLCT, 0x18c, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, CMD_CTRL, 0x190, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40),
|
||||
|
@ -189,6 +191,14 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
|
|||
RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_SWRSR, 0xe00, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_DVUIR, 0xe04, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_ADINR, 0xe08, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_DVUCR, 0xe10, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_ZCMCR, 0xe14, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_VOL0R, 0xe28, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_VOL1R, 0xe2c, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_DVUER, 0xe48, 0x100),
|
||||
|
||||
RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00),
|
||||
RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04),
|
||||
|
@ -207,6 +217,7 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
|
|||
RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50),
|
||||
RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54),
|
||||
RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58),
|
||||
RSND_GEN2_S_REG(gen, ADG, CMDOUT_TIMSEL, 0x5c),
|
||||
|
||||
RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40),
|
||||
|
@ -252,13 +263,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
|
|||
return ret;
|
||||
|
||||
dev_dbg(dev, "Gen2 device probed\n");
|
||||
dev_dbg(dev, "SCU : %08x => %p\n", scu_res->start,
|
||||
dev_dbg(dev, "SCU : %pap => %p\n", &scu_res->start,
|
||||
gen->base[RSND_GEN2_SCU]);
|
||||
dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start,
|
||||
dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start,
|
||||
gen->base[RSND_GEN2_ADG]);
|
||||
dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start,
|
||||
dev_dbg(dev, "SSIU : %pap => %p\n", &ssiu_res->start,
|
||||
gen->base[RSND_GEN2_SSIU]);
|
||||
dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start,
|
||||
dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start,
|
||||
gen->base[RSND_GEN2_SSI]);
|
||||
|
||||
return 0;
|
||||
|
@ -345,11 +356,11 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
|
|||
return ret;
|
||||
|
||||
dev_dbg(dev, "Gen1 device probed\n");
|
||||
dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start,
|
||||
dev_dbg(dev, "SRU : %pap => %p\n", &sru_res->start,
|
||||
gen->base[RSND_GEN1_SRU]);
|
||||
dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start,
|
||||
dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start,
|
||||
gen->base[RSND_GEN1_ADG]);
|
||||
dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start,
|
||||
dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start,
|
||||
gen->base[RSND_GEN1_SSI]);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -44,6 +44,15 @@ enum rsnd_reg {
|
|||
RSND_REG_SRC_IFSCR,
|
||||
RSND_REG_SRC_IFSVR,
|
||||
RSND_REG_SRC_SRCCR,
|
||||
RSND_REG_CMD_ROUTE_SLCT,
|
||||
RSND_REG_DVC_SWRSR,
|
||||
RSND_REG_DVC_DVUIR,
|
||||
RSND_REG_DVC_ADINR,
|
||||
RSND_REG_DVC_DVUCR,
|
||||
RSND_REG_DVC_ZCMCR,
|
||||
RSND_REG_DVC_VOL0R,
|
||||
RSND_REG_DVC_VOL1R,
|
||||
RSND_REG_DVC_DVUER,
|
||||
|
||||
/* ADG */
|
||||
RSND_REG_BRRA,
|
||||
|
@ -79,6 +88,8 @@ enum rsnd_reg {
|
|||
RSND_REG_SHARE17,
|
||||
RSND_REG_SHARE18,
|
||||
RSND_REG_SHARE19,
|
||||
RSND_REG_SHARE20,
|
||||
RSND_REG_SHARE21,
|
||||
|
||||
RSND_REG_MAX,
|
||||
};
|
||||
|
@ -114,6 +125,8 @@ enum rsnd_reg {
|
|||
#define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17
|
||||
#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18
|
||||
#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
|
||||
#define RSND_REG_CMD_CTRL RSND_REG_SHARE20
|
||||
#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
|
||||
|
||||
struct rsnd_of_data;
|
||||
struct rsnd_priv;
|
||||
|
@ -136,6 +149,7 @@ void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
|
|||
enum rsnd_reg reg, u32 data);
|
||||
void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
|
||||
u32 mask, u32 data);
|
||||
u32 rsnd_get_adinr(struct rsnd_mod *mod);
|
||||
|
||||
/*
|
||||
* R-Car DMA
|
||||
|
@ -165,29 +179,27 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
|
|||
enum rsnd_mod_type {
|
||||
RSND_MOD_SRC = 0,
|
||||
RSND_MOD_SSI,
|
||||
RSND_MOD_DVC,
|
||||
RSND_MOD_MAX,
|
||||
};
|
||||
|
||||
struct rsnd_mod_ops {
|
||||
char *name;
|
||||
int (*probe)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
int (*remove)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
int (*init)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
int (*quit)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
int (*start)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
int (*stop)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
int (*pcm_new)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd);
|
||||
};
|
||||
|
||||
struct rsnd_dai_stream;
|
||||
|
@ -228,6 +240,7 @@ struct rsnd_dai_stream {
|
|||
};
|
||||
#define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI])
|
||||
#define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC])
|
||||
#define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC])
|
||||
|
||||
struct rsnd_dai {
|
||||
char name[RSND_DAI_NAME_SIZE];
|
||||
|
@ -291,6 +304,9 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
|
|||
int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io);
|
||||
|
||||
/*
|
||||
* R-Car sound priv
|
||||
|
@ -327,6 +343,12 @@ struct rsnd_priv {
|
|||
void *ssi;
|
||||
int ssi_nr;
|
||||
|
||||
/*
|
||||
* below value will be filled on rsnd_dvc_probe()
|
||||
*/
|
||||
void *dvc;
|
||||
int dvc_nr;
|
||||
|
||||
/*
|
||||
* below value will be filled on rsnd_dai_probe()
|
||||
*/
|
||||
|
@ -364,11 +386,9 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
|
|||
struct rsnd_dai_stream *io,
|
||||
struct snd_pcm_runtime *runtime);
|
||||
int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
struct rsnd_dai *rdai);
|
||||
|
||||
#define rsnd_src_nr(priv) ((priv)->src_nr)
|
||||
|
||||
|
@ -379,9 +399,19 @@ int rsnd_ssi_probe(struct platform_device *pdev,
|
|||
const struct rsnd_of_data *of_data,
|
||||
struct rsnd_priv *priv);
|
||||
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
|
||||
struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
|
||||
int dai_id, int is_play);
|
||||
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
|
||||
int rsnd_ssi_is_play(struct rsnd_mod *mod);
|
||||
|
||||
/*
|
||||
* R-Car DVC
|
||||
*/
|
||||
int rsnd_dvc_probe(struct platform_device *pdev,
|
||||
const struct rsnd_of_data *of_data,
|
||||
struct rsnd_priv *priv);
|
||||
void rsnd_dvc_remove(struct platform_device *pdev,
|
||||
struct rsnd_priv *priv);
|
||||
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
|
||||
|
||||
#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,21 +18,9 @@ struct rsnd_src {
|
|||
|
||||
#define RSND_SRC_NAME_SIZE 16
|
||||
|
||||
/*
|
||||
* ADINR
|
||||
*/
|
||||
#define OTBL_24 (0 << 16)
|
||||
#define OTBL_22 (2 << 16)
|
||||
#define OTBL_20 (4 << 16)
|
||||
#define OTBL_18 (6 << 16)
|
||||
#define OTBL_16 (8 << 16)
|
||||
|
||||
#define rsnd_src_mode_flags(p) ((p)->info->flags)
|
||||
#define rsnd_src_convert_rate(p) ((p)->info->convert_rate)
|
||||
#define rsnd_mod_to_src(_mod) \
|
||||
container_of((_mod), struct rsnd_src, mod)
|
||||
#define rsnd_src_hpbif_is_enable(src) \
|
||||
(rsnd_src_mode_flags(src) & RSND_SCU_USE_HPBIF)
|
||||
#define rsnd_src_dma_available(src) \
|
||||
rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod))
|
||||
|
||||
|
@ -80,34 +68,35 @@ struct rsnd_src {
|
|||
*
|
||||
* This driver request
|
||||
* struct rsnd_src_platform_info {
|
||||
* u32 flags;
|
||||
* u32 convert_rate;
|
||||
* int dma_id;
|
||||
* }
|
||||
*
|
||||
* rsnd_src_hpbif_is_enable() will be true
|
||||
* if flags had RSND_SRC_USE_HPBIF,
|
||||
* and it controls whether SSIU is used or not.
|
||||
*
|
||||
* rsnd_src_convert_rate() indicates
|
||||
* above convert_rate, and it controls
|
||||
* whether SRC is used or not.
|
||||
*
|
||||
* ex) doesn't use SRC
|
||||
* struct rsnd_src_platform_info info = {
|
||||
* .flags = 0,
|
||||
* .convert_rate = 0,
|
||||
* static struct rsnd_dai_platform_info rsnd_dai = {
|
||||
* .playback = { .ssi = &rsnd_ssi[0], },
|
||||
* };
|
||||
*
|
||||
* ex) uses SRC
|
||||
* struct rsnd_src_platform_info info = {
|
||||
* .flags = RSND_SRC_USE_HPBIF,
|
||||
* .convert_rate = 48000,
|
||||
* static struct rsnd_src_platform_info rsnd_src[] = {
|
||||
* RSND_SCU(48000, 0),
|
||||
* ...
|
||||
* };
|
||||
* static struct rsnd_dai_platform_info rsnd_dai = {
|
||||
* .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
|
||||
* };
|
||||
*
|
||||
* ex) uses SRC bypass mode
|
||||
* struct rsnd_src_platform_info info = {
|
||||
* .flags = RSND_SRC_USE_HPBIF,
|
||||
* .convert_rate = 0,
|
||||
* static struct rsnd_src_platform_info rsnd_src[] = {
|
||||
* RSND_SCU(0, 0),
|
||||
* ...
|
||||
* };
|
||||
* static struct rsnd_dai_platform_info rsnd_dai = {
|
||||
* .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
|
||||
* };
|
||||
*
|
||||
*/
|
||||
|
@ -116,27 +105,17 @@ struct rsnd_src {
|
|||
* Gen1/Gen2 common functions
|
||||
*/
|
||||
int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod);
|
||||
struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
|
||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||
int ssi_id = rsnd_mod_id(ssi_mod);
|
||||
int has_src = 0;
|
||||
|
||||
/*
|
||||
* SSI_MODE0
|
||||
*/
|
||||
if (info->dai_info) {
|
||||
has_src = !!src_mod;
|
||||
} else {
|
||||
struct rsnd_src *src = rsnd_mod_to_src(src_mod);
|
||||
has_src = rsnd_src_hpbif_is_enable(src);
|
||||
}
|
||||
|
||||
rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
|
||||
has_src ? 0 : (1 << ssi_id));
|
||||
src_mod ? 0 : (1 << ssi_id));
|
||||
|
||||
/*
|
||||
* SSI_MODE1
|
||||
|
@ -166,8 +145,7 @@ int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
|
|||
}
|
||||
|
||||
int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
|
||||
|
||||
|
@ -203,13 +181,12 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
|
|||
}
|
||||
|
||||
static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
u32 convert_rate = rsnd_src_convert_rate(src);
|
||||
u32 adinr = runtime->channels;
|
||||
u32 fsrate = 0;
|
||||
|
||||
if (convert_rate)
|
||||
|
@ -226,17 +203,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
|
|||
rsnd_mod_write(mod, SRC_SRCIR, 1);
|
||||
|
||||
/* Set channel number and output bit length */
|
||||
switch (runtime->sample_bits) {
|
||||
case 16:
|
||||
adinr |= OTBL_16;
|
||||
break;
|
||||
case 32:
|
||||
adinr |= OTBL_24;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
rsnd_mod_write(mod, SRC_ADINR, adinr);
|
||||
rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod));
|
||||
|
||||
/* Enable the initial value of IFS */
|
||||
if (fsrate) {
|
||||
|
@ -253,8 +220,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_init(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
|
||||
|
@ -264,8 +230,7 @@ static int rsnd_src_init(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_quit(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
|
||||
|
@ -275,8 +240,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
|
||||
|
@ -294,8 +258,7 @@ static int rsnd_src_start(struct rsnd_mod *mod,
|
|||
|
||||
|
||||
static int rsnd_src_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
|
||||
|
@ -313,9 +276,9 @@ static struct rsnd_mod_ops rsnd_src_non_ops = {
|
|||
* Gen1 functions
|
||||
*/
|
||||
static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct src_route_config {
|
||||
u32 mask;
|
||||
int shift;
|
||||
|
@ -351,9 +314,9 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
|
@ -410,12 +373,11 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rsnd_src_set_convert_rate(mod, rdai, io);
|
||||
ret = rsnd_src_set_convert_rate(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -432,24 +394,23 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_init_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rsnd_src_init(mod, rdai, io);
|
||||
ret = rsnd_src_init(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_route_gen1(mod, rdai, io);
|
||||
ret = rsnd_src_set_route_gen1(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_rate_gen1(mod, rdai, io);
|
||||
ret = rsnd_src_set_convert_rate_gen1(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_timing_gen1(mod, rdai, io);
|
||||
ret = rsnd_src_set_convert_timing_gen1(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -457,25 +418,23 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_start_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
int id = rsnd_mod_id(mod);
|
||||
|
||||
rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
|
||||
|
||||
return rsnd_src_start(mod, rdai, io);
|
||||
return rsnd_src_start(mod, rdai);
|
||||
}
|
||||
|
||||
static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
int id = rsnd_mod_id(mod);
|
||||
|
||||
rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
|
||||
|
||||
return rsnd_src_stop(mod, rdai, io);
|
||||
return rsnd_src_stop(mod, rdai);
|
||||
}
|
||||
|
||||
static struct rsnd_mod_ops rsnd_src_gen1_ops = {
|
||||
|
@ -490,17 +449,16 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = {
|
|||
* Gen2 functions
|
||||
*/
|
||||
static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rsnd_src_set_convert_rate(mod, rdai, io);
|
||||
ret = rsnd_src_set_convert_rate(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR));
|
||||
rsnd_mod_write(mod, SSI_BUSIF_MODE, rsnd_mod_read(mod, SRC_BUSIF_MODE));
|
||||
rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_get_adinr(mod));
|
||||
rsnd_mod_write(mod, SSI_BUSIF_MODE, 1);
|
||||
|
||||
rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);
|
||||
|
||||
|
@ -511,9 +469,9 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
u32 convert_rate = rsnd_src_convert_rate(src);
|
||||
|
@ -530,25 +488,16 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, rsnd_mod_id(mod));
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int ret;
|
||||
int is_play;
|
||||
|
||||
if (info->dai_info)
|
||||
is_play = rsnd_info_is_playback(priv, src);
|
||||
else
|
||||
is_play = rsnd_ssi_is_play(ssi);
|
||||
|
||||
ret = rsnd_dma_init(priv,
|
||||
rsnd_mod_to_dma(mod),
|
||||
is_play,
|
||||
rsnd_info_is_playback(priv, src),
|
||||
src->info->dma_id);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "SRC DMA failed\n");
|
||||
|
@ -557,8 +506,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
|
||||
|
||||
|
@ -566,20 +514,19 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_init_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rsnd_src_init(mod, rdai, io);
|
||||
ret = rsnd_src_init(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_rate_gen2(mod, rdai, io);
|
||||
ret = rsnd_src_set_convert_rate_gen2(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_src_set_convert_timing_gen2(mod, rdai, io);
|
||||
ret = rsnd_src_set_convert_timing_gen2(mod, rdai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -587,22 +534,22 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_src_start_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;
|
||||
|
||||
rsnd_dma_start(rsnd_mod_to_dma(&src->mod));
|
||||
|
||||
rsnd_mod_write(mod, SSI_CTRL, 0x1);
|
||||
rsnd_mod_write(mod, SRC_CTRL, 0x11);
|
||||
rsnd_mod_write(mod, SRC_CTRL, val);
|
||||
|
||||
return rsnd_src_start(mod, rdai, io);
|
||||
return rsnd_src_start(mod, rdai);
|
||||
}
|
||||
|
||||
static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
|
||||
|
@ -611,7 +558,7 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
|
|||
|
||||
rsnd_dma_stop(rsnd_mod_to_dma(&src->mod));
|
||||
|
||||
return rsnd_src_stop(mod, rdai, io);
|
||||
return rsnd_src_stop(mod, rdai);
|
||||
}
|
||||
|
||||
static struct rsnd_mod_ops rsnd_src_gen2_ops = {
|
||||
|
@ -699,11 +646,6 @@ int rsnd_src_probe(struct platform_device *pdev,
|
|||
snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i);
|
||||
|
||||
clk = devm_clk_get(dev, name);
|
||||
if (IS_ERR(clk)) {
|
||||
snprintf(name, RSND_SRC_NAME_SIZE, "scu.%d", i);
|
||||
clk = devm_clk_get(dev, name);
|
||||
}
|
||||
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
|
@ -711,12 +653,10 @@ int rsnd_src_probe(struct platform_device *pdev,
|
|||
src->clk = clk;
|
||||
|
||||
ops = &rsnd_src_non_ops;
|
||||
if (rsnd_src_hpbif_is_enable(src)) {
|
||||
if (rsnd_is_gen1(priv))
|
||||
ops = &rsnd_src_gen1_ops;
|
||||
if (rsnd_is_gen2(priv))
|
||||
ops = &rsnd_src_gen2_ops;
|
||||
}
|
||||
if (rsnd_is_gen1(priv))
|
||||
ops = &rsnd_src_gen1_ops;
|
||||
if (rsnd_is_gen2(priv))
|
||||
ops = &rsnd_src_gen2_ops;
|
||||
|
||||
rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i);
|
||||
|
||||
|
|
|
@ -240,10 +240,10 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
|
|||
* SSI mod common functions
|
||||
*/
|
||||
static int rsnd_ssi_init(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
u32 cr;
|
||||
|
||||
|
@ -287,14 +287,13 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
|
|||
ssi->cr_own = cr;
|
||||
ssi->err = -1; /* ignore 1st error */
|
||||
|
||||
rsnd_src_ssi_mode_init(mod, rdai, io);
|
||||
rsnd_src_ssi_mode_init(mod, rdai);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_ssi_quit(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
|
@ -359,8 +358,7 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
|
|||
}
|
||||
|
||||
static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
@ -379,15 +377,15 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
|
||||
/* enable PIO IRQ */
|
||||
ssi->cr_etc = UIEN | OIEN | DIEN;
|
||||
|
||||
rsnd_src_enable_ssi_irq(mod, rdai, io);
|
||||
rsnd_src_enable_ssi_irq(mod, rdai);
|
||||
|
||||
rsnd_ssi_hw_start(ssi, rdai, io);
|
||||
|
||||
|
@ -395,8 +393,7 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_ssi_pio_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
|
||||
|
@ -417,25 +414,17 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
|
|||
};
|
||||
|
||||
static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
int dma_id = ssi->info->dma_id;
|
||||
int is_play;
|
||||
int ret;
|
||||
|
||||
if (info->dai_info)
|
||||
is_play = rsnd_info_is_playback(priv, ssi);
|
||||
else
|
||||
is_play = rsnd_ssi_is_play(&ssi->mod);
|
||||
|
||||
ret = rsnd_dma_init(
|
||||
priv, rsnd_mod_to_dma(mod),
|
||||
is_play,
|
||||
rsnd_info_is_playback(priv, ssi),
|
||||
dma_id);
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -445,8 +434,7 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
|
||||
|
||||
|
@ -454,11 +442,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
|
||||
/* enable DMA transfer */
|
||||
ssi->cr_etc = DMEN;
|
||||
|
@ -475,8 +463,7 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
|
|||
}
|
||||
|
||||
static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io)
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod);
|
||||
|
@ -512,41 +499,6 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = {
|
|||
/*
|
||||
* ssi mod function
|
||||
*/
|
||||
struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
|
||||
int dai_id, int is_play)
|
||||
{
|
||||
struct rsnd_dai_platform_info *dai_info = NULL;
|
||||
struct rsnd_dai_path_info *path_info = NULL;
|
||||
struct rsnd_ssi_platform_info *target_info = NULL;
|
||||
struct rsnd_ssi *ssi;
|
||||
int i, has_play;
|
||||
|
||||
if (priv->rdai)
|
||||
dai_info = priv->rdai[dai_id].info;
|
||||
if (dai_info)
|
||||
path_info = (is_play) ? &dai_info->playback : &dai_info->capture;
|
||||
if (path_info)
|
||||
target_info = path_info->ssi;
|
||||
|
||||
is_play = !!is_play;
|
||||
|
||||
for_each_rsnd_ssi(ssi, priv, i) {
|
||||
if (target_info == ssi->info)
|
||||
return &ssi->mod;
|
||||
|
||||
/* for compatible */
|
||||
if (rsnd_ssi_dai_id(ssi) != dai_id)
|
||||
continue;
|
||||
|
||||
has_play = rsnd_ssi_is_play(&ssi->mod);
|
||||
|
||||
if (is_play == has_play)
|
||||
return &ssi->mod;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
|
||||
{
|
||||
if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
|
||||
|
@ -562,13 +514,6 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
|
|||
return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
|
||||
}
|
||||
|
||||
int rsnd_ssi_is_play(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
|
||||
return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);
|
||||
}
|
||||
|
||||
static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
|
||||
{
|
||||
if (!rsnd_ssi_is_pin_sharing(&ssi->mod))
|
||||
|
|
Loading…
Reference in New Issue