mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 00:51:44 +00:00
ASoC: sgtl5000: Let the codec acquire its clock
On a mx6qsabrelite board the following error happens on probe: sgtl5000: probe of 0-000a failed with error -5 imx-sgtl5000 sound.13: ASoC: CODEC (null) not registered imx-sgtl5000 sound.13: snd_soc_register_card failed (-517) platform sound.13: Driver imx-sgtl5000 requests probe defer Prior to reading the codec ID we need to turn the SYS_MCLK clock, so let's enable the codec clock inside sgtl5000_i2c_probe(). Also remove the codec clock enable/disable functions from the machine driver. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
915b2c750e
commit
9e13f34588
@ -114,6 +114,7 @@ struct sgtl5000_priv {
|
||||
struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
|
||||
struct ldo_regulator *ldo;
|
||||
struct regmap *regmap;
|
||||
struct clk *mclk;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1522,16 +1523,28 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
|
||||
return ret;
|
||||
}
|
||||
|
||||
sgtl5000->mclk = devm_clk_get(&client->dev, NULL);
|
||||
if (IS_ERR(sgtl5000->mclk)) {
|
||||
ret = PTR_ERR(sgtl5000->mclk);
|
||||
dev_err(&client->dev, "Failed to get mclock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(sgtl5000->mclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* read chip information */
|
||||
ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_clk;
|
||||
|
||||
if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
|
||||
SGTL5000_PARTID_PART_ID) {
|
||||
dev_err(&client->dev,
|
||||
"Device with ID register %x is not a sgtl5000\n", reg);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
|
||||
@ -1542,17 +1555,30 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
|
||||
/* Ensure sgtl5000 will start with sane register values */
|
||||
ret = sgtl5000_fill_defaults(sgtl5000);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_clk;
|
||||
|
||||
ret = snd_soc_register_codec(&client->dev,
|
||||
&sgtl5000_driver, &sgtl5000_dai, 1);
|
||||
if (ret)
|
||||
goto disable_clk;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
clk_disable_unprepare(sgtl5000->mclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sgtl5000_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
struct sgtl5000_priv *sgtl5000;
|
||||
sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv),
|
||||
GFP_KERNEL);
|
||||
if (!sgtl5000)
|
||||
return -ENOMEM;
|
||||
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
clk_disable_unprepare(sgtl5000->mclk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -129,20 +129,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
data->codec_clk = clk_get(&codec_dev->dev, NULL);
|
||||
if (IS_ERR(data->codec_clk)) {
|
||||
/* assuming clock enabled by default */
|
||||
data->codec_clk = NULL;
|
||||
ret = of_property_read_u32(codec_np, "clock-frequency",
|
||||
&data->clk_frequency);
|
||||
if (ret) {
|
||||
dev_err(&codec_dev->dev,
|
||||
"clock-frequency missing or invalid\n");
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
data->clk_frequency = clk_get_rate(data->codec_clk);
|
||||
clk_prepare_enable(data->codec_clk);
|
||||
}
|
||||
if (IS_ERR(data->codec_clk))
|
||||
goto fail;
|
||||
|
||||
data->clk_frequency = clk_get_rate(data->codec_clk);
|
||||
|
||||
data->dai.name = "HiFi";
|
||||
data->dai.stream_name = "HiFi";
|
||||
@ -157,10 +147,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
|
||||
data->card.dev = &pdev->dev;
|
||||
ret = snd_soc_of_parse_card_name(&data->card, "model");
|
||||
if (ret)
|
||||
goto clk_fail;
|
||||
goto fail;
|
||||
ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
|
||||
if (ret)
|
||||
goto clk_fail;
|
||||
goto fail;
|
||||
data->card.num_links = 1;
|
||||
data->card.owner = THIS_MODULE;
|
||||
data->card.dai_link = &data->dai;
|
||||
@ -170,7 +160,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
|
||||
ret = snd_soc_register_card(&data->card);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
|
||||
goto clk_fail;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
@ -179,8 +169,6 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
|
||||
clk_fail:
|
||||
clk_put(data->codec_clk);
|
||||
fail:
|
||||
if (ssi_np)
|
||||
of_node_put(ssi_np);
|
||||
@ -194,10 +182,6 @@ static int imx_sgtl5000_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
if (data->codec_clk) {
|
||||
clk_disable_unprepare(data->codec_clk);
|
||||
clk_put(data->codec_clk);
|
||||
}
|
||||
snd_soc_unregister_card(&data->card);
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user