static int pm8xxx_vib_set(struct pm8xxx_vib *vib, int on)
{
	int rc;
	u8 val;
/* LGE_CHANGE_S */
	unsigned long flags;

	spin_lock_irqsave(&vib->lock, flags);
/* LGE_CHANGE_E */

	if (on) {
		val = vib->reg_vib_drv;
		val &= ~VIB_DRV_SEL_MASK;
		val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
		rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
		if (rc < 0)
			return rc;
		vib->reg_vib_drv = val;
	} else {
		val = vib->reg_vib_drv;
		val &= ~VIB_DRV_SEL_MASK;
		rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
		if (rc < 0)
			return rc;
		vib->reg_vib_drv = val;
	}
	__dump_vib_regs(vib, "vib_set_end");

/* LGE_CHANGE_S */
    if(unlikely(debug_mask))
        printk(KERN_INFO "pm8xxx_vib_set vib->level:%d, val:0x%x\n",vib->level,val);

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_REST_POWER
	if(on)
	{
		if(vib->vib_state == 0)
		{
			vib->vib_state = 1;
			do_gettimeofday(&(vib->start_tv));
		}
	}
	else
	{
		if(vib->vib_state == 1)
		{
			vib->vib_state = 0;
			do_gettimeofday(&(vib->stop_tv));
		}
	}
#endif

	spin_unlock_irqrestore(&vib->lock, flags);
/* LGE_CHANGE_E */

	return rc;
}
Beispiel #2
0
static int pm8xxx_vib_set(struct pm8xxx_vib *vib, int on, int time)
{
    int rc;
    u8 val;

    mutex_lock(&vib->vib_mutex);
    VIB_DEBUG_LOG(KERN_INFO, "called. on=%d,time=%d\n", on, time);
    if (on) {
        VIB_DEBUG_LOG(KERN_INFO, "VIB ON.reg_vib_drv=0x%02X,level=0x%02X\n",
                                              vib->reg_vib_drv, vib->level);
        val = vib->reg_vib_drv;
        val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
        rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
        VIB_DEBUG_LOG(KERN_INFO,
                      "pm8xxx_vib_write_u8 called.rc=%d,val=0x%02X\n", rc, val);
        if (rc < 0) {
            VIB_DEBUG_LOG(KERN_INFO, "pm8xxx_vib_write_u8() error. rc=%d\n",
                                                                        rc);
            mutex_unlock(&vib->vib_mutex);
            return rc;
        }
        vib->reg_vib_drv = val;
        hrtimer_start(&vib->vib_timer,
                  ktime_set(time / 1000, (time % 1000) * 1000000),
                  HRTIMER_MODE_REL);
    } else {
        VIB_DEBUG_LOG(KERN_INFO, "VIB OFF.reg_vib_drv=0x%02X,level=0x%02X\n",
                                               vib->reg_vib_drv, vib->level);
        val = vib->reg_vib_drv;
        val &= ~VIB_DRV_SEL_MASK;
        rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
        VIB_DEBUG_LOG(KERN_INFO,
                      "pm8xxx_vib_write_u8 called.rc=%d,val=0x%02X\n", rc, val);
        if (rc < 0) {
            VIB_DEBUG_LOG(KERN_INFO, "pm8xxx_vib_write_u8() error. rc=%d\n"
                                                                     , rc);
            mutex_unlock(&vib->vib_mutex);
            return rc;
        }
        vib->reg_vib_drv = val;
    }
#ifdef DEBUG_VIB_PM8XXX
    __dump_vib_regs(vib, "vib_set_end");
#endif /* DEBUG_VIB_PM8XXX */

    mutex_unlock(&vib->vib_mutex);
    VIB_DEBUG_LOG(KERN_INFO, "end.rc=%d,reg_vib_drv=0x%02X\n", rc,
                                                vib->reg_vib_drv);
    return rc;
}
// LGE_CHANGE_S [[email protected]], add for debugging & tunning
// echo strength(0~31) duration > /sys/class/timed_output/vibrator/amp_test
static ssize_t pm8xxx_amp_test_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
    struct timed_output_dev *dev_ = (struct timed_output_dev *)dev_get_drvdata(dev);
    struct pm8xxx_vib *vib = container_of(dev_, struct pm8xxx_vib, timed_dev);
    int val, ms;

    sscanf(buf, "%d %d", &val, &ms);
	val = ((val << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
    pm8xxx_vib_write_u8(vib, val, VIB_DRV);
    mdelay(ms);
    pm8xxx_vib_write_u8(vib, 0, VIB_DRV);

    return size;
}
static int pm8xxx_vib_set(struct pm8xxx_vib *vib, int on)
{
	int rc;
	u8 val;

	if (on) {
		val = vib->reg_vib_drv;
		val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
		rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
		if (rc < 0)
			return rc;
		vib->reg_vib_drv = val;
/*add for PM_log*/
#ifdef CONFIG_PM_LOG
		rc = pmlog_device_on(vib->pmlog_device);
		if (rc)
			printk("pmlog_device_on fall rc = %d\n",rc);
#endif
/*Carl Chang,20120528*/
	} else {
		val = vib->reg_vib_drv;
		val &= ~VIB_DRV_SEL_MASK;
		rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
		if (rc < 0)
			return rc;
		vib->reg_vib_drv = val;
/*add for PM_log*/
#ifdef CONFIG_PM_LOG
                rc = pmlog_device_off(vib->pmlog_device);
                if (rc)
                        printk("pmlog_device_off fall rc = %d\n",rc);
#endif
/*Carl Chang,20120528*/
	}
	__dump_vib_regs(vib, "vib_set_end");

	return rc;
}
Beispiel #5
0
static int pm8xxx_vib_set(struct pm8xxx_vib *vib, int on)
{
	int rc;
	u8 val;

	if (on) {
		val = vib->reg_vib_drv;
		val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
		rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
		if (rc < 0)
			return rc;
		vib->reg_vib_drv = val;
	} else {
		val = vib->reg_vib_drv;
		val &= ~VIB_DRV_SEL_MASK;
		rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
		if (rc < 0)
			return rc;
		vib->reg_vib_drv = val;
	}
	__dump_vib_regs(vib, "vib_set_end");

	return rc;
}
Beispiel #6
0
static int pm8xxx_vib_set_off(struct pm8xxx_vib *vib)
{
	int rc;
	u8 val2;
	val2 = vib->reg_vib_drv;
	val2 &= ~VIB_DRV_SEL_MASK;
	VIB_INFO_LOG("%s + val: %x \n", __func__, val2);
	rc = pm8xxx_vib_write_u8(vib, val2, VIB_DRV);
	if (rc < 0){
		VIB_ERR_LOG("%s writing pmic fail, ret:%X\n", __func__, rc);
		return rc;
	}
	__dump_vib_regs(vib, "vib_set_end");
	VIB_INFO_LOG("%s - \n", __func__);
	return rc;
}
Beispiel #7
0
static int pm8xxx_vib_set_on(struct pm8xxx_vib *vib)
{
	int rc;
	u8 val1;
	val1 = vib->reg_vib_drv;
	val1 &= ~VIB_DRV_SEL_MASK;
	val1 |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
	VIB_INFO_LOG("%s + val: %x \n", __func__, val1);
	rc = pm8xxx_vib_write_u8(vib, val1, VIB_DRV);
	if (rc < 0){
		VIB_ERR_LOG("%s writing pmic fail, ret:%X\n", __func__, rc);
		return rc;
	}
	__dump_vib_regs(vib, "vib_set_end");
	VIB_INFO_LOG("%s - \n", __func__);
	return rc;
}
static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
{
	int rc;
	u8 val = vib->reg_vib_drv;

	if (on)
		val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
	else
		val &= ~VIB_DRV_SEL_MASK;

	rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
	if (rc < 0)
		return rc;

	vib->reg_vib_drv = val;
	return 0;
}
Beispiel #9
0
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
	const struct pm8xxx_vibrator_platform_data *pdata =
						pdev->dev.platform_data;
	struct pm8xxx_vib *vib;
	u8 val;
	int rc;

	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->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

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

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

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pm8xxx_vib_get_time;
	vib->timed_dev.enable = pm8xxx_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/*
	 * Configure the vibrator, it operates in manual mode
	 * for timed_output framework.
	 */
	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pm8xxx_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;
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_voltage_level);
	if (rc < 0) {
		VIB_ERR_LOG("%s, create sysfs fail: voltage_level\n", __func__);
	}

	platform_set_drvdata(pdev, vib);
	vib_dev = vib;
	return 0;

