linux/drivers/input/misc/pm8xxx-vibrator.c
<<
>>
Prefs
   1/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
   2 *
   3 * This program is free software; you can redistribute it and/or modify
   4 * it under the terms of the GNU General Public License version 2 and
   5 * only version 2 as published by the Free Software Foundation.
   6 *
   7 * This program is distributed in the hope that it will be useful,
   8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 * GNU General Public License for more details.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/init.h>
  15#include <linux/kernel.h>
  16#include <linux/errno.h>
  17#include <linux/platform_device.h>
  18#include <linux/input.h>
  19#include <linux/slab.h>
  20#include <linux/mfd/pm8xxx/core.h>
  21
  22#define VIB_DRV                 0x4A
  23
  24#define VIB_DRV_SEL_MASK        0xf8
  25#define VIB_DRV_SEL_SHIFT       0x03
  26#define VIB_DRV_EN_MANUAL_MASK  0xfc
  27
  28#define VIB_MAX_LEVEL_mV        (3100)
  29#define VIB_MIN_LEVEL_mV        (1200)
  30#define VIB_MAX_LEVELS          (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
  31
  32#define MAX_FF_SPEED            0xff
  33
  34/**
  35 * struct pm8xxx_vib - structure to hold vibrator data
  36 * @vib_input_dev: input device supporting force feedback
  37 * @work: work structure to set the vibration parameters
  38 * @dev: device supporting force feedback
  39 * @speed: speed of vibration set from userland
  40 * @active: state of vibrator
  41 * @level: level of vibration to set in the chip
  42 * @reg_vib_drv: VIB_DRV register value
  43 */
  44struct pm8xxx_vib {
  45        struct input_dev *vib_input_dev;
  46        struct work_struct work;
  47        struct device *dev;
  48        int speed;
  49        int level;
  50        bool active;
  51        u8  reg_vib_drv;
  52};
  53
  54/**
  55 * pm8xxx_vib_read_u8 - helper to read a byte from pmic chip
  56 * @vib: pointer to vibrator structure
  57 * @data: placeholder for data to be read
  58 * @reg: register address
  59 */
  60static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib,
  61                                 u8 *data, u16 reg)
  62{
  63        int rc;
  64
  65        rc = pm8xxx_readb(vib->dev->parent, reg, data);
  66        if (rc < 0)
  67                dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n",
  68                                reg, rc);
  69        return rc;
  70}
  71
  72/**
  73 * pm8xxx_vib_write_u8 - helper to write a byte to pmic chip
  74 * @vib: pointer to vibrator structure
  75 * @data: data to write
  76 * @reg: register address
  77 */
  78static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
  79                                 u8 data, u16 reg)
  80{
  81        int rc;
  82
  83        rc = pm8xxx_writeb(vib->dev->parent, reg, data);
  84        if (rc < 0)
  85                dev_warn(vib->dev, "Error writing pm8xxx reg 0x%x(0x%x)\n",
  86                                reg, rc);
  87        return rc;
  88}
  89
  90/**
  91 * pm8xxx_vib_set - handler to start/stop vibration
  92 * @vib: pointer to vibrator structure
  93 * @on: state to set
  94 */
  95static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
  96{
  97        int rc;
  98        u8 val = vib->reg_vib_drv;
  99
 100        if (on)
 101                val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
 102        else
 103                val &= ~VIB_DRV_SEL_MASK;
 104
 105        rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
 106        if (rc < 0)
 107                return rc;
 108
 109        vib->reg_vib_drv = val;
 110        return 0;
 111}
 112
 113/**
 114 * pm8xxx_work_handler - worker to set vibration level
 115 * @work: pointer to work_struct
 116 */
 117static void pm8xxx_work_handler(struct work_struct *work)
 118{
 119        struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
 120        int rc;
 121        u8 val;
 122
 123        rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
 124        if (rc < 0)
 125                return;
 126
 127        /*
 128         * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
 129         * scale the level to fit into these ranges.
 130         */
 131        if (vib->speed) {
 132                vib->active = true;
 133                vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
 134                                                VIB_MIN_LEVEL_mV;
 135                vib->level /= 100;
 136        } else {
 137                vib->active = false;
 138                vib->level = VIB_MIN_LEVEL_mV / 100;
 139        }
 140
 141        pm8xxx_vib_set(vib, vib->active);
 142}
 143
 144/**
 145 * pm8xxx_vib_close - callback of input close callback
 146 * @dev: input device pointer
 147 *
 148 * Turns off the vibrator.
 149 */
 150static void pm8xxx_vib_close(struct input_dev *dev)
 151{
 152        struct pm8xxx_vib *vib = input_get_drvdata(dev);
 153
 154        cancel_work_sync(&vib->work);
 155        if (vib->active)
 156                pm8xxx_vib_set(vib, false);
 157}
 158
 159/**
 160 * pm8xxx_vib_play_effect - function to handle vib effects.
 161 * @dev: input device pointer
 162 * @data: data of effect
 163 * @effect: effect to play
 164 *
 165 * Currently this driver supports only rumble effects.
 166 */
 167static int pm8xxx_vib_play_effect(struct input_dev *dev, void *data,
 168                                  struct ff_effect *effect)
 169{
 170        struct pm8xxx_vib *vib = input_get_drvdata(dev);
 171
 172        vib->speed = effect->u.rumble.strong_magnitude >> 8;
 173        if (!vib->speed)
 174                vib->speed = effect->u.rumble.weak_magnitude >> 9;
 175
 176        schedule_work(&vib->work);
 177
 178        return 0;
 179}
 180
 181static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)
 182
 183{
 184        struct pm8xxx_vib *vib;
 185        struct input_dev *input_dev;
 186        int error;
 187        u8 val;
 188
 189        vib = kzalloc(sizeof(*vib), GFP_KERNEL);
 190        input_dev = input_allocate_device();
 191        if (!vib || !input_dev) {
 192                dev_err(&pdev->dev, "couldn't allocate memory\n");
 193                error = -ENOMEM;
 194                goto err_free_mem;
 195        }
 196
 197        INIT_WORK(&vib->work, pm8xxx_work_handler);
 198        vib->dev = &pdev->dev;
 199        vib->vib_input_dev = input_dev;
 200
 201        /* operate in manual mode */
 202        error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
 203        if (error < 0)
 204                goto err_free_mem;
 205        val &= ~VIB_DRV_EN_MANUAL_MASK;
 206        error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
 207        if (error < 0)
 208                goto err_free_mem;
 209
 210        vib->reg_vib_drv = val;
 211
 212        input_dev->name = "pm8xxx_vib_ffmemless";
 213        input_dev->id.version = 1;
 214        input_dev->dev.parent = &pdev->dev;
 215        input_dev->close = pm8xxx_vib_close;
 216        input_set_drvdata(input_dev, vib);
 217        input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
 218
 219        error = input_ff_create_memless(input_dev, NULL,
 220                                        pm8xxx_vib_play_effect);
 221        if (error) {
 222                dev_err(&pdev->dev,
 223                        "couldn't register vibrator as FF device\n");
 224                goto err_free_mem;
 225        }
 226
 227        error = input_register_device(input_dev);
 228        if (error) {
 229                dev_err(&pdev->dev, "couldn't register input device\n");
 230                goto err_destroy_memless;
 231        }
 232
 233        platform_set_drvdata(pdev, vib);
 234        return 0;
 235
 236err_destroy_memless:
 237        input_ff_destroy(input_dev);
 238err_free_mem:
 239        input_free_device(input_dev);
 240        kfree(vib);
 241
 242        return error;
 243}
 244
 245static int __devexit pm8xxx_vib_remove(struct platform_device *pdev)
 246{
 247        struct pm8xxx_vib *vib = platform_get_drvdata(pdev);
 248
 249        input_unregister_device(vib->vib_input_dev);
 250        kfree(vib);
 251
 252        platform_set_drvdata(pdev, NULL);
 253
 254        return 0;
 255}
 256
 257#ifdef CONFIG_PM_SLEEP
 258static int pm8xxx_vib_suspend(struct device *dev)
 259{
 260        struct pm8xxx_vib *vib = dev_get_drvdata(dev);
 261
 262        /* Turn off the vibrator */
 263        pm8xxx_vib_set(vib, false);
 264
 265        return 0;
 266}
 267#endif
 268
 269static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
 270
 271static struct platform_driver pm8xxx_vib_driver = {
 272        .probe          = pm8xxx_vib_probe,
 273        .remove         = __devexit_p(pm8xxx_vib_remove),
 274        .driver         = {
 275                .name   = "pm8xxx-vib",
 276                .owner  = THIS_MODULE,
 277                .pm     = &pm8xxx_vib_pm_ops,
 278        },
 279};
 280module_platform_driver(pm8xxx_vib_driver);
 281
 282MODULE_ALIAS("platform:pm8xxx_vib");
 283MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");
 284MODULE_LICENSE("GPL v2");
 285MODULE_AUTHOR("Amy Maloche <amaloche@codeaurora.org>");
 286