111205bb63e5c2e5174f377595103005b00c68370Amy Maloche/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
211205bb63e5c2e5174f377595103005b00c68370Amy Maloche *
311205bb63e5c2e5174f377595103005b00c68370Amy Maloche * This program is free software; you can redistribute it and/or modify
411205bb63e5c2e5174f377595103005b00c68370Amy Maloche * it under the terms of the GNU General Public License version 2 and
511205bb63e5c2e5174f377595103005b00c68370Amy Maloche * only version 2 as published by the Free Software Foundation.
611205bb63e5c2e5174f377595103005b00c68370Amy Maloche *
711205bb63e5c2e5174f377595103005b00c68370Amy Maloche * This program is distributed in the hope that it will be useful,
811205bb63e5c2e5174f377595103005b00c68370Amy Maloche * but WITHOUT ANY WARRANTY; without even the implied warranty of
911205bb63e5c2e5174f377595103005b00c68370Amy Maloche * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1011205bb63e5c2e5174f377595103005b00c68370Amy Maloche * GNU General Public License for more details.
1111205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
1211205bb63e5c2e5174f377595103005b00c68370Amy Maloche
1311205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/module.h>
1411205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/init.h>
1511205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/kernel.h>
1611205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/errno.h>
1711205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/platform_device.h>
1811205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/input.h>
1911205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/slab.h>
2011205bb63e5c2e5174f377595103005b00c68370Amy Maloche#include <linux/mfd/pm8xxx/core.h>
2111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
2211205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define VIB_DRV			0x4A
2311205bb63e5c2e5174f377595103005b00c68370Amy Maloche
2411205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define VIB_DRV_SEL_MASK	0xf8
2511205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define VIB_DRV_SEL_SHIFT	0x03
2611205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define VIB_DRV_EN_MANUAL_MASK	0xfc
2711205bb63e5c2e5174f377595103005b00c68370Amy Maloche
2811205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define VIB_MAX_LEVEL_mV	(3100)
2911205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define VIB_MIN_LEVEL_mV	(1200)
3011205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define VIB_MAX_LEVELS		(VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
3111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
3211205bb63e5c2e5174f377595103005b00c68370Amy Maloche#define MAX_FF_SPEED		0xff
3311205bb63e5c2e5174f377595103005b00c68370Amy Maloche
3411205bb63e5c2e5174f377595103005b00c68370Amy Maloche/**
3511205bb63e5c2e5174f377595103005b00c68370Amy Maloche * struct pm8xxx_vib - structure to hold vibrator data
3611205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @vib_input_dev: input device supporting force feedback
3711205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @work: work structure to set the vibration parameters
3811205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @dev: device supporting force feedback
3911205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @speed: speed of vibration set from userland
4011205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @active: state of vibrator
4111205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @level: level of vibration to set in the chip
4211205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @reg_vib_drv: VIB_DRV register value
4311205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
4411205bb63e5c2e5174f377595103005b00c68370Amy Malochestruct pm8xxx_vib {
4511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct input_dev *vib_input_dev;
4611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct work_struct work;
4711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct device *dev;
4811205bb63e5c2e5174f377595103005b00c68370Amy Maloche	int speed;
4911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	int level;
5011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	bool active;
5111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	u8  reg_vib_drv;
5211205bb63e5c2e5174f377595103005b00c68370Amy Maloche};
5311205bb63e5c2e5174f377595103005b00c68370Amy Maloche
5411205bb63e5c2e5174f377595103005b00c68370Amy Maloche/**
5511205bb63e5c2e5174f377595103005b00c68370Amy Maloche * pm8xxx_vib_read_u8 - helper to read a byte from pmic chip
5611205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @vib: pointer to vibrator structure
5711205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @data: placeholder for data to be read
5811205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @reg: register address
5911205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
6011205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib,
6111205bb63e5c2e5174f377595103005b00c68370Amy Maloche				 u8 *data, u16 reg)
6211205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
6311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	int rc;
6411205bb63e5c2e5174f377595103005b00c68370Amy Maloche
6511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	rc = pm8xxx_readb(vib->dev->parent, reg, data);
6611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (rc < 0)
6711205bb63e5c2e5174f377595103005b00c68370Amy Maloche		dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n",
6811205bb63e5c2e5174f377595103005b00c68370Amy Maloche				reg, rc);
6911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return rc;
7011205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
7111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
7211205bb63e5c2e5174f377595103005b00c68370Amy Maloche/**
7311205bb63e5c2e5174f377595103005b00c68370Amy Maloche * pm8xxx_vib_write_u8 - helper to write a byte to pmic chip
7411205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @vib: pointer to vibrator structure
7511205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @data: data to write
7611205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @reg: register address
7711205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
7811205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
7911205bb63e5c2e5174f377595103005b00c68370Amy Maloche				 u8 data, u16 reg)
8011205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
8111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	int rc;
8211205bb63e5c2e5174f377595103005b00c68370Amy Maloche
8311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	rc = pm8xxx_writeb(vib->dev->parent, reg, data);
8411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (rc < 0)
8511205bb63e5c2e5174f377595103005b00c68370Amy Maloche		dev_warn(vib->dev, "Error writing pm8xxx reg 0x%x(0x%x)\n",
8611205bb63e5c2e5174f377595103005b00c68370Amy Maloche				reg, rc);
8711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return rc;
8811205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
8911205bb63e5c2e5174f377595103005b00c68370Amy Maloche
9011205bb63e5c2e5174f377595103005b00c68370Amy Maloche/**
9111205bb63e5c2e5174f377595103005b00c68370Amy Maloche * pm8xxx_vib_set - handler to start/stop vibration
9211205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @vib: pointer to vibrator structure
9311205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @on: state to set
9411205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
9511205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
9611205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
9711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	int rc;
9811205bb63e5c2e5174f377595103005b00c68370Amy Maloche	u8 val = vib->reg_vib_drv;
9911205bb63e5c2e5174f377595103005b00c68370Amy Maloche
10011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (on)
10111205bb63e5c2e5174f377595103005b00c68370Amy Maloche		val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
10211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	else
10311205bb63e5c2e5174f377595103005b00c68370Amy Maloche		val &= ~VIB_DRV_SEL_MASK;
10411205bb63e5c2e5174f377595103005b00c68370Amy Maloche
10511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
10611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (rc < 0)
10711205bb63e5c2e5174f377595103005b00c68370Amy Maloche		return rc;
10811205bb63e5c2e5174f377595103005b00c68370Amy Maloche
10911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	vib->reg_vib_drv = val;
11011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return 0;
11111205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
11211205bb63e5c2e5174f377595103005b00c68370Amy Maloche
11311205bb63e5c2e5174f377595103005b00c68370Amy Maloche/**
11411205bb63e5c2e5174f377595103005b00c68370Amy Maloche * pm8xxx_work_handler - worker to set vibration level
11511205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @work: pointer to work_struct
11611205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
11711205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic void pm8xxx_work_handler(struct work_struct *work)
11811205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
11911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
12011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	int rc;
12111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	u8 val;
12211205bb63e5c2e5174f377595103005b00c68370Amy Maloche
12311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
12411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (rc < 0)
12511205bb63e5c2e5174f377595103005b00c68370Amy Maloche		return;
12611205bb63e5c2e5174f377595103005b00c68370Amy Maloche
12711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	/*
12811205bb63e5c2e5174f377595103005b00c68370Amy Maloche	 * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
12911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	 * scale the level to fit into these ranges.
13011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	 */
13111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (vib->speed) {
13211205bb63e5c2e5174f377595103005b00c68370Amy Maloche		vib->active = true;
13311205bb63e5c2e5174f377595103005b00c68370Amy Maloche		vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
13411205bb63e5c2e5174f377595103005b00c68370Amy Maloche						VIB_MIN_LEVEL_mV;
13511205bb63e5c2e5174f377595103005b00c68370Amy Maloche		vib->level /= 100;
13611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	} else {
13711205bb63e5c2e5174f377595103005b00c68370Amy Maloche		vib->active = false;
13811205bb63e5c2e5174f377595103005b00c68370Amy Maloche		vib->level = VIB_MIN_LEVEL_mV / 100;
13911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	}
14011205bb63e5c2e5174f377595103005b00c68370Amy Maloche
14111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	pm8xxx_vib_set(vib, vib->active);
14211205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
14311205bb63e5c2e5174f377595103005b00c68370Amy Maloche
14411205bb63e5c2e5174f377595103005b00c68370Amy Maloche/**
14511205bb63e5c2e5174f377595103005b00c68370Amy Maloche * pm8xxx_vib_close - callback of input close callback
14611205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @dev: input device pointer
14711205bb63e5c2e5174f377595103005b00c68370Amy Maloche *
14811205bb63e5c2e5174f377595103005b00c68370Amy Maloche * Turns off the vibrator.
14911205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
15011205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic void pm8xxx_vib_close(struct input_dev *dev)
15111205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
15211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct pm8xxx_vib *vib = input_get_drvdata(dev);
15311205bb63e5c2e5174f377595103005b00c68370Amy Maloche
15411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	cancel_work_sync(&vib->work);
15511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (vib->active)
15611205bb63e5c2e5174f377595103005b00c68370Amy Maloche		pm8xxx_vib_set(vib, false);
15711205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
15811205bb63e5c2e5174f377595103005b00c68370Amy Maloche
15911205bb63e5c2e5174f377595103005b00c68370Amy Maloche/**
16011205bb63e5c2e5174f377595103005b00c68370Amy Maloche * pm8xxx_vib_play_effect - function to handle vib effects.
16111205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @dev: input device pointer
16211205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @data: data of effect
16311205bb63e5c2e5174f377595103005b00c68370Amy Maloche * @effect: effect to play
16411205bb63e5c2e5174f377595103005b00c68370Amy Maloche *
16511205bb63e5c2e5174f377595103005b00c68370Amy Maloche * Currently this driver supports only rumble effects.
16611205bb63e5c2e5174f377595103005b00c68370Amy Maloche */
16711205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic int pm8xxx_vib_play_effect(struct input_dev *dev, void *data,
16811205bb63e5c2e5174f377595103005b00c68370Amy Maloche				  struct ff_effect *effect)
16911205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
17011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct pm8xxx_vib *vib = input_get_drvdata(dev);
17111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
17211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	vib->speed = effect->u.rumble.strong_magnitude >> 8;
17311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (!vib->speed)
17411205bb63e5c2e5174f377595103005b00c68370Amy Maloche		vib->speed = effect->u.rumble.weak_magnitude >> 9;
17511205bb63e5c2e5174f377595103005b00c68370Amy Maloche
17611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	schedule_work(&vib->work);
17711205bb63e5c2e5174f377595103005b00c68370Amy Maloche
17811205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return 0;
17911205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
18011205bb63e5c2e5174f377595103005b00c68370Amy Maloche
18111205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic int __devinit pm8xxx_vib_probe(struct platform_device *pdev)
18211205bb63e5c2e5174f377595103005b00c68370Amy Maloche
18311205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
18411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct pm8xxx_vib *vib;
18511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct input_dev *input_dev;
18611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	int error;
18711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	u8 val;
18811205bb63e5c2e5174f377595103005b00c68370Amy Maloche
18911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
19011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_dev = input_allocate_device();
19111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (!vib || !input_dev) {
19211205bb63e5c2e5174f377595103005b00c68370Amy Maloche		dev_err(&pdev->dev, "couldn't allocate memory\n");
19311205bb63e5c2e5174f377595103005b00c68370Amy Maloche		error = -ENOMEM;
19411205bb63e5c2e5174f377595103005b00c68370Amy Maloche		goto err_free_mem;
19511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	}
19611205bb63e5c2e5174f377595103005b00c68370Amy Maloche
19711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	INIT_WORK(&vib->work, pm8xxx_work_handler);
19811205bb63e5c2e5174f377595103005b00c68370Amy Maloche	vib->dev = &pdev->dev;
19911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	vib->vib_input_dev = input_dev;
20011205bb63e5c2e5174f377595103005b00c68370Amy Maloche
20111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	/* operate in manual mode */
20211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
20311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (error < 0)
20411205bb63e5c2e5174f377595103005b00c68370Amy Maloche		goto err_free_mem;
20511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	val &= ~VIB_DRV_EN_MANUAL_MASK;
20611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
20711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (error < 0)
20811205bb63e5c2e5174f377595103005b00c68370Amy Maloche		goto err_free_mem;
20911205bb63e5c2e5174f377595103005b00c68370Amy Maloche
21011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	vib->reg_vib_drv = val;
21111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
21211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_dev->name = "pm8xxx_vib_ffmemless";
21311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_dev->id.version = 1;
21411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_dev->dev.parent = &pdev->dev;
21511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_dev->close = pm8xxx_vib_close;
21611205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_set_drvdata(input_dev, vib);
21711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
21811205bb63e5c2e5174f377595103005b00c68370Amy Maloche
21911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	error = input_ff_create_memless(input_dev, NULL,
22011205bb63e5c2e5174f377595103005b00c68370Amy Maloche					pm8xxx_vib_play_effect);
22111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (error) {
22211205bb63e5c2e5174f377595103005b00c68370Amy Maloche		dev_err(&pdev->dev,
22311205bb63e5c2e5174f377595103005b00c68370Amy Maloche			"couldn't register vibrator as FF device\n");
22411205bb63e5c2e5174f377595103005b00c68370Amy Maloche		goto err_free_mem;
22511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	}
22611205bb63e5c2e5174f377595103005b00c68370Amy Maloche
22711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	error = input_register_device(input_dev);
22811205bb63e5c2e5174f377595103005b00c68370Amy Maloche	if (error) {
22911205bb63e5c2e5174f377595103005b00c68370Amy Maloche		dev_err(&pdev->dev, "couldn't register input device\n");
23011205bb63e5c2e5174f377595103005b00c68370Amy Maloche		goto err_destroy_memless;
23111205bb63e5c2e5174f377595103005b00c68370Amy Maloche	}
23211205bb63e5c2e5174f377595103005b00c68370Amy Maloche
23311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	platform_set_drvdata(pdev, vib);
23411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return 0;
23511205bb63e5c2e5174f377595103005b00c68370Amy Maloche
23611205bb63e5c2e5174f377595103005b00c68370Amy Malocheerr_destroy_memless:
23711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_ff_destroy(input_dev);
23811205bb63e5c2e5174f377595103005b00c68370Amy Malocheerr_free_mem:
23911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_free_device(input_dev);
24011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	kfree(vib);
24111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
24211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return error;
24311205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
24411205bb63e5c2e5174f377595103005b00c68370Amy Maloche
24511205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic int __devexit pm8xxx_vib_remove(struct platform_device *pdev)
24611205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
24711205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct pm8xxx_vib *vib = platform_get_drvdata(pdev);
24811205bb63e5c2e5174f377595103005b00c68370Amy Maloche
24911205bb63e5c2e5174f377595103005b00c68370Amy Maloche	input_unregister_device(vib->vib_input_dev);
25011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	kfree(vib);
25111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
25211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	platform_set_drvdata(pdev, NULL);
25311205bb63e5c2e5174f377595103005b00c68370Amy Maloche
25411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return 0;
25511205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
25611205bb63e5c2e5174f377595103005b00c68370Amy Maloche
25711205bb63e5c2e5174f377595103005b00c68370Amy Maloche#ifdef CONFIG_PM_SLEEP
25811205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic int pm8xxx_vib_suspend(struct device *dev)
25911205bb63e5c2e5174f377595103005b00c68370Amy Maloche{
26011205bb63e5c2e5174f377595103005b00c68370Amy Maloche	struct pm8xxx_vib *vib = dev_get_drvdata(dev);
26111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
26211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	/* Turn off the vibrator */
26311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	pm8xxx_vib_set(vib, false);
26411205bb63e5c2e5174f377595103005b00c68370Amy Maloche
26511205bb63e5c2e5174f377595103005b00c68370Amy Maloche	return 0;
26611205bb63e5c2e5174f377595103005b00c68370Amy Maloche}
26711205bb63e5c2e5174f377595103005b00c68370Amy Maloche#endif
26811205bb63e5c2e5174f377595103005b00c68370Amy Maloche
26911205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
27011205bb63e5c2e5174f377595103005b00c68370Amy Maloche
27111205bb63e5c2e5174f377595103005b00c68370Amy Malochestatic struct platform_driver pm8xxx_vib_driver = {
27211205bb63e5c2e5174f377595103005b00c68370Amy Maloche	.probe		= pm8xxx_vib_probe,
27311205bb63e5c2e5174f377595103005b00c68370Amy Maloche	.remove		= __devexit_p(pm8xxx_vib_remove),
27411205bb63e5c2e5174f377595103005b00c68370Amy Maloche	.driver		= {
27511205bb63e5c2e5174f377595103005b00c68370Amy Maloche		.name	= "pm8xxx-vib",
27611205bb63e5c2e5174f377595103005b00c68370Amy Maloche		.owner	= THIS_MODULE,
27711205bb63e5c2e5174f377595103005b00c68370Amy Maloche		.pm	= &pm8xxx_vib_pm_ops,
27811205bb63e5c2e5174f377595103005b00c68370Amy Maloche	},
27911205bb63e5c2e5174f377595103005b00c68370Amy Maloche};
280840a746be2beddd2ada0e5ba772147316d071f25JJ Dingmodule_platform_driver(pm8xxx_vib_driver);
28111205bb63e5c2e5174f377595103005b00c68370Amy Maloche
28211205bb63e5c2e5174f377595103005b00c68370Amy MalocheMODULE_ALIAS("platform:pm8xxx_vib");
28311205bb63e5c2e5174f377595103005b00c68370Amy MalocheMODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");
28411205bb63e5c2e5174f377595103005b00c68370Amy MalocheMODULE_LICENSE("GPL v2");
28511205bb63e5c2e5174f377595103005b00c68370Amy MalocheMODULE_AUTHOR("Amy Maloche <amaloche@codeaurora.org>");
286