int ret;
struct device_node *np = pdev->dev.of_node;
struct am335x_tx48_drvdata *drvdata;
- struct device_node *of_node;
+ struct device_node *codec_np;
+ struct device_node *mcasp_np;
+ struct platform_device *mcasp_pdev;
+ struct i2c_client *codec_dev;
struct clk *mclk;
- of_node = of_parse_phandle(np, "ti,audio-codec", 0);
- if (!of_node) {
+ codec_np = of_parse_phandle(np, "ti,audio-codec", 0);
+ if (!codec_np) {
dev_err(&pdev->dev, "codec handle missing in DT\n");
return -EINVAL;
}
- am335x_tx48_dai.codec_of_node = of_node;
- of_node_put(of_node);
-
- of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
- if (!of_node) {
+ mcasp_np = of_parse_phandle(np, "ti,mcasp-controller", 0);
+ if (!mcasp_np) {
dev_err(&pdev->dev, "mcasp handle missing in DT\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_codec;
+ }
+
+ codec_dev = of_find_i2c_device_by_node(codec_np);
+ if (!codec_dev) {
+ dev_err(&pdev->dev, "failed to find codec platform device\n");
+ ret = -EPROBE_DEFER;
+ goto err_mcasp;
}
- am335x_tx48_dai.cpu_of_node = of_node;
- am335x_tx48_dai.platform_of_node = of_node;
- of_node_put(of_node);
+ mcasp_pdev = of_find_device_by_node(mcasp_np);
+ if (!mcasp_pdev) {
+ dev_err(&pdev->dev, "failed to find MCASP platform device\n");
+ ret = -EPROBE_DEFER;
+ goto err_mcasp;
+ }
+
+ am335x_tx48_dai.codec_of_node = codec_np;
+ am335x_tx48_dai.cpu_of_node = mcasp_np;
+ am335x_tx48_dai.platform_of_node = mcasp_np;
am335x_tx48_soc_card.dev = &pdev->dev;
ret = snd_soc_of_parse_card_name(&am335x_tx48_soc_card, "ti,model");
if (ret)
- return ret;
-
- mclk = devm_clk_get(&pdev->dev, "mclk");
- if (PTR_ERR(mclk) == -EPROBE_DEFER) {
- return -EPROBE_DEFER;
- } else if (IS_ERR(mclk)) {
- dev_dbg(&pdev->dev, "mclk not found\n");
- mclk = NULL;
+ goto err_mcasp;
+
+ mclk = devm_clk_get(&codec_dev->dev, NULL);
+ if (IS_ERR(mclk)) {
+ ret = PTR_ERR(mclk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "mclk not found: %d\n", ret);
+ goto err_mcasp;
}
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
+ if (!drvdata) {
+ ret = -ENOMEM;
+ goto err_mcasp;
+ }
+ drvdata->mclk = mclk;
ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
if (ret < 0) {
if (!drvdata->mclk) {
dev_err(&pdev->dev,
"No clock or clock rate defined.\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_mcasp;
}
drvdata->sysclk = clk_get_rate(drvdata->mclk);
} else if (drvdata->mclk) {
- unsigned int requestd_rate = drvdata->sysclk;
+ unsigned int requested_rate = drvdata->sysclk;
ret = clk_set_rate(drvdata->mclk, drvdata->sysclk);
if (ret) {
dev_err(&pdev->dev, "Could not set mclk rate to %u\n",
drvdata->sysclk);
- return ret;
+ goto err_mcasp;
}
drvdata->sysclk = clk_get_rate(drvdata->mclk);
- if (drvdata->sysclk != requestd_rate)
+ if (drvdata->sysclk != requested_rate)
dev_warn(&pdev->dev,
"Could not get requested rate %u using %u\n",
- requestd_rate, drvdata->sysclk);
+ requested_rate, drvdata->sysclk);
}
snd_soc_card_set_drvdata(&am335x_tx48_soc_card, drvdata);
ret = devm_snd_soc_register_card(&pdev->dev, &am335x_tx48_soc_card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
- return ret;
+ goto err_mcasp;
}
- dev_dbg(&pdev->dev, "Soundcard %p registered\n", &am335x_tx48_soc_card);
+ dev_dbg(&pdev->dev, "Soundcard %s registered\n",
+ am335x_tx48_soc_card.name);
return 0;
-}
-static int am335x_tx48_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
-
-dev_dbg(&pdev->dev, "%s: Unregistering card %p\n", __func__, card);
- snd_soc_unregister_card(card);
+err_mcasp:
+ of_node_put(mcasp_np);
- return 0;
+err_codec:
+ of_node_put(codec_np);
+ return ret;
}
static struct platform_driver am335x_tx48_driver = {
.probe = am335x_tx48_probe,
- .remove = am335x_tx48_remove,
.driver = {
.name = "am335x_tx48",
.owner = THIS_MODULE,