Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 332160
b: refs/heads/master
c: 2ef39e6
h: refs/heads/master
v: v3
  • Loading branch information
Mark Brown committed Sep 22, 2012
1 parent bc14788 commit 7fcb268
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 109 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a89be93c28cd656d1c3c49fe627666b3bbecd45a
refs/heads/master: 2ef39e606bb43d6041b6d820e2a9156110a82d21
39 changes: 39 additions & 0 deletions trunk/Documentation/devicetree/bindings/sound/ux500-mop500.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
* MOP500 Audio Machine Driver

This node is responsible for linking together all ux500 Audio Driver components.

Required properties:
- compatible : "stericsson,snd-soc-mop500"

Non-standard properties:
- stericsson,cpu-dai : Phandle to the CPU-side DAI
- stericsson,audio-codec : Phandle to the Audio CODEC
- stericsson,card-name : Over-ride default card name

Example:

sound {
compatible = "stericsson,snd-soc-mop500";

stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
};

msp1: msp@80124000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80124000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};

msp3: msp@80125000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80125000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};

codec: ab8500-codec {
compatible = "stericsson,ab8500-codec";
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
43 changes: 43 additions & 0 deletions trunk/Documentation/devicetree/bindings/sound/ux500-msp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
* ux500 MSP (CPU-side Digital Audio Interface)

Required properties:
- compatible :"stericsson,ux500-msp-i2s"
- reg : Physical base address and length of the device's registers.

Optional properties:
- interrupts : The interrupt output from the device.
- interrupt-parent : The parent interrupt controller.
- <name>-supply : Phandle to the regulator <name> supply

Example:

sound {
compatible = "stericsson,snd-soc-mop500";

stericsson,platform-pcm-dma = <&pcm>;
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
};

pcm: ux500-pcm {
compatible = "stericsson,ux500-pcm";
};

msp1: msp@80124000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80124000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};

msp3: msp@80125000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80125000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};

codec: ab8500-codec {
compatible = "stericsson,ab8500-codec";
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};
79 changes: 1 addition & 78 deletions trunk/arch/arm/mach-ux500/board-mop500-msp.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/pinctrl/consumer.h>

#include <plat/gpio-nomadik.h>
#include <plat/pincfg.h>
Expand All @@ -23,53 +22,6 @@
#include "devices-db8500.h"
#include "pins-db8500.h"

/* MSP1/3 Tx/Rx usage protection */
static DEFINE_SPINLOCK(msp_rxtx_lock);

/* Reference Count */
static int msp_rxtx_ref;

/* Pin modes */
struct pinctrl *msp1_p;
struct pinctrl_state *msp1_def;
struct pinctrl_state *msp1_sleep;

int msp13_i2s_init(void)
{
int retval = 0;
unsigned long flags;

spin_lock_irqsave(&msp_rxtx_lock, flags);
if (msp_rxtx_ref == 0 && !(IS_ERR(msp1_p) || IS_ERR(msp1_def))) {
retval = pinctrl_select_state(msp1_p, msp1_def);
if (retval)
pr_err("could not set MSP1 defstate\n");
}
if (!retval)
msp_rxtx_ref++;
spin_unlock_irqrestore(&msp_rxtx_lock, flags);

return retval;
}

int msp13_i2s_exit(void)
{
int retval = 0;
unsigned long flags;

spin_lock_irqsave(&msp_rxtx_lock, flags);
WARN_ON(!msp_rxtx_ref);
msp_rxtx_ref--;
if (msp_rxtx_ref == 0 && !(IS_ERR(msp1_p) || IS_ERR(msp1_sleep))) {
retval = pinctrl_select_state(msp1_p, msp1_sleep);
if (retval)
pr_err("could not set MSP1 sleepstate\n");
}
spin_unlock_irqrestore(&msp_rxtx_lock, flags);

return retval;
}

static struct stedma40_chan_cfg msp0_dma_rx = {
.high_priority = true,
.dir = STEDMA40_PERIPH_TO_MEM,
Expand Down Expand Up @@ -132,8 +84,6 @@ static struct msp_i2s_platform_data msp1_platform_data = {
.id = MSP_I2S_1,
.msp_i2s_dma_rx = NULL,
.msp_i2s_dma_tx = &msp1_dma_tx,
.msp_i2s_init = msp13_i2s_init,
.msp_i2s_exit = msp13_i2s_exit,
};

static struct stedma40_chan_cfg msp2_dma_rx = {
Expand Down Expand Up @@ -219,49 +169,22 @@ static struct msp_i2s_platform_data msp3_platform_data = {
.id = MSP_I2S_3,
.msp_i2s_dma_rx = &msp1_dma_rx,
.msp_i2s_dma_tx = NULL,
.msp_i2s_init = msp13_i2s_init,
.msp_i2s_exit = msp13_i2s_exit,
};

int mop500_msp_init(struct device *parent)
{
struct platform_device *msp1;

pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__);
platform_device_register(&snd_soc_mop500);

pr_info("Initialize MSP I2S-devices.\n");
db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0,
&msp0_platform_data);
msp1 = db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1,
db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1,
&msp1_platform_data);
db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2,
&msp2_platform_data);
db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1,
&msp3_platform_data);