err_read_vib:
	kfree(vib);
	return rc;
}
static int vibrator_probe(struct platform_device *pdev)
{
    int nRet, i;   /* initialized below */

#if !defined(CONFIG_MACH_LGE_L9II_OPEN_EU)
    u8 val;

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

    vib_dev->dev = &pdev->dev;
#endif

    printk("[VIBRATOR] tspdrv_probe.!!\n");

#ifdef IMPLEMENT_AS_CHAR_DRIVER
    g_nMajor = register_chrdev(0, MODULE_NAME, &fops);
    if (g_nMajor < 0) 
    {
        DbgOut((KERN_ERR "tspdrv: can't get major number.\n"));
        return g_nMajor;
    }
#else
    nRet = misc_register(&miscdev);
	if (nRet) 
    {
        DbgOut((KERN_ERR "tspdrv: misc_register failed.\n"));
		return nRet;
	}
#endif

    DbgRecorderInit(());
    ImmVibeSPI_ForceOut_Initialize();
    VibeOSKernelLinuxInitTimer();

    /* Get and concatenate device name and initialize data buffer */
    g_cchDeviceName = 0;
    for (i=0; i<NUM_ACTUATORS; i++)
    {
        char *szName = g_szDeviceName + g_cchDeviceName;
        ImmVibeSPI_Device_GetName(i, szName, VIBE_MAX_DEVICE_NAME_LENGTH);

        /* Append version information and get buffer length */
        strcat(szName, VERSION_STR);
        g_cchDeviceName += strlen(szName);

        g_SamplesBuffer[i].nIndexPlayingBuffer = -1; /* Not playing */
        g_SamplesBuffer[i].actuatorSamples[0].nBufferSize = 0;
        g_SamplesBuffer[i].actuatorSamples[1].nBufferSize = 0;
    }

#if !defined(CONFIG_MACH_LGE_L9II_OPEN_EU)
    nRet = pm8xxx_vib_read_u8(vib_dev, &val, VIB_DRV);
    if (nRet < 0)
        goto err_read_vib;

    val &= ~VIB_DRV_EN_MANUAL_MASK;
    nRet = pm8xxx_vib_write_u8(vib_dev, val, VIB_DRV);
    if (nRet < 0)
        goto err_read_vib;

    vib_dev->reg_vib_drv = val;

    return 0;

err_read_vib :
    kfree(vib_dev);
    return nRet;
#else
	return 0;
#endif
}
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
	const struct pm8xxx_vibrator_platform_data *pdata =
						pdev->dev.platform_data;
	struct pm8xxx_vib *vib;
	u8 val;
	int rc;
	printk("[vibrator] %s ,probe+++++ \n",__func__ );/*Carl Chang*/

	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->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

	//spin_lock_init(&vib->lock);
	mutex_init(&vib->lock);
	/*Register PM_log*/
