コード例 #1
0
ファイル: twl6040.c プロジェクト: panhenry/MyTest
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;
}
コード例 #2
0
ファイル: twl6040-codec.c プロジェクト: AdiPat/i9003_Kernel
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;
}
コード例 #3
0
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;
}
コード例 #4
0
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;
}
コード例 #5
0
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;
}