/* Get the pinctrl handle for MSP1 */
if (msp1) {
msp1_p = pinctrl_get(&msp1->dev);
if (IS_ERR(msp1_p))
dev_err(&msp1->dev, "could not get MSP1 pinctrl\n");
else {
msp1_def = pinctrl_lookup_state(msp1_p,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(msp1_def)) {
dev_err(&msp1->dev,
"could not get MSP1 defstate\n");
}
msp1_sleep = pinctrl_lookup_state(msp1_p,
PINCTRL_STATE_SLEEP);
if (IS_ERR(msp1_sleep))
dev_err(&msp1->dev,
"could not get MSP1 idlestate\n");
}
}

pr_info("%s: Register platform-device 'ux500-pcm'\n", __func__);
platform_device_register(&ux500_pcm);

return 0;
}
2 changes: 0 additions & 2 deletions trunk/arch/arm/mach-ux500/include/mach/msp.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ struct msp_i2s_platform_data {
enum msp_i2s_id id;
struct stedma40_chan_cfg *msp_i2s_dma_rx;
struct stedma40_chan_cfg *msp_i2s_dma_tx;
int (*msp_i2s_init) (void);
int (*msp_i2s_exit) (void);
};

#endif
6 changes: 4 additions & 2 deletions trunk/include/linux/mfd/abx500/ab8500-codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ enum amic_type {
/* Mic-biases */
enum amic_micbias {
AMIC_MICBIAS_VAMIC1,
AMIC_MICBIAS_VAMIC2
AMIC_MICBIAS_VAMIC2,
AMIC_MICBIAS_UNKNOWN
};

/* Bias-voltage */
enum ear_cm_voltage {
EAR_CMV_0_95V,
EAR_CMV_1_10V,
EAR_CMV_1_27V,
EAR_CMV_1_58V
EAR_CMV_1_58V,
EAR_CMV_UNKNOWN
};

/* Analog microphone settings */
Expand Down
81 changes: 81 additions & 0 deletions trunk/sound/soc/codecs/ab8500-codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/mfd/abx500/ab8500-sysctrl.h>
#include <linux/mfd/abx500/ab8500-codec.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>

#include <sound/core.h>
#include <sound/pcm.h>
Expand Down Expand Up @@ -2394,9 +2395,65 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
}
};

static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
struct ab8500_codec_platform_data *codec)
{
u32 value;

if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL))
codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED;
else
codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL;

if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL))
codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED;
else
codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL;

/* Has a non-standard Vamic been requested? */
if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL))
codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2;
else
codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1;

if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL))
codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2;
else
codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1;

if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL))
codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1;
else
codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2;

if (!of_property_read_u32(np, "stericsson,earpeice-cmv", &value)) {
switch (value) {
case 950 :
codec->ear_cmv = EAR_CMV_0_95V;
break;
case 1100 :
codec->ear_cmv = EAR_CMV_1_10V;
break;
case 1270 :
codec->ear_cmv = EAR_CMV_1_27V;
break;
case 1580 :
codec->ear_cmv = EAR_CMV_1_58V;
break;
default :
codec->ear_cmv = EAR_CMV_UNKNOWN;
dev_err(dev, "Unsuitable earpiece voltage found in DT\n");
}
} else {
dev_warn(dev, "No earpiece voltage found in DT - using default\n");
codec->ear_cmv = EAR_CMV_0_95V;
}
}

static int ab8500_codec_probe(struct snd_soc_codec *codec)
{
struct device *dev = codec->dev;
struct device_node *np = dev->of_node;
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
struct ab8500_platform_data *pdata;
struct filter_control *fc;
Expand All @@ -2407,6 +2464,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
/* Setup AB8500 according to board-settings */
pdata = dev_get_platdata(dev->parent);

if (np) {
if (!pdata)
pdata = devm_kzalloc(dev,
sizeof(struct ab8500_platform_data),
GFP_KERNEL);

if (pdata && !pdata->codec)
pdata->codec
= devm_kzalloc(dev,
sizeof(struct ab8500_codec_platform_data),
GFP_KERNEL);

if (!(pdata && pdata->codec))
return -ENOMEM;

ab8500_codec_of_probe(dev, np, pdata->codec);

} else {
if (!(pdata && pdata->codec)) {
dev_err(dev, "No codec platform data or DT found\n");
return -EINVAL;
}
}

status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
if (status < 0) {
pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
Expand Down
Loading

0 comments on commit 7fcb268

Please sign in to comment.