0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/jiffies.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/of.h>
0016 #include <linux/workqueue.h>
0017 #include <linux/mfd/twl.h>
0018 #include <linux/mfd/twl4030-audio.h>
0019 #include <linux/input.h>
0020 #include <linux/slab.h>
0021
0022
0023 #define LEDEN 0x00
0024
0025
0026 #define EFFECT_DIR_180_DEG 0x8000
0027
0028 struct vibra_info {
0029 struct device *dev;
0030 struct input_dev *input_dev;
0031
0032 struct work_struct play_work;
0033
0034 bool enabled;
0035 int speed;
0036 int direction;
0037
0038 bool coexist;
0039 };
0040
0041 static void vibra_disable_leds(void)
0042 {
0043 u8 reg;
0044
0045
0046 twl_i2c_read_u8(TWL4030_MODULE_LED, ®, LEDEN);
0047 reg &= ~0x03;
0048 twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg);
0049 }
0050
0051
0052 static void vibra_enable(struct vibra_info *info)
0053 {
0054 u8 reg;
0055
0056 twl4030_audio_enable_resource(TWL4030_AUDIO_RES_POWER);
0057
0058
0059 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
0060 ®, TWL4030_REG_VIBRA_CTL);
0061 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
0062 (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
0063
0064 twl4030_audio_enable_resource(TWL4030_AUDIO_RES_APLL);
0065
0066 info->enabled = true;
0067 }
0068
0069 static void vibra_disable(struct vibra_info *info)
0070 {
0071 u8 reg;
0072
0073
0074 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
0075 ®, TWL4030_REG_VIBRA_CTL);
0076 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
0077 (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
0078
0079 twl4030_audio_disable_resource(TWL4030_AUDIO_RES_APLL);
0080 twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER);
0081
0082 info->enabled = false;
0083 }
0084
0085 static void vibra_play_work(struct work_struct *work)
0086 {
0087 struct vibra_info *info = container_of(work,
0088 struct vibra_info, play_work);
0089 int dir;
0090 int pwm;
0091 u8 reg;
0092
0093 dir = info->direction;
0094 pwm = info->speed;
0095
0096 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
0097 ®, TWL4030_REG_VIBRA_CTL);
0098 if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) {
0099
0100 if (!info->enabled)
0101 vibra_enable(info);
0102
0103
0104 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
0105 ®, TWL4030_REG_VIBRA_CTL);
0106 reg = (dir) ? (reg | TWL4030_VIBRA_DIR) :
0107 (reg & ~TWL4030_VIBRA_DIR);
0108 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
0109 reg, TWL4030_REG_VIBRA_CTL);
0110
0111
0112 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
0113 256 - pwm, TWL4030_REG_VIBRA_SET);
0114 } else {
0115 if (info->enabled)
0116 vibra_disable(info);
0117 }
0118 }
0119
0120
0121
0122 static int vibra_play(struct input_dev *input, void *data,
0123 struct ff_effect *effect)
0124 {
0125 struct vibra_info *info = input_get_drvdata(input);
0126
0127 info->speed = effect->u.rumble.strong_magnitude >> 8;
0128 if (!info->speed)
0129 info->speed = effect->u.rumble.weak_magnitude >> 9;
0130 info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1;
0131 schedule_work(&info->play_work);
0132 return 0;
0133 }
0134
0135 static void twl4030_vibra_close(struct input_dev *input)
0136 {
0137 struct vibra_info *info = input_get_drvdata(input);
0138
0139 cancel_work_sync(&info->play_work);
0140
0141 if (info->enabled)
0142 vibra_disable(info);
0143 }
0144
0145
0146 static int __maybe_unused twl4030_vibra_suspend(struct device *dev)
0147 {
0148 struct platform_device *pdev = to_platform_device(dev);
0149 struct vibra_info *info = platform_get_drvdata(pdev);
0150
0151 if (info->enabled)
0152 vibra_disable(info);
0153
0154 return 0;
0155 }
0156
0157 static int __maybe_unused twl4030_vibra_resume(struct device *dev)
0158 {
0159 vibra_disable_leds();
0160 return 0;
0161 }
0162
0163 static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
0164 twl4030_vibra_suspend, twl4030_vibra_resume);
0165
0166 static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
0167 struct device_node *parent)
0168 {
0169 struct device_node *node;
0170
0171 if (pdata && pdata->coexist)
0172 return true;
0173
0174 node = of_get_child_by_name(parent, "codec");
0175 if (node) {
0176 of_node_put(node);
0177 return true;
0178 }
0179
0180 return false;
0181 }
0182
0183 static int twl4030_vibra_probe(struct platform_device *pdev)
0184 {
0185 struct twl4030_vibra_data *pdata = dev_get_platdata(&pdev->dev);
0186 struct device_node *twl4030_core_node = pdev->dev.parent->of_node;
0187 struct vibra_info *info;
0188 int ret;
0189
0190 if (!pdata && !twl4030_core_node) {
0191 dev_dbg(&pdev->dev, "platform_data not available\n");
0192 return -EINVAL;
0193 }
0194
0195 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
0196 if (!info)
0197 return -ENOMEM;
0198
0199 info->dev = &pdev->dev;
0200 info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node);
0201 INIT_WORK(&info->play_work, vibra_play_work);
0202
0203 info->input_dev = devm_input_allocate_device(&pdev->dev);
0204 if (info->input_dev == NULL) {
0205 dev_err(&pdev->dev, "couldn't allocate input device\n");
0206 return -ENOMEM;
0207 }
0208
0209 input_set_drvdata(info->input_dev, info);
0210
0211 info->input_dev->name = "twl4030:vibrator";
0212 info->input_dev->id.version = 1;
0213 info->input_dev->close = twl4030_vibra_close;
0214 __set_bit(FF_RUMBLE, info->input_dev->ffbit);
0215
0216 ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
0217 if (ret < 0) {
0218 dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
0219 return ret;
0220 }
0221
0222 ret = input_register_device(info->input_dev);
0223 if (ret < 0) {
0224 dev_dbg(&pdev->dev, "couldn't register input device\n");
0225 goto err_iff;
0226 }
0227
0228 vibra_disable_leds();
0229
0230 platform_set_drvdata(pdev, info);
0231 return 0;
0232
0233 err_iff:
0234 input_ff_destroy(info->input_dev);
0235 return ret;
0236 }
0237
0238 static struct platform_driver twl4030_vibra_driver = {
0239 .probe = twl4030_vibra_probe,
0240 .driver = {
0241 .name = "twl4030-vibra",
0242 .pm = &twl4030_vibra_pm_ops,
0243 },
0244 };
0245 module_platform_driver(twl4030_vibra_driver);
0246
0247 MODULE_ALIAS("platform:twl4030-vibra");
0248 MODULE_DESCRIPTION("TWL4030 Vibra driver");
0249 MODULE_LICENSE("GPL");
0250 MODULE_AUTHOR("Nokia Corporation");