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