static int twl6040_probe(struct snd_soc_codec *codec) { struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev); 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; #if TWL6040_DEBUG /////////////////////////////////////////////////////////////////////////////////////////////////// { codec_twl6040 = codec->control_data; ret = device_create_file(codec->dev, &dev_attr_reg); if (ret < 0) printk(KERN_WARNING "twl6040: failed to add entries\n"); ret = device_create_file(codec->dev, &dev_attr_val); if (ret < 0) printk(KERN_WARNING "twl6040: failed to add entries\n"); ret = device_create_file(codec->dev, &dev_attr_prt); if (ret < 0) printk(KERN_WARNING "twl6040: failed to add entries\n"); } /////////////////////////////////////////////////////////////////////////////////////////////////// #endif 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); priv->vddhf_reg = regulator_get(codec->dev, "vddhf"); if (IS_ERR(priv->vddhf_reg)) { ret = PTR_ERR(priv->vddhf_reg); dev_warn(codec->dev, "couldn't get VDDHF regulator %d\n", ret); priv->vddhf_reg = NULL; } if (priv->vddhf_reg) { ret = regulator_set_voltage(priv->vddhf_reg, pdata->vddhf_uV, pdata->vddhf_uV); if (ret) { dev_warn(codec->dev, "failed to set VDDHF voltage %d\n", ret); goto reg_err; } } /* 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 reg_err; } 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); 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: wake_lock_destroy(&priv->wake_lock); switch_dev_unregister(&jack->sdev); reg_err: if (priv->vddhf_reg) regulator_put(priv->vddhf_reg); destroy_workqueue(priv->workqueue); work_err: kfree(priv); return ret; }
static int __devinit twl6040_codec_probe(struct platform_device *pdev) { struct twl4030_codec_data *pdata = pdev->dev.platform_data; struct twl6040_codec *twl6040; struct mfd_cell *cell = NULL; unsigned int naudint; int audpwron; int ret, children = 0; u8 icrev = 0, accctl; if(!pdata) { dev_err(&pdev->dev, "Platform data is missing\n"); return -EINVAL; } twl6040 = kzalloc(sizeof(struct twl6040_codec), GFP_KERNEL); if (!twl6040) return -ENOMEM; platform_set_drvdata(pdev, twl6040); twl6040_codec_dev = pdev; twl6040->dev = &pdev->dev; mutex_init(&twl6040->mutex); mutex_init(&twl6040->io_mutex); icrev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); if (pdata && (icrev > 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->data_size = sizeof(*pdata->audio); children++; } if (pdata->vibra) { cell = &twl6040->cells[children]; cell->name = "vib-twl6040"; cell->platform_data = pdata->vibra; cell->data_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_codec_dev = NULL; return ret; }
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_vibra_probe(struct platform_device *pdev) { struct twl4030_vibra_data *pdata = pdev->dev.platform_data; struct vibra_info *info; int ret; if (!pdata) { dev_err(&pdev->dev, "platform_data not available\n"); return -EINVAL; } info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { dev_err(&pdev->dev, "couldn't allocate memory\n"); return -ENOMEM; } info->dev = &pdev->dev; info->twl6040 = dev_get_drvdata(pdev->dev.parent); info->vibldrv_res = pdata->vibldrv_res; info->vibrdrv_res = pdata->vibrdrv_res; info->viblmotor_res = pdata->viblmotor_res; info->vibrmotor_res = pdata->vibrmotor_res; if ((!info->vibldrv_res && !info->viblmotor_res) || (!info->vibrdrv_res && !info->vibrmotor_res)) { dev_err(info->dev, "invalid vibra driver/motor resistance\n"); ret = -EINVAL; goto err_kzalloc; } mutex_init(&info->mutex); info->input_dev = input_allocate_device(); if (info->input_dev == NULL) { dev_err(info->dev, "couldn't allocate input device\n"); ret = -ENOMEM; goto err_kzalloc; } input_set_drvdata(info->input_dev, info); info->input_dev->name = "twl6040:vibrator"; info->input_dev->id.version = 1; info->input_dev->dev.parent = pdev->dev.parent; info->input_dev->close = twl6040_vibra_close; __set_bit(FF_RUMBLE, info->input_dev->ffbit); ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); if (ret < 0) { dev_err(info->dev, "couldn't register vibrator to FF\n"); goto err_ialloc; } ret = input_register_device(info->input_dev); if (ret < 0) { dev_err(info->dev, "couldn't register input device\n"); goto err_iff; } platform_set_drvdata(pdev, info); ret = twl6040_request_irq(info->twl6040, TWL6040_IRQ_VIB, twl6040_vib_irq_handler, 0, "twl6040_irq_vib", info); if (ret) { dev_err(info->dev, "VIB IRQ request failed: %d\n", ret); goto err_irq; } info->supplies[0].supply = "vddvibl"; info->supplies[1].supply = "vddvibr"; ret = regulator_bulk_get(info->dev, ARRAY_SIZE(info->supplies), info->supplies); if (ret) { dev_err(info->dev, "couldn't get regulators %d\n", ret); goto err_regulator; } if (pdata->vddvibl_uV) { ret = regulator_set_voltage(info->supplies[0].consumer, pdata->vddvibl_uV, pdata->vddvibl_uV); if (ret) { dev_err(info->dev, "failed to set VDDVIBL volt %d\n", ret); goto err_voltage; } } if (pdata->vddvibr_uV) { ret = regulator_set_voltage(info->supplies[1].consumer, pdata->vddvibr_uV, pdata->vddvibr_uV); if (ret) { dev_err(info->dev, "failed to set VDDVIBR volt %d\n", ret); goto err_voltage; } } info->workqueue = alloc_workqueue("twl6040-vibra", 0, 0); if (info->workqueue == NULL) { dev_err(info->dev, "couldn't create workqueue\n"); ret = -ENOMEM; goto err_voltage; } INIT_WORK(&info->play_work, vibra_play_work); return 0; err_voltage: regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); err_regulator: twl6040_free_irq(info->twl6040, TWL6040_IRQ_VIB, info); err_irq: input_unregister_device(info->input_dev); info->input_dev = NULL; err_iff: if (info->input_dev) input_ff_destroy(info->input_dev); err_ialloc: input_free_device(info->input_dev); err_kzalloc: kfree(info); return ret; }
static int vib_probe(struct platform_device *pdev) { struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; struct vib_data *data; int ret = 0; if (!pdata) { ret = -EBUSY; goto err0; } data = kzalloc(sizeof(struct vib_data), GFP_KERNEL); if (!data) { ret = -ENOMEM; goto err0; } data->pdata = pdata; data->twl6040 = dev_get_drvdata(pdev->dev.parent); INIT_WORK(&data->vib_work, vib_update); hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); data->timer.function = vib_timer_func; spin_lock_init(&data->lock); data->dev.name = "vibrator"; data->dev.get_time = vib_get_time; data->dev.enable = vib_enable; ret = timed_output_dev_register(&data->dev); if (ret < 0) goto err1; if (data->pdata->init) ret = data->pdata->init(); if (ret < 0) goto err2; misc_data = data; platform_set_drvdata(pdev, data); mutex_init(&misc_data->io_mutex); ret = twl6040_request_irq(data->twl6040, TWL6040_IRQ_VIB, twl6040_vib_irq_handler, 0, "twl6040_irq_vib", data); if (ret) { pr_err("%s: VIB IRQ request failed: %d\n", __func__, ret); goto err2; } twl6040_enable(data->twl6040); vib_enable(&data->dev, data->pdata->initial_vibrate); return 0; err2: timed_output_dev_unregister(&data->dev); err1: kfree(data); err0: return ret; }