Skip to content

Commit

Permalink
Merge branch 'asoc-omap' into for-3.7
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Brown committed Aug 22, 2012
2 parents 02e7947 + b810104 commit 2bbf607
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 200 deletions.
37 changes: 37 additions & 0 deletions Documentation/devicetree/bindings/sound/omap-mcbsp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
* Texas Instruments OMAP2+ McBSP module

Required properties:
- compatible: "ti,omap2420-mcbsp" for McBSP on OMAP2420
"ti,omap2430-mcbsp" for McBSP on OMAP2430
"ti,omap3-mcbsp" for McBSP on OMAP3
"ti,omap4-mcbsp" for McBSP on OMAP4 and newer SoC
- reg: Register location and size, for OMAP4+ as an array:
<MPU access base address, size>,
<L3 interconnect address, size>;
- reg-names: Array of strings associated with the address space
- interrupts: Interrupt numbers for the McBSP port, as an array in case the
McBSP IP have more interrupt lines:
<OCP compliant irq>,
<TX irq>,
<RX irq>;
- interrupt-names: Array of strings associated with the interrupt numbers
- interrupt-parent: The parent interrupt controller
- ti,buffer-size: Size of the FIFO on the port (OMAP2430 and newer SoC)
- ti,hwmods: Name of the hwmod associated to the McBSP port

Example:

mcbsp2: mcbsp@49022000 {
compatible = "ti,omap3-mcbsp";
reg = <0x49022000 0xff>,
<0x49028000 0xff>;
reg-names = "mpu", "sidetone";
interrupts = <0 17 0x4>, /* OCP compliant interrupt */
<0 62 0x4>, /* TX interrupt */
<0 63 0x4>, /* RX interrupt */
<0 4 0x4>; /* Sidetone */
interrupt-names = "common", "tx", "rx", "sidetone";
interrupt-parent = <&intc>;
ti,buffer-size = <1280>;
ti,hwmods = "mcbsp2";
};
13 changes: 13 additions & 0 deletions arch/arm/mach-omap2/board-am3517evm.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,16 @@ static __init void am3517_evm_musb_init(void)
usb_musb_init(&musb_board_data);
}

static __init void am3517_evm_mcbsp1_init(void)
{
u32 devconf0;

/* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */
devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
devconf0 |= OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK;
omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
}

static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
Expand Down Expand Up @@ -373,6 +383,9 @@ static void __init am3517_evm_init(void)
/* MUSB */
am3517_evm_musb_init();

/* McBSP1 */
am3517_evm_mcbsp1_init();

/* MMC init function */
omap_hsmmc_init(mmc);
}
Expand Down
126 changes: 7 additions & 119 deletions arch/arm/mach-omap2/mcbsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

Expand All @@ -25,121 +26,13 @@
#include <plat/omap_device.h>
#include <linux/pm_runtime.h>

#include "control.h"

/*
* FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
* Sidetone needs non-gated ICLK and sidetone autoidle is broken.
*/
#include "cm2xxx_3xxx.h"
#include "cm-regbits-34xx.h"

/* McBSP1 internal signal muxing function for OMAP2/3 */
static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal,
const char *src)
{
u32 v;

v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);

if (!strcmp(signal, "clkr")) {
if (!strcmp(src, "clkr"))
v &= ~OMAP2_MCBSP1_CLKR_MASK;
else if (!strcmp(src, "clkx"))
v |= OMAP2_MCBSP1_CLKR_MASK;
else
return -EINVAL;
} else if (!strcmp(signal, "fsr")) {
if (!strcmp(src, "fsr"))
v &= ~OMAP2_MCBSP1_FSR_MASK;
else if (!strcmp(src, "fsx"))
v |= OMAP2_MCBSP1_FSR_MASK;
else
return -EINVAL;
} else {
return -EINVAL;
}

omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);

return 0;
}

/* McBSP4 internal signal muxing function for OMAP4 */
#define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX (1 << 31)
#define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX (1 << 30)
static int omap4_mcbsp4_mux_rx_clk(struct device *dev, const char *signal,
const char *src)
{
u32 v;

/*
* In CONTROL_MCBSPLP register only bit 30 (CLKR mux), and bit 31 (FSR
* mux) is used */
v = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP);

if (!strcmp(signal, "clkr")) {
if (!strcmp(src, "clkr"))
v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX;
else if (!strcmp(src, "clkx"))
v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX;
else
return -EINVAL;
} else if (!strcmp(signal, "fsr")) {
if (!strcmp(src, "fsr"))
v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX;
else if (!strcmp(src, "fsx"))
v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX;
else
return -EINVAL;
} else {
return -EINVAL;
}

