Skip to content

Commit

Permalink
Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl…
Browse files Browse the repository at this point in the history
…5000', 'asoc/topic/simple', 'asoc/topic/sirf' and 'asoc/topic/ssm4567' into asoc-next
  • Loading branch information
broonie committed Apr 30, 2017
6 parents fc180c0 + aba611f + 570c70a + d27f3b4 + adbdba3 + 71c314d commit ae17a14
Show file tree
Hide file tree
Showing 16 changed files with 372 additions and 41 deletions.
57 changes: 57 additions & 0 deletions Documentation/devicetree/bindings/sound/samsung,odroid.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Samsung Exynos Odroid XU3/XU4 audio complex with MAX98090 codec

Required properties:

- compatible - "samsung,odroidxu3-audio" - for Odroid XU3 board,
"samsung,odroidxu4-audio" - for Odroid XU4 board
- model - the user-visible name of this sound complex
- 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
controller
- 'codec' subnode with a 'sound-dai' property containing list of phandles
to the CODEC nodes, first entry must be corresponding to the MAX98090
CODEC and the second entry must be the phandle of the HDMI IP block node
- clocks - should contain entries matching clock names in the clock-names
property
- clock-names - should contain following entries:
- "epll" - indicating the EPLL output clock
- "i2s_rclk" - indicating the RCLK (root) clock of the I2S0 controller
- samsung,audio-widgets - this property specifies off-codec audio elements
like headphones or speakers, for details see widgets.txt
- samsung,audio-routing - a list of the connections between audio
components; each entry is a pair of strings, the first being the
connection's sink, the second being the connection's source;
valid names for sources and sinks are the MAX98090's pins (as
documented in its binding), and the jacks on the board

For Odroid X2:
"Headphone Jack", "Mic Jack", "DMIC"

For Odroid U3, XU3:
"Headphone Jack", "Speakers"

For Odroid XU4:
no entries

Example:

sound {
compatible = "samsung,odroidxu3-audio";
samsung,cpu-dai = <&i2s0>;
samsung,codec-dai = <&max98090>;
model = "Odroid-XU3";
samsung,audio-routing =
"Headphone Jack", "HPL",
"Headphone Jack", "HPR",
"IN1", "Mic Jack",
"Mic Jack", "MICBIAS";

clocks = <&clock CLK_FOUT_EPLL>, <&i2s0 CLK_I2S_RCLK_SRC>;
clock-names = "epll", "sclk_i2s";

cpu {
sound-dai = <&i2s0 0>;
};
codec {
sound-dai = <&hdmi>, <&max98090>;
};
};
9 changes: 9 additions & 0 deletions Documentation/devicetree/bindings/sound/sgtl5000.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ Optional properties:
If this node is not mentioned or the value is unknown, then
the value is set to 1.25V.

- lrclk-strength: the LRCLK pad strength. Possible values are:
0, 1, 2 and 3 as per the table below:

VDDIO 1.8V 2.5V 3.3V
0 = Disable
1 = 1.66 mA 2.87 mA 4.02 mA
2 = 3.33 mA 5.74 mA 8.03 mA
3 = 4.99 mA 8.61 mA 12.05 mA

Example:

codec: sgtl5000@0a {
Expand Down
19 changes: 18 additions & 1 deletion sound/soc/codecs/sgtl5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ enum sgtl5000_micbias_resistor {
SGTL5000_MICBIAS_8K = 8,
};

enum {
I2S_LRCLK_STRENGTH_DISABLE,
I2S_LRCLK_STRENGTH_LOW,
I2S_LRCLK_STRENGTH_MEDIUM,
I2S_LRCLK_STRENGTH_HIGH,
};

/* sgtl5000 private structure in codec */
struct sgtl5000_priv {
int sysclk; /* sysclk rate */
Expand All @@ -111,6 +118,7 @@ struct sgtl5000_priv {
int revision;
u8 micbias_resistor;
u8 micbias_voltage;
u8 lrclk_strength;
};

/*
Expand Down Expand Up @@ -1089,6 +1097,7 @@ static int sgtl5000_enable_regulators(struct i2c_client *client)
static int sgtl5000_probe(struct snd_soc_codec *codec)
{
int ret;
u16 reg;
struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);

/* power up sgtl5000 */
Expand Down Expand Up @@ -1118,7 +1127,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
SGTL5000_DAC_MUTE_RIGHT |
SGTL5000_DAC_MUTE_LEFT);

snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f);
reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f);
snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, reg);

snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
SGTL5000_HP_ZCD_EN |
Expand Down Expand Up @@ -1347,6 +1357,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
}
}

sgtl5000->lrclk_strength = I2S_LRCLK_STRENGTH_LOW;
if (!of_property_read_u32(np, "lrclk-strength", &value)) {
if (value > I2S_LRCLK_STRENGTH_HIGH)
value = I2S_LRCLK_STRENGTH_LOW;
sgtl5000->lrclk_strength = value;
}

/* Ensure sgtl5000 will start with sane register values */
sgtl5000_fill_defaults(client);

Expand Down
9 changes: 9 additions & 0 deletions sound/soc/codecs/ssm4567.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,14 @@ static const struct i2c_device_id ssm4567_i2c_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, ssm4567_i2c_ids);

#ifdef CONFIG_OF
static const struct of_device_id ssm4567_of_match[] = {
{ .compatible = "adi,ssm4567", },
{ }
};
MODULE_DEVICE_TABLE(of, ssm4567_of_match);
#endif

#ifdef CONFIG_ACPI

static const struct acpi_device_id ssm4567_acpi_match[] = {
Expand All @@ -498,6 +506,7 @@ MODULE_DEVICE_TABLE(acpi, ssm4567_acpi_match);
static struct i2c_driver ssm4567_driver = {
.driver = {
.name = "ssm4567",
.of_match_table = of_match_ptr(ssm4567_of_match),
.acpi_match_table = ACPI_PTR(ssm4567_acpi_match),
},
.probe = ssm4567_i2c_probe,
Expand Down
43 changes: 24 additions & 19 deletions sound/soc/generic/simple-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ struct simple_card_data {
struct snd_soc_dai_link *dai_link;
};

#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
#define simple_priv_to_card(priv) (&(priv)->snd_card)
#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))

#define DAI "sound-dai"
#define CELL "#sound-dai-cells"
Expand Down Expand Up @@ -323,6 +324,7 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
{
struct device *dev = simple_priv_to_dev(priv);
struct device_node *aux_node;
struct snd_soc_card *card = simple_priv_to_card(priv);
int i, n, len;

if (!of_find_property(node, PREFIX "aux-devs", &len))
Expand All @@ -332,26 +334,27 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
if (n <= 0)
return -EINVAL;

priv->snd_card.aux_dev = devm_kzalloc(dev,
n * sizeof(*priv->snd_card.aux_dev), GFP_KERNEL);
if (!priv->snd_card.aux_dev)
card->aux_dev = devm_kzalloc(dev,
n * sizeof(*card->aux_dev), GFP_KERNEL);
if (!card->aux_dev)
return -ENOMEM;

for (i = 0; i < n; i++) {
aux_node = of_parse_phandle(node, PREFIX "aux-devs", i);
if (!aux_node)
return -EINVAL;
priv->snd_card.aux_dev[i].codec_of_node = aux_node;
card->aux_dev[i].codec_of_node = aux_node;
}

priv->snd_card.num_aux_devs = n;
card->num_aux_devs = n;
return 0;
}

static int asoc_simple_card_parse_of(struct device_node *node,
struct simple_card_data *priv)
{
struct device *dev = simple_priv_to_dev(priv);
struct snd_soc_card *card = simple_priv_to_card(priv);
struct device_node *dai_link;
int ret;

Expand All @@ -362,15 +365,15 @@ static int asoc_simple_card_parse_of(struct device_node *node,

/* The off-codec widgets */
if (of_property_read_bool(node, PREFIX "widgets")) {
ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
ret = snd_soc_of_parse_audio_simple_widgets(card,
PREFIX "widgets");
if (ret)
goto card_parse_end;
}

/* DAPM routes */
if (of_property_read_bool(node, PREFIX "routing")) {
ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
ret = snd_soc_of_parse_audio_routing(card,
PREFIX "routing");
if (ret)
goto card_parse_end;
Expand Down Expand Up @@ -401,7 +404,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
goto card_parse_end;
}

ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
ret = asoc_simple_card_parse_card_name(card, PREFIX);
if (ret < 0)
goto card_parse_end;

Expand All @@ -418,8 +421,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
struct simple_card_data *priv;
struct snd_soc_dai_link *dai_link;
struct simple_dai_props *dai_props;
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct snd_soc_card *card;
int num, ret;

/* Get the number of DAI links */
Expand All @@ -442,10 +446,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
priv->dai_link = dai_link;

/* Init snd_soc_card */
priv->snd_card.owner = THIS_MODULE;
priv->snd_card.dev = dev;
priv->snd_card.dai_link = priv->dai_link;
priv->snd_card.num_links = num;
card = simple_priv_to_card(priv);
card->owner = THIS_MODULE;
card->dev = dev;
card->dai_link = priv->dai_link;
card->num_links = num;

if (np && of_device_is_available(np)) {

Expand Down Expand Up @@ -474,7 +479,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
return -EINVAL;
}

priv->snd_card.name = (cinfo->card) ? cinfo->card : cinfo->name;
card->name = (cinfo->card) ? cinfo->card : cinfo->name;
dai_link->name = cinfo->name;
dai_link->stream_name = cinfo->name;
dai_link->platform_name = cinfo->platform;
Expand All @@ -489,13 +494,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
sizeof(priv->dai_props->codec_dai));
}

snd_soc_card_set_drvdata(&priv->snd_card, priv);
snd_soc_card_set_drvdata(card, priv);

ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
ret = devm_snd_soc_register_card(dev, card);
if (ret >= 0)
return ret;
err:
asoc_simple_card_clean_reference(&priv->snd_card);
asoc_simple_card_clean_reference(card);

return ret;
}
Expand Down
37 changes: 21 additions & 16 deletions sound/soc/generic/simple-scu-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ struct simple_card_data {
u32 convert_channels;
};

#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
#define simple_priv_to_card(priv) (&(priv)->snd_card)
#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))

#define DAI "sound-dai"
#define CELL "#sound-dai-cells"
Expand Down Expand Up @@ -109,6 +110,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
struct device *dev = simple_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
struct snd_soc_card *card = simple_priv_to_card(priv);
int ret;

if (is_fe) {
Expand Down Expand Up @@ -163,7 +165,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
if (ret < 0)
return ret;

snd_soc_of_parse_audio_prefix(&priv->snd_card,
snd_soc_of_parse_audio_prefix(card,
&priv->codec_conf,
dai_link->codec_of_node,
PREFIX "prefix");
Expand Down Expand Up @@ -201,14 +203,15 @@ static int asoc_simple_card_parse_of(struct device_node *node,
{
struct device *dev = simple_priv_to_dev(priv);
struct device_node *np;
struct snd_soc_card *card = simple_priv_to_card(priv);
unsigned int daifmt = 0;
bool is_fe;
int ret, i;

if (!node)
return -EINVAL;

ret = snd_soc_of_parse_audio_routing(&priv->snd_card, PREFIX "routing");
ret = snd_soc_of_parse_audio_routing(card, PREFIX "routing");
if (ret < 0)
return ret;

Expand Down Expand Up @@ -239,12 +242,12 @@ static int asoc_simple_card_parse_of(struct device_node *node,
i++;
}

ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
ret = asoc_simple_card_parse_card_name(card, PREFIX);
if (ret < 0)
return ret;

dev_dbg(dev, "New card: %s\n",
priv->snd_card.name ? priv->snd_card.name : "");
card->name ? card->name : "");
dev_dbg(dev, "convert_rate %d\n", priv->convert_rate);
dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);

Expand All @@ -256,8 +259,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
struct simple_card_data *priv;
struct snd_soc_dai_link *dai_link;
struct asoc_simple_dai *dai_props;
struct snd_soc_card *card;
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node;
struct device_node *np = dev->of_node;
int num, ret;

/* Allocate the private data */
Expand All @@ -276,12 +280,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
priv->dai_link = dai_link;

/* Init snd_soc_card */
priv->snd_card.owner = THIS_MODULE;
priv->snd_card.dev = dev;
priv->snd_card.dai_link = priv->dai_link;
priv->snd_card.num_links = num;
priv->snd_card.codec_conf = &priv->codec_conf;
priv->snd_card.num_configs = 1;
card = simple_priv_to_card(priv);
card->owner = THIS_MODULE;
card->dev = dev;
card->dai_link = priv->dai_link;
card->num_links = num;
card->codec_conf = &priv->codec_conf;
card->num_configs = 1;

ret = asoc_simple_card_parse_of(np, priv);
if (ret < 0) {
Expand All @@ -290,13 +295,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
goto err;
}

snd_soc_card_set_drvdata(&priv->snd_card, priv);
snd_soc_card_set_drvdata(card, priv);

ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
ret = devm_snd_soc_register_card(dev, card);
if (ret >= 0)
return ret;
err:
asoc_simple_card_clean_reference(&priv->snd_card);
asoc_simple_card_clean_reference(card);

return ret;
}
Expand Down
Loading

0 comments on commit ae17a14

Please sign in to comment.