root/drivers/input/misc/pm8xxx-vibrator.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pm8xxx_vib_set
  2. pm8xxx_work_handler
  3. pm8xxx_vib_close
  4. pm8xxx_vib_play_effect
  5. pm8xxx_vib_probe
  6. pm8xxx_vib_suspend

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
   3  */
   4 
   5 #include <linux/errno.h>
   6 #include <linux/input.h>
   7 #include <linux/kernel.h>
   8 #include <linux/module.h>
   9 #include <linux/of.h>
  10 #include <linux/of_device.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/regmap.h>
  13 #include <linux/slab.h>
  14 
  15 #define VIB_MAX_LEVEL_mV        (3100)
  16 #define VIB_MIN_LEVEL_mV        (1200)
  17 #define VIB_MAX_LEVELS          (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
  18 
  19 #define MAX_FF_SPEED            0xff
  20 
  21 struct pm8xxx_regs {
  22         unsigned int enable_addr;
  23         unsigned int enable_mask;
  24 
  25         unsigned int drv_addr;
  26         unsigned int drv_mask;
  27         unsigned int drv_shift;
  28         unsigned int drv_en_manual_mask;
  29 };
  30 
  31 static const struct pm8xxx_regs pm8058_regs = {
  32         .drv_addr = 0x4A,
  33         .drv_mask = 0xf8,
  34         .drv_shift = 3,
  35         .drv_en_manual_mask = 0xfc,
  36 };
  37 
  38 static struct pm8xxx_regs pm8916_regs = {
  39         .enable_addr = 0xc046,
  40         .enable_mask = BIT(7),
  41         .drv_addr = 0xc041,
  42         .drv_mask = 0x1F,
  43         .drv_shift = 0,
  44         .drv_en_manual_mask = 0,
  45 };
  46 
  47 /**
  48  * struct pm8xxx_vib - structure to hold vibrator data
  49  * @vib_input_dev: input device supporting force feedback
  50  * @work: work structure to set the vibration parameters
  51  * @regmap: regmap for register read/write
  52  * @regs: registers' info
  53  * @speed: speed of vibration set from userland
  54  * @active: state of vibrator
  55  * @level: level of vibration to set in the chip
  56  * @reg_vib_drv: regs->drv_addr register value
  57  */
  58 struct pm8xxx_vib {
  59         struct input_dev *vib_input_dev;
  60         struct work_struct work;
  61         struct regmap *regmap;
  62         const struct pm8xxx_regs *regs;
  63         int speed;
  64         int level;
  65         bool active;
  66         u8  reg_vib_drv;
  67 };
  68 
  69 /**
  70  * pm8xxx_vib_set - handler to start/stop vibration
  71  * @vib: pointer to vibrator structure
  72  * @on: state to set
  73  */
  74 static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
  75 {
  76         int rc;
  77         unsigned int val = vib->reg_vib_drv;
  78         const struct pm8xxx_regs *regs = vib->regs;
  79 
  80         if (on)
  81                 val |= (vib->level << regs->drv_shift) & regs->drv_mask;
  82         else
  83                 val &= ~regs->drv_mask;
  84 
  85         rc = regmap_write(vib->regmap, regs->drv_addr, val);
  86         if (rc < 0)
  87                 return rc;
  88 
  89         vib->reg_vib_drv = val;
  90 
  91         if (regs->enable_mask)
  92                 rc = regmap_update_bits(vib->regmap, regs->enable_addr,
  93                                         regs->enable_mask, on ? ~0 : 0);
  94 
  95         return rc;
  96 }
  97 
  98 /**
  99  * pm8xxx_work_handler - worker to set vibration level
 100  * @work: pointer to work_struct
 101  */
 102 static void pm8xxx_work_handler(struct work_struct *work)
 103 {
 104         struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
 105         const struct pm8xxx_regs *regs = vib->regs;
 106         int rc;
 107         unsigned int val;
 108 
 109         rc = regmap_read(vib->regmap, regs->drv_addr, &val);
 110         if (rc < 0)
 111                 return;
 112 
 113         /*
 114          * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
 115          * scale the level to fit into these ranges.
 116          */
 117         if (vib->speed) {
 118                 vib->active = true;
 119                 vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
 120                                                 VIB_MIN_LEVEL_mV;
 121                 vib->level /= 100;
 122         } else {
 123                 vib->active = false;
 124                 vib->level = VIB_MIN_LEVEL_mV / 100;
 125         }
 126 
 127         pm8xxx_vib_set(vib, vib->active);
 128 }
 129 
 130 /**
 131  * pm8xxx_vib_close - callback of input close callback
 132  * @dev: input device pointer
 133  *
 134  * Turns off the vibrator.
 135  */
 136 static void pm8xxx_vib_close(struct input_dev *dev)
 137 {
 138         struct pm8xxx_vib *vib = input_get_drvdata(dev);
 139 
 140         cancel_work_sync(&vib->work);
 141         if (vib->active)
 142                 pm8xxx_vib_set(vib, false);
 143 }
 144 
 145 /**
 146  * pm8xxx_vib_play_effect - function to handle vib effects.
 147  * @dev: input device pointer
 148  * @data: data of effect
 149  * @effect: effect to play
 150  *
 151  * Currently this driver supports only rumble effects.
 152  */
 153 static int pm8xxx_vib_play_effect(struct input_dev *dev, void *data,
 154                                   struct ff_effect *effect)
 155 {
 156         struct pm8xxx_vib *vib = input_get_drvdata(dev);
 157 
 158         vib->speed = effect->u.rumble.strong_magnitude >> 8;
 159         if (!vib->speed)
 160                 vib->speed = effect->u.rumble.weak_magnitude >> 9;
 161 
 162         schedule_work(&vib->work);
 163 
 164         return 0;
 165 }
 166 
 167 static int pm8xxx_vib_probe(struct platform_device *pdev)
 168 {
 169         struct pm8xxx_vib *vib;
 170         struct input_dev *input_dev;
 171         int error;
 172         unsigned int val;
 173         const struct pm8xxx_regs *regs;
 174 
 175         vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL);
 176         if (!vib)
 177                 return -ENOMEM;
 178 
 179         vib->regmap = dev_get_regmap(pdev->dev.parent, NULL);
 180         if (!vib->regmap)
 181                 return -ENODEV;
 182 
 183         input_dev = devm_input_allocate_device(&pdev->dev);
 184         if (!input_dev)
 185                 return -ENOMEM;
 186 
 187         INIT_WORK(&vib->work, pm8xxx_work_handler);
 188         vib->vib_input_dev = input_dev;
 189 
 190         regs = of_device_get_match_data(&pdev->dev);
 191 
 192         /* operate in manual mode */
 193         error = regmap_read(vib->regmap, regs->drv_addr, &val);
 194         if (error < 0)
 195                 return error;
 196 
 197         val &= regs->drv_en_manual_mask;
 198         error = regmap_write(vib->regmap, regs->drv_addr, val);
 199         if (error < 0)
 200                 return error;
 201 
 202         vib->regs = regs;
 203         vib->reg_vib_drv = val;
 204 
 205         input_dev->name = "pm8xxx_vib_ffmemless";
 206         input_dev->id.version = 1;
 207         input_dev->close = pm8xxx_vib_close;
 208         input_set_drvdata(input_dev, vib);
 209         input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
 210 
 211         error = input_ff_create_memless(input_dev, NULL,
 212                                         pm8xxx_vib_play_effect);
 213         if (error) {
 214                 dev_err(&pdev->dev,
 215                         "couldn't register vibrator as FF device\n");
 216                 return error;
 217         }
 218 
 219         error = input_register_device(input_dev);
 220         if (error) {
 221                 dev_err(&pdev->dev, "couldn't register input device\n");
 222                 return error;
 223         }
 224 
 225         platform_set_drvdata(pdev, vib);
 226         return 0;
 227 }
 228 
 229 static int __maybe_unused pm8xxx_vib_suspend(struct device *dev)
 230 {
 231         struct pm8xxx_vib *vib = dev_get_drvdata(dev);
 232 
 233         /* Turn off the vibrator */
 234         pm8xxx_vib_set(vib, false);
 235 
 236         return 0;
 237 }
 238 
 239 static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
 240 
 241 static const struct of_device_id pm8xxx_vib_id_table[] = {
 242         { .compatible = "qcom,pm8058-vib", .data = &pm8058_regs },
 243         { .compatible = "qcom,pm8921-vib", .data = &pm8058_regs },
 244         { .compatible = "qcom,pm8916-vib", .data = &pm8916_regs },
 245         { }
 246 };
 247 MODULE_DEVICE_TABLE(of, pm8xxx_vib_id_table);
 248 
 249 static struct platform_driver pm8xxx_vib_driver = {
 250         .probe          = pm8xxx_vib_probe,
 251         .driver         = {
 252                 .name   = "pm8xxx-vib",
 253                 .pm     = &pm8xxx_vib_pm_ops,
 254                 .of_match_table = pm8xxx_vib_id_table,
 255         },
 256 };
 257 module_platform_driver(pm8xxx_vib_driver);
 258 
 259 MODULE_ALIAS("platform:pm8xxx_vib");
 260 MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");
 261 MODULE_LICENSE("GPL v2");
 262 MODULE_AUTHOR("Amy Maloche <amaloche@codeaurora.org>");

/* [<][>][^][v][top][bottom][index][help] */