omap4_ctrl_pad_writel(v, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP);

return 0;
}

/* McBSP CLKS source switching function */
static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk,
const char *src)
{
struct clk *fck_src;
char *fck_src_name;
int r;

if (!strcmp(src, "clks_ext"))
fck_src_name = "pad_fck";
else if (!strcmp(src, "clks_fclk"))
fck_src_name = "prcm_fck";
else
return -EINVAL;

fck_src = clk_get(dev, fck_src_name);
if (IS_ERR_OR_NULL(fck_src)) {
pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
fck_src_name);
return -EINVAL;
}

pm_runtime_put_sync(dev);

r = clk_set_parent(clk, fck_src);
if (IS_ERR_VALUE(r)) {
pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
"clks", fck_src_name);
clk_put(fck_src);
return -EINVAL;
}

pm_runtime_get_sync(dev);

clk_put(fck_src);

return 0;
}

static int omap3_enable_st_clock(unsigned int id, bool enable)
{
unsigned int w;
Expand Down Expand Up @@ -181,17 +74,11 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
pdata->reg_size = 4;
pdata->has_ccr = true;
}
pdata->set_clk_src = omap2_mcbsp_set_clk_src;

/* On OMAP2/3 the McBSP1 port has 6 pin configuration */
if (id == 1 && oh->class->rev < MCBSP_CONFIG_TYPE4)
pdata->mux_signal = omap2_mcbsp1_mux_rx_clk;

/* On OMAP4 the McBSP4 port has 6 pin configuration */
if (id == 4 && oh->class->rev == MCBSP_CONFIG_TYPE4)
pdata->mux_signal = omap4_mcbsp4_mux_rx_clk;

if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
if (oh->class->rev == MCBSP_CONFIG_TYPE2) {
/* The FIFO has 128 locations */
pdata->buffer_size = 0x80;
} else if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
if (id == 2)
/* The FIFO has 1024 + 256 locations */
pdata->buffer_size = 0x500;
Expand Down Expand Up @@ -227,7 +114,8 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)

static int __init omap2_mcbsp_init(void)
{
omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
if (!of_have_populated_dt())
omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);

return 0;
}
Expand Down
2 changes: 0 additions & 2 deletions arch/arm/plat-omap/include/plat/mcbsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ struct omap_mcbsp_platform_data {
bool has_wakeup; /* Wakeup capability */
bool has_ccr; /* Transceiver has configuration control registers */
int (*enable_st_clock)(unsigned int, bool);
int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src);
int (*mux_signal)(struct device *dev, const char *signal, const char *src);
};

/**
Expand Down
20 changes: 2 additions & 18 deletions sound/soc/omap/am3517evm.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,10 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
/* Set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
CODEC_CLOCK, SND_SOC_CLOCK_IN);
if (ret < 0) {
if (ret < 0)
printk(KERN_ERR "can't set codec system clock\n");
return ret;
}

ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
SND_SOC_CLOCK_IN);
if (ret < 0) {
printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
return ret;
}

snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
SND_SOC_CLOCK_IN);
if (ret < 0) {
printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
return ret;
}

return 0;
return ret;
}

static struct snd_soc_ops am3517evm_ops = {
Expand Down
31 changes: 26 additions & 5 deletions sound/soc/omap/mcbsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>

#include <plat/mcbsp.h>

Expand Down Expand Up @@ -726,19 +727,39 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)

int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
{
struct clk *fck_src;
const char *src;
int r;

if (fck_src_id == MCBSP_CLKS_PAD_SRC)
src = "clks_ext";
src = "pad_fck";
else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
src = "clks_fclk";
src = "prcm_fck";
else
return -EINVAL;

if (mcbsp->pdata->set_clk_src)
return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
else
fck_src = clk_get(mcbsp->dev, src);
if (IS_ERR(fck_src)) {
dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src);
return -EINVAL;
}

pm_runtime_put_sync(mcbsp->dev);

r = clk_set_parent(mcbsp->fclk, fck_src);
if (r) {
dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n",
src);
clk_put(fck_src);
return r;
}

pm_runtime_get_sync(mcbsp->dev);

clk_put(fck_src);

return 0;

}

int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
Expand Down
3 changes: 0 additions & 3 deletions sound/soc/omap/mcbsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,6 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx);
/* McBSP functional clock source changing function */
int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id);

/* McBSP signal muxing API */
int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux);

/* Sidetone specific API */
int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain);
int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain);
Expand Down
Loading

0 comments on commit 2bbf607

Please sign in to comment.