static void pmic8058_work_handler(struct work_struct *work)
{
	u8 val;
	int rc;
	struct pmic8058_vib *info;

	info  = container_of(work, struct pmic8058_vib, work);

	rc = pmic8058_vib_read_u8(info, &val, VIB_DRV);
	if (rc < 0)
		return;

	/*
                                                        
                                      
  */
	if (info->speed) {
		info->state = 1;
		info->level = ((VIB_MAX_LEVELS * info->speed) / MAX_FF_SPEED) +
						VIB_MIN_LEVEL_mV;
		info->level /= 100;
	} else {
		info->state = 0;
		info->level = VIB_MIN_LEVEL_mV / 100;
	}
	pmic8058_vib_set(info, info->state);
}
static int __devinit pmic8058_vib_probe(struct platform_device *pdev)

{
	struct pmic8058_vibrator_pdata *pdata = pdev->dev.platform_data;
	struct pmic8058_vib *vib;
	u8 val;
	int rc;

	struct pm8058_chip	*pm_chip;

	pm_chip = platform_get_drvdata(pdev);
	if (pm_chip == NULL) {
		dev_err(&pdev->dev, "no parent data passed in\n");
		return -EFAULT;
	}

	if (!pdata)
		return -EINVAL;

	if (pdata->level_mV < VIB_MIN_LEVEL_mV ||
			 pdata->level_mV > VIB_MAX_LEVEL_mV)
		return -EINVAL;

	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->pm_chip	= pm_chip;
	vib->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

	spin_lock_init(&vib->lock);
	INIT_WORK(&vib->work, pmic8058_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = pmic8058_vib_timer_func;

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pmic8058_vib_get_time;
	vib->timed_dev.enable = pmic8058_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/* operate in manual mode */
	rc = pmic8058_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pmic8058_vib_write_u8(vib, val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;

	vib->reg_vib_drv = val;

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		goto err_read_vib;

	pmic8058_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);

	platform_set_drvdata(pdev, vib);

	return 0;

err_read_vib:
	kfree(vib);
	return rc;
}
static int __devinit pmic8058_vib_probe(struct platform_device *pdev)

{
	struct pmic8058_vibrator_pdata *pdata = pdev->dev.platform_data;
	struct pmic8058_vib *vib;
	u8 val;
	int rc;

	struct pm8058_chip	*pm_chip;

	pm_chip = dev_get_drvdata(pdev->parent.dev);
	if (pm_chip == NULL) {
		dev_err(&pdev->dev, "no parent data passed in\n");
		return -EFAULT;
	}

	if (!pdata)
		return -EINVAL;

	if (pdata->level_mV < VIB_MIN_LEVEL_mV ||
			 pdata->level_mV > VIB_MAX_LEVEL_mV)
		return -EINVAL;

	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->pm_chip	= pm_chip;
	vib->enabled	= 0;
	vib->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

	spin_lock_init(&vib->lock);
	INIT_WORK(&vib->work, pmic8058_work_handler);

	vib->info = input_allocate_device();

	if (vib->info == NULL) {
		dev_err(&pdev->dev, "couldn't allocate input device\n");
		return -ENOMEM;
	}

	input_set_drvdata(vib->info, vib);

	vib->info->name = "pmic8058:vibrator";
	vib->info->id.version = 1;
	vib->info->dev.parent = pdev->dev.parent;

	__set_bit(FF_RUMBLE, vib->info->ffbit);
	__dump_vib_regs(vib, "boot_vib_default");

	/*                        */
	rc = pmic8058_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pmic8058_vib_write_u8(vib, val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;

	vib->reg_vib_drv = val;

	rc = input_ff_create_memless(vib->info, NULL, pmic8058_vib_play_effect);
	if (rc < 0) {
		dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
		goto create_memless_err;
	}

	platform_set_drvdata(pdev, vib);

	rc = input_register_device(vib->info);
	if (rc < 0) {
		dev_dbg(&pdev->dev, "couldn't register input device\n");
		goto reg_err;
	}

	return 0;

reg_err:
	input_ff_destroy(vib->info);
create_memless_err:
	input_free_device(vib->info);
err_read_vib:
	kfree(vib);
	return rc;
}
Ejemplo n.º 4
0
//[SIMT-lilening-20110804]}
static int __devinit pmic8058_vib_probe(struct platform_device *pdev)

{
	struct pmic8058_vibrator_pdata *pdata = pdev->dev.platform_data;
	struct pmic8058_vib *vib;
	u8 val;
	int rc;

	struct pm8058_chip	*pm_chip;

	pm_chip = platform_get_drvdata(pdev);
	if (pm_chip == NULL) {
		dev_err(&pdev->dev, "no parent data passed in\n");
		return -EFAULT;
	}

	if (!pdata)
		return -EINVAL;

	if (pdata->level_mV < VIB_MIN_LEVEL_mV ||
			 pdata->level_mV > VIB_MAX_LEVEL_mV)
		return -EINVAL;

	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	/* Enable runtime PM ops, start in ACTIVE mode */
	rc = pm_runtime_set_active(&pdev->dev);
	if (rc < 0)
		dev_dbg(&pdev->dev, "unable to set runtime pm state\n");
	pm_runtime_enable(&pdev->dev);

	vib->pm_chip	= pm_chip;
	vib->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

	spin_lock_init(&vib->lock);
	INIT_WORK(&vib->work, pmic8058_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = pmic8058_vib_timer_func;

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pmic8058_vib_get_time;
	vib->timed_dev.enable = pmic8058_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/* operate in manual mode */
	rc = pmic8058_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pmic8058_vib_write_u8(vib, val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;

	vib->reg_vib_drv = val;

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		goto err_read_vib;

	//[SIM-chengbin-110926] del the second vib event 
    #if  0
	pmic8058_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
    #endif

	platform_set_drvdata(pdev, vib);

	pm_runtime_set_suspended(&pdev->dev);
//[SIMT-lilening-20110804] add vibrator start voltage{
	rc = device_create_file(&pdev->dev, &dev_attr_vib_set);
	if(rc)
		return rc;
//[SIMT-lilening-20110804]}
	return 0;

err_read_vib:
	pm_runtime_set_suspended(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	kfree(vib);
	return rc;
}