#ifdef CONFIG_PM_LOG
	vib->pmlog_device = pmlog_register_device(&pdev->dev);
#endif
	/*Carl Chang,20120528*/
	INIT_WORK(&vib->work, pm8xxx_vib_update);

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

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pm8xxx_vib_get_time;
	vib->timed_dev.enable = pm8xxx_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/*
	 * Configure the vibrator, it operates in manual mode
	 * for timed_output framework.
	 */
	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pm8xxx_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;

	//pm8xxx_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
	// Carl Chang, 20120829, remove initial vibrate

	platform_set_drvdata(pdev, vib);

	vib_dev = vib;

	/* Add for debugfs and fvs mode test */
	vibrator_create_debugfs_entries(vib_dev);
	vibrator_create_kernel_debuglevel_entries();
	/* Emily Jiang, 20120201 */
	printk("[vibrator] %s ,probe----- \n",__func__ );/*Carl Chang*/
	
	return 0;

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

{
	struct pm8xxx_vib *vib;
	struct input_dev *input_dev;
	int error;
	u8 val;

	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!vib || !input_dev) {
		dev_err(&pdev->dev, "couldn't allocate memory\n");
		error = -ENOMEM;
		goto err_free_mem;
	}

	INIT_WORK(&vib->work, pm8xxx_work_handler);
	vib->dev = &pdev->dev;
	vib->vib_input_dev = input_dev;

	
	error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (error < 0)
		goto err_free_mem;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
	if (error < 0)
		goto err_free_mem;

	vib->reg_vib_drv = val;

	input_dev->name = "pm8xxx_vib_ffmemless";
	input_dev->id.version = 1;
	input_dev->dev.parent = &pdev->dev;
	input_dev->close = pm8xxx_vib_close;
	input_set_drvdata(input_dev, vib);
	input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);

	error = input_ff_create_memless(input_dev, NULL,
					pm8xxx_vib_play_effect);
	if (error) {
		dev_err(&pdev->dev,
			"couldn't register vibrator as FF device\n");
		goto err_free_mem;
	}

	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev, "couldn't register input device\n");
		goto err_destroy_memless;
	}

	platform_set_drvdata(pdev, vib);
	return 0;

