static int twl6040_probe(struct snd_soc_codec *codec) { struct twl6040_data *priv; struct twl6040_jack_data *jack; int ret = 0; codec->control_data = dev_get_drvdata(codec->dev->parent); priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); if (priv == NULL) return -ENOMEM; snd_soc_codec_set_drvdata(codec, priv); priv->codec = codec; priv->workqueue = create_singlethread_workqueue("twl6040-codec"); if (!priv->workqueue) goto work_err; priv->hfl_gain = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN); priv->hfr_gain = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN); priv->hs_gain = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN); INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work); mutex_init(&priv->mutex); /* switch-class based headset detection */ jack = &priv->hs_jack; jack->sdev.name = "h2w"; ret = switch_dev_register(&jack->sdev); if (ret) { dev_err(codec->dev, "error registering switch device %d\n", ret); goto switch_err; } //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] : add from DCM_GB wake_lock_init(&priv->wake_lock, WAKE_LOCK_SUSPEND, "twl6040"); ret = twl6040_request_irq(codec->control_data, TWL6040_IRQ_PLUG, twl6040_audio_handler, IRQF_NO_SUSPEND, "twl6040_irq_plug", codec); //--[[ LGE_UBIQUIX_MODIFIED_END : [email protected] : add from DCM_GB if (ret) { dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret); goto irq_err; } /* init vio registers */ twl6040_init_vio_regs(codec); /* power on device */ ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); if (ret) goto bias_err; snd_soc_add_controls(codec, twl6040_snd_controls, ARRAY_SIZE(twl6040_snd_controls)); twl6040_add_widgets(codec); /* TODO: read HS jack insertion status */ return 0; bias_err: twl6040_free_irq(codec->control_data, TWL6040_IRQ_PLUG, codec); irq_err: //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] : add from DCM_GB wake_lock_destroy(&priv->wake_lock); //--[[ LGE_UBIQUIX_MODIFIED_END : [email protected] : add from DCM_GB switch_dev_unregister(&jack->sdev); switch_err: destroy_workqueue(priv->workqueue); work_err: kfree(priv); return ret; }
static int __devinit twl6040_probe(struct platform_device *pdev) { struct twl4030_codec_data *pdata = pdev->dev.platform_data; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; unsigned int naudint; int audpwron; int ret, children = 0; u8 accctl; if(!pdata) { dev_err(&pdev->dev, "Platform data is missing\n"); return -EINVAL; } twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); if (!twl6040) return -ENOMEM; platform_set_drvdata(pdev, twl6040); twl6040_dev = pdev; twl6040->dev = &pdev->dev; mutex_init(&twl6040->mutex); mutex_init(&twl6040->io_mutex); twl6040->icrev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); if (twl6040->icrev < 0) { ret = twl6040->icrev; goto gpio1_err; } if (pdata && (twl6040_get_icrev(twl6040) > TWL6040_REV_1_0)) audpwron = pdata->audpwron_gpio; else audpwron = -EINVAL; if (pdata) naudint = pdata->naudint_irq; else naudint = 0; twl6040->audpwron = audpwron; twl6040->powered = 0; twl6040->irq = naudint; twl6040->irq_base = pdata->irq_base; init_completion(&twl6040->ready); if (gpio_is_valid(audpwron)) { ret = gpio_request(audpwron, "audpwron"); if (ret) goto gpio1_err; ret = gpio_direction_output(audpwron, 0); if (ret) goto gpio2_err; } if (naudint) { /* codec interrupt */ ret = twl6040_irq_init(twl6040); if (ret) goto gpio2_err; ret = twl6040_request_irq(twl6040, TWL6040_IRQ_READY, twl6040_naudint_handler, "twl6040_irq_ready", twl6040); if (ret) { dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); goto irq_err; } } /* dual-access registers controlled by I2C only */ accctl = twl6040_reg_read(twl6040, TWL6040_REG_ACCCTL); twl6040_reg_write(twl6040, TWL6040_REG_ACCCTL, accctl | TWL6040_I2CSEL); if (pdata->audio) { cell = &twl6040->cells[children]; cell->name = "twl6040-codec"; cell->platform_data = pdata->audio; cell->pdata_size = sizeof(*pdata->audio); children++; } if (pdata->vibra) { cell = &twl6040->cells[children]; cell->name = "twl6040-vibra"; cell->platform_data = pdata->vibra; cell->pdata_size = sizeof(*pdata->vibra); children++; } if (children) { ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, children, NULL, 0); if (ret) goto mfd_err; } else { dev_err(&pdev->dev, "No platform data found for children\n"); ret = -ENODEV; goto mfd_err; } return 0; mfd_err: if (naudint) twl6040_free_irq(twl6040, TWL6040_IRQ_READY, twl6040); irq_err: if (naudint) twl6040_irq_exit(twl6040); gpio2_err: if (gpio_is_valid(audpwron)) gpio_free(audpwron); gpio1_err: platform_set_drvdata(pdev, NULL); kfree(twl6040); twl6040_dev = NULL; return ret; }