static int msm8x16_wcd_spmi_probe(struct spmi_device *spmi)
{
int ret = 0;
struct msm8x16_wcd *msm8x16 = NULL;
struct msm8x16_wcd_pdata *pdata;
struct resource *wcd_resource;
int modem_state;
dev_dbg(&spmi->dev, "%s(%d):slave ID = 0x%x\n",
__func__, __LINE__, spmi->sid);
modem_state = apr_get_modem_state();
if (modem_state != APR_SUBSYS_LOADED) {
dev_dbg(&spmi->dev, "Modem is not loaded yet %d\n",
modem_state);
return -EPROBE_DEFER;
}
wcd_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
if (!wcd_resource) {
dev_err(&spmi->dev, "Unable to get Tombak base address\n");
return -ENXIO;
}
switch (wcd_resource->start) {
case TOMBAK_CORE_0_SPMI_ADDR:
msm8x16_wcd_modules[0].spmi = spmi;
msm8x16_wcd_modules[0].base = (spmi->sid << 16) +
wcd_resource->start;
wcd9xxx_spmi_set_dev(msm8x16_wcd_modules[0].spmi, 0);
device_init_wakeup(&spmi->dev, true);
break;
case TOMBAK_CORE_1_SPMI_ADDR:
msm8x16_wcd_modules[1].spmi = spmi;
msm8x16_wcd_modules[1].base = (spmi->sid << 16) +
wcd_resource->start;
wcd9xxx_spmi_set_dev(msm8x16_wcd_modules[1].spmi, 1);
if (wcd9xxx_spmi_irq_init()) {
dev_err(&spmi->dev,
"%s: irq initialization failed\n", __func__);
} else {
dev_dbg(&spmi->dev,
"%s: irq initialization passed\n", __func__);
}
goto rtn;
default:
ret = -EINVAL;
goto rtn;
}
dev_dbg(&spmi->dev, "%s(%d):start addr = 0x%pa\n",
__func__, __LINE__, &wcd_resource->start);
if (wcd_resource->start != TOMBAK_CORE_0_SPMI_ADDR)
goto rtn;
dev_set_name(&spmi->dev, "%s", MSM8X16_CODEC_NAME);
if (spmi->dev.of_node) {
dev_dbg(&spmi->dev, "%s:Platform data from device tree\n",
__func__);
pdata = msm8x16_wcd_populate_dt_pdata(&spmi->dev);
spmi->dev.platform_data = pdata;
} else {
dev_dbg(&spmi->dev, "%s:Platform data from board file\n",
__func__);
pdata = spmi->dev.platform_data;
}
msm8x16 = kzalloc(sizeof(struct msm8x16_wcd), GFP_KERNEL);
if (msm8x16 == NULL) {
dev_err(&spmi->dev,
"%s: error, allocation failed\n", __func__);
ret = -ENOMEM;
goto rtn;
}
msm8x16->dev = &spmi->dev;
msm8x16->read_dev = __msm8x16_wcd_reg_read;
msm8x16->write_dev = __msm8x16_wcd_reg_write;
ret = msm8x16_wcd_init_supplies(msm8x16, pdata);
if (ret) {
dev_err(&spmi->dev, "%s: Fail to enable Codec supplies\n",
__func__);
goto err_codec;
}
ret = msm8x16_wcd_enable_static_supplies(msm8x16, pdata);
if (ret) {
dev_err(&spmi->dev,
"%s: Fail to enable Codec pre-reset supplies\n",
__func__);
goto err_codec;
}
usleep_range(5, 6);
ret = msm8x16_wcd_device_init(msm8x16);
if (ret) {
dev_err(&spmi->dev,
"%s:msm8x16_wcd_device_init failed with error %d\n",
__func__, ret);
goto err_supplies;
}
dev_set_drvdata(&spmi->dev, msm8x16);
ret = snd_soc_register_codec(&spmi->dev, &soc_codec_dev_msm8x16_wcd,
msm8x16_wcd_i2s_dai,
ARRAY_SIZE(msm8x16_wcd_i2s_dai));
if (ret) {
dev_err(&spmi->dev,
"%s:snd_soc_register_codec failed with error %d\n",
__func__, ret);
} else {
goto rtn;
}
err_supplies:
msm8x16_wcd_disable_supplies(msm8x16, pdata);
err_codec:
kfree(msm8x16);
rtn:
return ret;
}
来源: https://www.cnblogs.com/linhaostudy/p/8425337.html