err_destroy_memless:
	input_ff_destroy(input_dev);
err_free_mem:
	input_free_device(input_dev);
	kfree(vib);

	return error;
}
Beispiel #13
0
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
	const struct pm8xxx_vibrator_platform_data *pdata =
						pdev->dev.platform_data;
	struct pm8xxx_vib *vib;
	u8 val;
	int rc;

	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->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

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

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

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pm8xxx_vib_get_time;
	vib->timed_dev.enable = pm8xxx_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/*
	 * Configure the vibrator, it operates in manual mode
	 * for timed_output framework.
	 */
	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pm8xxx_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;

	/*PERI-AH-VIBRATOR_Add_level_file_node-00+[ */
	vib_Level = vib->level;
	dev_info(&pdev->dev, "default vib_Level %d \n", vib_Level);
	
	/* Set voltage parameter of vibrator(corresponding to the file node /sys/class/timed_output/vibrator/level) */
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_level);	
	if (rc) {
		dev_err(&pdev->dev, "dev_attr_level device_create_file failed\n");
		device_remove_file(vib->timed_dev.dev, &dev_attr_level);
	}
	/*PERI-AH-VIBRATOR_Add_level_file_node-00+[ */

	#ifdef INIT_VIB_ENABLE
	pm8xxx_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
	#endif

	platform_set_drvdata(pdev, vib);

	vib_dev = vib;

	return 0;

err_read_vib:
	kfree(vib);
	return rc;
}
Beispiel #14
0
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
	const struct pm8xxx_vibrator_platform_data *pdata =
						pdev->dev.platform_data;
	struct pm8xxx_vib *vib;
	u8 val;
	int rc;

	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->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->pre_value  = 0;
	vib->dev	= &pdev->dev;

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

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

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pm8xxx_vib_get_time;
	vib->timed_dev.enable = pm8xxx_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/*
	 * Configure the vibrator, it operates in manual mode
	 * for timed_output framework.
	 */
	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pm8xxx_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;

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_VOL
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_amp);
	if (rc < 0)
		goto err_read_vib;

	/* no vibration during initialization, [email protected], 01/02/2012 */
	//pm8xxx_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
#else
	pm8xxx_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
#endif

	platform_set_drvdata(pdev, vib);

	vib_dev = vib;

	return 0;

err_read_vib:
	kfree(vib);
	return rc;
}
Beispiel #15
0
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
    const struct pm8xxx_vibrator_platform_data *pdata =
                        pdev->dev.platform_data;
    struct pm8xxx_vib *vib;
    u8 val;
    int rc;
    int count = 0;

    VIB_DEBUG_LOG(KERN_INFO, "called.\n");
    if (!pdata) {
        VIB_LOG(KERN_ERR, "pdata is NULL\n");
        return -EINVAL;
    }

    if (pdata->level_mV < VIB_MIN_LEVEL_mV ||
             pdata->level_mV > VIB_MAX_LEVEL_mV) {
        VIB_LOG(KERN_ERR, "level_mV error. level_mV=%d\n",
                                         pdata->level_mV);
        return -EINVAL;
    }

    vib = kzalloc(sizeof(*vib), GFP_KERNEL);
    if (!vib) {
        VIB_LOG(KERN_ERR, "kzalloc error.\n");
        return -ENOMEM;
    }

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

    mutex_init(&vib->vib_mutex);
    for (count = 0; count < VIB_WORK_NUM; count++) {
        INIT_WORK(&(vib->vib_on_work_data[count].work_vib_on),
                                          pm8xxx_vibrator_on);
        INIT_WORK(&vib->work_vib_off[count], pm8xxx_vibrator_off);
        vib->vib_on_work_data[count].vib_time = 0;
        VIB_DEBUG_LOG(KERN_INFO, "vib_on_work_data[%d].vib_time=%d\n", count,
                                      vib->vib_on_work_data[count].vib_time);
    }

    vib->work_vib_on_pos = 0;
    vib->work_vib_off_pos = 0;

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

    vib->timed_dev.name = "vibrator";
    vib->timed_dev.get_time = pm8xxx_vib_get_time;
    vib->timed_dev.enable = pm8xxx_vib_enable;

#ifdef DEBUG_VIB_PM8XXX
    __dump_vib_regs(vib, "boot_vib_default");
#endif /* DEBUG_VIB_PM8XXX */

    /*
     * Configure the vibrator, it operates in manual mode
     * for timed_output framework.
     */
    rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
    if (rc < 0) {
        VIB_LOG(KERN_ERR, "pm8xxx_vib_read_u8 error. rc=%d\n", rc);
        goto err_read_vib;
    }
    val &= ~VIB_DRV_EN_MANUAL_MASK;
    rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
    if (rc < 0) {
        VIB_LOG(KERN_ERR, "pm8xxx_vib_write_u8 error. rc=%d\n", rc);
        goto err_read_vib;
    }

    vib->reg_vib_drv = val;

    rc = timed_output_dev_register(&vib->timed_dev);
    if (rc < 0) {
        VIB_LOG(KERN_ERR, "timed_output_dev_register error. rc=%d\n", rc);
        goto err_read_vib;
    }

    platform_set_drvdata(pdev, vib);

    vib_dev = vib;

    VIB_DEBUG_LOG(KERN_INFO, "end.rc=%d\n", 0);
    return 0;

err_read_vib:
    VIB_DEBUG_LOG(KERN_INFO, "err_read_vib.\n");
    kfree(vib);
    VIB_DEBUG_LOG(KERN_INFO, "end.rc=%d\n", rc);
    return rc;
}
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
	const struct pm8xxx_vibrator_platform_data *pdata =
						pdev->dev.platform_data;
	struct pm8xxx_vib *vib;
	u8 val;
	int rc;

	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->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_VOL
	vib->default_level  = vib->level;
	vib->request_level  = vib->level;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_MIN_TIMEOUT
	vib->min_timeout_ms  = pdata->min_timeout_ms;
	vib->pre_value  = 0;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_OVERDRIVE
	vib->overdrive_ms  = pdata->overdrive_ms;
	vib->overdrive_range_ms  = pdata->overdrive_range_ms;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_REST_POWER
	vib->min_stop_ms  = pdata->min_stop_ms;
	vib->start_tv.tv_sec = 0;
	vib->start_tv.tv_usec = 0;
	vib->stop_tv.tv_sec = 0;
	vib->stop_tv.tv_usec = 0;
#endif

    vib->max_level_mv = VIB_MAX_LEVEL_mV;
    vib->min_level_mv = VIB_MIN_LEVEL_mV;

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

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

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_OVERDRIVE
	hrtimer_init(&vib->vib_overdrive_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_overdrive_timer.function = pm8xxx_vib_overdrive_timer_func;
#endif

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pm8xxx_vib_get_time;
	vib->timed_dev.enable = pm8xxx_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/*
	 * Configure the vibrator, it operates in manual mode
	 * for timed_output framework.
	 */
	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pm8xxx_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;

    rc = sysfs_create_group(&vib->timed_dev.dev->kobj, &pm8xxx_vib_attr_group);

#if 0

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_VOL
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_amp);
	if (rc < 0)
		goto err_read_vib;

	rc = device_create_file(vib->timed_dev.dev, &dev_attr_default_level);
	if (rc < 0)
		goto err_read_vib;
#endif

// LGE does not use this function. power on vib effect is played at SBL3
#ifndef CONFIG_MACH_LGE
	pm8xxx_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_MIN_TIMEOUT
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_min_ms);
	if (rc < 0)
		goto err_read_vib;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_OVERDRIVE
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_over_ms);
	if (rc < 0)
		goto err_read_vib;

	rc = device_create_file(vib->timed_dev.dev, &dev_attr_over_range_ms);
	if (rc < 0)
		goto err_read_vib;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_REST_POWER
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_min_stop_ms);
	if (rc < 0)
		goto err_read_vib;
#endif

#endif // #if 0
	platform_set_drvdata(pdev, vib);

	vib_dev = vib;

	return 0;

err_read_vib:
	kfree(vib);
	return rc;
}