summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>2011-08-30 08:58:33 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:01:41 +0200
commit4af8850368fc894f920e504e5569779d179940f6 (patch)
tree183a7bfd0316b1e6ba3fee067d1550cdeb71fa9f
parent05f4e15da7ed2daf165d9472e1834e07ce44b9ab (diff)
u5500: timed output driver for ab5500 vibrator
Simple timed output vibrator driver for AB5500 MFD chips. This chip supports Rotary and Linear vibrator hardware types. Resonance frequency of 100-198 Hz is supported. ST-Ericsson ID: WP 256408 Signed-off-by: Avinash A <Avinash.a@stericsson.com> Signed-off-by: Robert Marklund <robert.marklund@stericsson.com> u5500: enable vibrator when new timeout is requested with this patch new timeout value will be accepted/updated even if vibrator is already executing. ST-Ericsson ID: 360178 Signed-off-by: Avinash A <Avinash.a@stericsson.com> vibra:Remove unnecessary assignment of dev->parent Remove unnecessary assignment of dev->parent, because of this during timed out class unregister it is trying to free resources of parent which does not exist ST-Ericsson ID: 410065 Signed-off-by: Naga Radhesh <naga.radheshy@stericsson.com> u5500: Add vibra end of life support Detect and disable vibra when vibra end of life(eol) condition is detected at boot sequence. ST-Ericsson ID: 265890 Signed-off-by: Rajagopala V <rajagopala.v@stericsson.com>
-rw-r--r--drivers/mfd/ab5500-gpadc.c15
-rw-r--r--drivers/staging/android/Kconfig10
-rw-r--r--drivers/staging/android/Makefile1
-rw-r--r--drivers/staging/android/ab5500-timed-vibra.c490
-rw-r--r--include/linux/ab5500-vibra.h57
-rw-r--r--include/linux/mfd/abx500/ab5500-gpadc.h1
6 files changed, 574 insertions, 0 deletions
diff --git a/drivers/mfd/ab5500-gpadc.c b/drivers/mfd/ab5500-gpadc.c
index 4718e26bee8..fe05ffbadfd 100644
--- a/drivers/mfd/ab5500-gpadc.c
+++ b/drivers/mfd/ab5500-gpadc.c
@@ -99,6 +99,7 @@
#define MIN_INDEX 0x02
#define MAX_INDEX 0x03
#define CTRL_INDEX 0x01
+#define KELVIN_SCALE_VOL45 0x00
/* GPADC constants from AB5500 spec */
#define GPADC0_MIN 0
@@ -129,6 +130,8 @@
#define USBID_MAX 1800
#define KELVIN_MIN 0
#define KELVIN_MAX 4500
+#define VIBRA_MIN 0
+#define VIBRA_MAX 4500
/* This is used for calibration */
#define ADC_RESOLUTION 1023
@@ -253,7 +256,9 @@ struct adc_data adc_tab[] = {
ADC_DATA(ACC_DETECT3, 0x19, ACCDET3_MIN, ACCDET3_MAX, 0),
ADC_DATA(MAIN_BAT_V_TRIG_MIN, 0x0C, VBAT_MIN, VBAT_MAX, 0),
ADC_DATA(MAIN_BAT_V_TXON_TRIG_MIN, 0x0C, VBAT_MIN, VBAT_MAX, 0),
+ ADC_DATA(VIBRA_KELVIN, 0x16, VIBRA_MIN, VIBRA_MAX, 0),
};
+
/**
* ab5500_gpadc_get() - returns a reference to the primary AB5500 GPADC
* (i.e. the first GPADC in the instance list)
@@ -279,6 +284,7 @@ static int ab5500_gpadc_ad_to_voltage(struct ab5500_gpadc *gpadc,
int res;
switch (in) {
+ case VIBRA_KELVIN:
case GPADC0_V:
case PCB_TEMP:
case BTEMP_BALL:
@@ -404,6 +410,15 @@ int ab5500_gpadc_convert(struct ab5500_gpadc *gpadc, u8 input)
goto out;
}
break;
+ case VIBRA_KELVIN:
+ ret = abx500_set_register_interruptible(gpadc->dev,
+ AB5500_BANK_ADC, AB5500_GPADC_KELVIN_CTRL,
+ KELVIN_SCALE_VOL45);
+ if (ret < 0) {
+ dev_err(gpadc->dev, "gpadc: fail to set kelv scale\n");
+ goto out;
+ }
+ break;
case USB_CHARGER_C:
case VBUS_V:
case BK_BAT_V:
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 7823c2a19ed..a4495997d1b 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -8,6 +8,16 @@ config ANDROID
if ANDROID
+config ANDROID_AB5500_TIMED_VIBRA
+ bool "AB5500 Timed Output Vibrator"
+ depends on AB5500_CORE
+ depends on ANDROID_TIMED_OUTPUT
+ default y
+ help
+ Say Y here to enable linear/rotary vibrator driver using timed
+ output class device for ST-Ericsson's based on ST-Ericsson's
+ AB5500 Mix-Sig PMIC
+
config ANDROID_BINDER_IPC
bool "Android Binder IPC Driver"
default n
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index e529c63da57..0d642936a0b 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_ANDROID_AB5500_TIMED_VIBRA) += ab5500-timed-vibra.o
obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o
obj-$(CONFIG_ASHMEM) += ashmem.o
obj-$(CONFIG_ANDROID_LOGGER) += logger.o
diff --git a/drivers/staging/android/ab5500-timed-vibra.c b/drivers/staging/android/ab5500-timed-vibra.c
new file mode 100644
index 00000000000..35c627a6285
--- /dev/null
+++ b/drivers/staging/android/ab5500-timed-vibra.c
@@ -0,0 +1,490 @@
+/*
+ * ab5500-vibra.c - driver for vibrator in ST-Ericsson AB5500 chip
+ *
+ * Copyright (C) 2011 ST-Ericsson SA.
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Author: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/wait.h>
+#include <linux/err.h>
+#include "timed_output.h"
+
+#include <linux/mfd/abx500.h> /* abx500_* */
+#include <linux/mfd/abx500/ab5500.h>
+#include <linux/mfd/abx500/ab5500-gpadc.h>
+#include <linux/ab5500-vibra.h>
+
+#define AB5500_VIBRA_DEV_NAME "ab5500:vibra"
+#define AB5500_VIBRA_DRV_NAME "ab5500-vibrator"
+
+/* Vibrator Register Address Offsets */
+#define AB5500_VIB_CTRL 0x10
+#define AB5500_VIB_VOLT 0x11
+#define AB5500_VIB_FUND_FREQ 0x12 /* Linear vibra resonance freq. */
+#define AB5500_VIB_FUND_DUTY 0x13
+#define AB5500_KELVIN_ANA 0xB1
+#define AB5500_VIBRA_KELVIN 0xFE
+
+/* Vibrator Control */
+#define AB5500_VIB_DISABLE (0x80)
+#define AB5500_VIB_PWR_ON (0x40)
+#define AB5500_VIB_FUND_EN (0x20)
+#define AB5500_VIB_FREQ_SHIFT (0)
+#define AB5500_VIB_DUTY_SHIFT (3)
+#define AB5500_VIB_VOLT_SHIFT (0)
+#define AB5500_VIB_PULSE_SHIFT (4)
+#define VIBRA_KELVIN_ENABLE (0x90)
+#define VIBRA_KELVIN_VOUT (0x20)
+
+/* Vibrator Freq. (in HZ) and Duty */
+enum ab5500_vibra_freq {
+ AB5500_VIB_FREQ_1HZ = 1,
+ AB5500_VIB_FREQ_2HZ,
+ AB5500_VIB_FREQ_4HZ,
+ AB5500_VIB_FREQ_8HZ,
+};
+
+enum ab5500_vibra_duty {
+ AB5500_VIB_DUTY_100 = 0,
+ AB5500_VIB_DUTY_75 = 8,
+ AB5500_VIB_DUTY_50 = 16,
+ AB5500_VIB_DUTY_25 = 24,
+};
+
+/* Linear vibrator resonance freq. duty */
+#define AB5500_VIB_RDUTY_50 (0x7F)
+
+/* Vibration magnitudes */
+#define AB5500_VIB_FREQ_MAX (4)
+#define AB5500_VIB_DUTY_MAX (4)
+
+static u8 vib_freq[AB5500_VIB_FREQ_MAX] = {
+ AB5500_VIB_FREQ_1HZ,
+ AB5500_VIB_FREQ_2HZ,
+ AB5500_VIB_FREQ_4HZ,
+ AB5500_VIB_FREQ_8HZ,
+};
+
+static u8 vib_duty[AB5500_VIB_DUTY_MAX] = {
+ AB5500_VIB_DUTY_100,
+ AB5500_VIB_DUTY_75,
+ AB5500_VIB_DUTY_50,
+ AB5500_VIB_DUTY_25,
+};
+
+/**
+ * struct ab5500_vibra - Vibrator driver interal info.
+ * @tdev: Pointer to timed output device structure
+ * @dev: Reference to vibra device structure
+ * @vibra_workqueue: Pointer to vibrator workqueue structure
+ * @vibra_work: Vibrator work
+ * @gpadc: Gpadc instance
+ * @vibra_wait: Vibrator wait queue head
+ * @vibra_lock: Vibrator lock
+ * @timeout_ms: Indicates how long time the vibrator will be enabled
+ * @timeout_start: Start of vibrator in jiffies
+ * @pdata: Local pointer to platform data with vibrator parameters
+ * @magnitude: required vibration strength
+ * @enable: Vibrator running status
+ * @eol: Vibrator end of life(eol) status
+ **/
+struct ab5500_vibra {
+ struct timed_output_dev tdev;
+ struct device *dev;
+ struct workqueue_struct *vibra_workqueue;
+ struct work_struct vibra_work;
+ struct ab5500_gpadc *gpadc;
+ wait_queue_head_t vibra_wait;
+ spinlock_t vibra_lock;
+ unsigned int timeout_ms;
+ unsigned long timeout_start;
+ struct ab5500_vibra_platform_data *pdata;
+ u8 magnitude;
+ bool enable;
+ bool eol;
+};
+
+static inline u8 vibra_magnitude(u8 mag)
+{
+ mag /= (AB5500_VIB_FREQ_MAX * AB5500_VIB_DUTY_MAX);
+ mag = vib_freq[mag / AB5500_VIB_FREQ_MAX] << AB5500_VIB_FREQ_SHIFT;
+ mag |= vib_duty[mag % AB5500_VIB_DUTY_MAX] << AB5500_VIB_DUTY_SHIFT;
+
+ return mag;
+}
+
+static int ab5500_setup_vibra_kelvin(struct ab5500_vibra* vibra)
+{
+ int ret;
+
+ /* Establish the kelvin IP connection to be measured */
+ ret = abx500_set_register_interruptible(vibra->dev,
+ AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
+ AB5500_KELVIN_ANA, VIBRA_KELVIN_ENABLE);
+ if (ret < 0) {
+ dev_err(vibra->dev, "failed to set kelvin network\n");
+ return ret;
+ }
+
+ /* Select vibra parameter to be measured */
+ ret = abx500_set_register_interruptible(vibra->dev, AB5500_BANK_VIBRA,
+ AB5500_VIBRA_KELVIN, VIBRA_KELVIN_VOUT);
+ if (ret < 0)
+ dev_err(vibra->dev, "failed to select the kelvin param\n");
+
+ return ret;
+}
+
+static int ab5500_vibra_start(struct ab5500_vibra* vibra)
+{
+ u8 ctrl = 0;
+
+ ctrl = AB5500_VIB_PWR_ON |
+ vibra_magnitude(vibra->magnitude);
+
+ if (vibra->pdata->type == AB5500_VIB_LINEAR)
+ ctrl |= AB5500_VIB_FUND_EN;
+
+ return abx500_set_register_interruptible(vibra->dev,
+ AB5500_BANK_VIBRA, AB5500_VIB_CTRL, ctrl);
+}
+
+static int ab5500_vibra_stop(struct ab5500_vibra* vibra)
+{
+ return abx500_mask_and_set_register_interruptible(vibra->dev,
+ AB5500_BANK_VIBRA, AB5500_VIB_CTRL,
+ AB5500_VIB_PWR_ON, 0);
+}
+
+static int ab5500_vibra_eol_check(struct ab5500_vibra* vibra)
+{
+ int ret, vout;
+
+ ret = ab5500_setup_vibra_kelvin(vibra);
+ if (ret < 0) {
+ dev_err(vibra->dev, "failed to setup kelvin network\n");
+ return ret;
+ }
+
+ /* Start vibra to measure voltage */
+ ret = ab5500_vibra_start(vibra);
+ if (ret < 0) {
+ dev_err(vibra->dev, "failed to start vibra\n");
+ return ret;
+ }
+ /* 20ms delay required for voltage rampup */
+ wait_event_interruptible_timeout(vibra->vibra_wait,
+ 0, msecs_to_jiffies(20));
+
+ vout = ab5500_gpadc_convert(vibra->gpadc, VIBRA_KELVIN);
+ if (vout < 0) {
+ dev_err(vibra->dev, "failed to read gpadc vibra\n");
+ return vout;
+ }
+
+ /* Stop vibra after measuring voltage */
+ ret = ab5500_vibra_stop(vibra);
+ if (ret < 0) {
+ dev_err(vibra->dev, "failed to stop vibra\n");
+ return ret;
+ }
+ /* Check for vibra eol condition */
+ if (vout < vibra->pdata->eol_voltage) {
+ vibra->eol = true;
+ dev_err(vibra->dev, "Vibra eol detected. Disabling vibra!\n");
+ }
+
+ return ret;
+}
+
+/**
+ * ab5500_vibra_work() - Vibrator work, turns on/off vibrator
+ * @work: Pointer to work structure
+ *
+ * This function is called from workqueue, turns on/off vibrator
+ **/
+static void ab5500_vibra_work(struct work_struct *work)
+{
+ struct ab5500_vibra *vibra = container_of(work,
+ struct ab5500_vibra, vibra_work);
+ unsigned long flags;
+ int ret;
+
+ ret = ab5500_vibra_start(vibra);
+ if (ret < 0)
+ dev_err(vibra->dev, "reg[%d] w failed: %d\n",
+ AB5500_VIB_CTRL, ret);
+
+ wait_event_interruptible_timeout(vibra->vibra_wait,
+ 0, msecs_to_jiffies(vibra->timeout_ms));
+
+ ret = ab5500_vibra_stop(vibra);
+ if (ret < 0)
+ dev_err(vibra->dev, "reg[%d] w failed: %d\n",
+ AB5500_VIB_CTRL, ret);
+
+ spin_lock_irqsave(&vibra->vibra_lock, flags);
+
+ vibra->timeout_start = 0;
+ vibra->enable = false;
+
+ spin_unlock_irqrestore(&vibra->vibra_lock, flags);
+}
+
+/**
+ * vibra_enable() - Enables vibrator
+ * @tdev: Pointer to timed output device structure
+ * @timeout: Time indicating how long vibrator will be enabled
+ *
+ * This function enables vibrator
+ **/
+static void vibra_enable(struct timed_output_dev *tdev, int timeout)
+{
+ struct ab5500_vibra *vibra = dev_get_drvdata(tdev->dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&vibra->vibra_lock, flags);
+
+ if ((!vibra->enable || timeout) && !vibra->eol) {
+ vibra->enable = true;
+
+ vibra->timeout_ms = timeout;
+ vibra->timeout_start = jiffies;
+ queue_work(vibra->vibra_workqueue, &vibra->vibra_work);
+ }
+
+ spin_unlock_irqrestore(&vibra->vibra_lock, flags);
+}
+
+/**
+ * vibra_get_time() - Returns remaining time to disabling vibration
+ * @tdev: Pointer to timed output device structure
+ *
+ * This function returns time remaining to disabling vibration
+ *
+ * Returns:
+ * Returns remaining time to disabling vibration
+ **/
+static int vibra_get_time(struct timed_output_dev *tdev)
+{
+ struct ab5500_vibra *vibra = dev_get_drvdata(tdev->dev);
+ unsigned int ms;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vibra->vibra_lock, flags);
+
+ if (vibra->enable)
+ ms = jiffies_to_msecs(vibra->timeout_start +
+ msecs_to_jiffies(vibra->timeout_ms) - jiffies);
+ else
+ ms = 0;
+
+ spin_unlock_irqrestore(&vibra->vibra_lock, flags);
+
+ return ms;
+}
+
+static int ab5500_vibra_reg_init(struct ab5500_vibra *vibra)
+{
+ int ret = 0;
+ u8 ctrl = 0;
+ u8 pulse = 0;
+
+ ctrl = (AB5500_VIB_DUTY_50 << AB5500_VIB_DUTY_SHIFT) |
+ (AB5500_VIB_FREQ_8HZ << AB5500_VIB_FREQ_SHIFT);
+
+ if (vibra->pdata->type == AB5500_VIB_LINEAR) {
+ ctrl |= AB5500_VIB_FUND_EN;
+
+ if (vibra->pdata->voltage > AB5500_VIB_VOLT_MAX)
+ vibra->pdata->voltage = AB5500_VIB_VOLT_MAX;
+
+ pulse = (vibra->pdata->pulse << AB5500_VIB_PULSE_SHIFT) |
+ (vibra->pdata->voltage << AB5500_VIB_VOLT_SHIFT);
+ ret = abx500_set_register_interruptible(vibra->dev,
+ AB5500_BANK_VIBRA, AB5500_VIB_VOLT,
+ pulse);
+ if (ret < 0) {
+ dev_err(vibra->dev,
+ "reg[%#x] w %#x failed: %d\n",
+ AB5500_VIB_VOLT, vibra->pdata->voltage, ret);
+ return ret;
+ }
+
+ ret = abx500_set_register_interruptible(vibra->dev,
+ AB5500_BANK_VIBRA, AB5500_VIB_FUND_FREQ,
+ vibra->pdata->res_freq);
+ if (ret < 0) {
+ dev_err(vibra->dev, "reg[%#x] w %#x failed: %d\n",
+ AB5500_VIB_FUND_FREQ,
+ vibra->pdata->res_freq, ret);
+ return ret;
+ }
+
+ ret = abx500_set_register_interruptible(vibra->dev,
+ AB5500_BANK_VIBRA, AB5500_VIB_FUND_DUTY,
+ AB5500_VIB_RDUTY_50);
+ if (ret < 0) {
+ dev_err(vibra->dev, "reg[%#x] w %#x failed: %d\n",
+ AB5500_VIB_FUND_DUTY,
+ AB5500_VIB_RDUTY_50, ret);
+ return ret;
+ }
+ }
+
+ ret = abx500_set_register_interruptible(vibra->dev,
+ AB5500_BANK_VIBRA, AB5500_VIB_CTRL, ctrl);
+ if (ret < 0) {
+ dev_err(vibra->dev, "reg[%#x] w %#x failed: %d\n",
+ AB5500_VIB_CTRL, ctrl, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int ab5500_vibra_register_dev(struct ab5500_vibra *vibra,
+ struct platform_device *pdev)
+{
+ int ret = 0;
+
+ ret = timed_output_dev_register(&vibra->tdev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register timed output device\n");
+ goto err_out;
+ }
+
+ dev_set_drvdata(vibra->tdev.dev, vibra);
+
+
+ /* Create workqueue just for timed output vibrator */
+ vibra->vibra_workqueue =
+ create_singlethread_workqueue("ste-timed-output-vibra");
+ if (!vibra->vibra_workqueue) {
+ dev_err(&pdev->dev, "failed to allocate workqueue\n");
+ ret = -ENOMEM;
+ goto exit_output_unregister;
+ }
+
+ init_waitqueue_head(&vibra->vibra_wait);
+ INIT_WORK(&vibra->vibra_work, ab5500_vibra_work);
+ spin_lock_init(&vibra->vibra_lock);
+
+ platform_set_drvdata(pdev, vibra);
+
+ return ret;
+
+exit_output_unregister:
+ timed_output_dev_unregister(&vibra->tdev);
+err_out:
+ return ret;
+}
+
+static int __devinit ab5500_vibra_probe(struct platform_device *pdev)
+{
+ struct ab5500_vibra_platform_data *pdata = pdev->dev.platform_data;
+ struct ab5500_vibra *vibra = NULL;
+ int ret = 0;
+
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "platform data required. Quitting...\n");
+ return -ENODEV;
+ }
+
+ vibra = kzalloc(sizeof(struct ab5500_vibra), GFP_KERNEL);
+ if (vibra == NULL)
+ return -ENOMEM;
+
+ vibra->tdev.name = "vibrator";
+ vibra->tdev.enable = vibra_enable;
+ vibra->tdev.get_time = vibra_get_time;
+ vibra->timeout_start = 0;
+ vibra->enable = false;
+ vibra->magnitude = pdata->magnitude;
+ vibra->pdata = pdata;
+ vibra->dev = &pdev->dev;
+
+ if (vibra->pdata->eol_voltage) {
+ vibra->gpadc = ab5500_gpadc_get("ab5500-adc.0");
+ if (IS_ERR(vibra->gpadc))
+ goto err_alloc;
+ }
+
+ if (vibra->pdata->type == AB5500_VIB_LINEAR)
+ dev_info(&pdev->dev, "Linear Type Vibrators\n");
+ else
+ dev_info(&pdev->dev, "Rotary Type Vibrators\n");
+
+ ret = ab5500_vibra_reg_init(vibra);
+ if (ret < 0)
+ goto err_alloc;
+
+ ret = ab5500_vibra_register_dev(vibra, pdev);
+ if (ret < 0)
+ goto err_alloc;
+
+ /* Perform vibra eol diagnostics if eol_voltage is set */
+ if (vibra->pdata->eol_voltage) {
+ ret = ab5500_vibra_eol_check(vibra);
+ if (ret < 0)
+ dev_warn(&pdev->dev, "EOL check failed\n");
+ }
+
+ dev_info(&pdev->dev, "initialization success\n");
+
+ return ret;
+
+err_alloc:
+ kfree(vibra);
+
+ return ret;
+}
+
+static int __devexit ab5500_vibra_remove(struct platform_device *pdev)
+{
+ struct ab5500_vibra *vibra = platform_get_drvdata(pdev);
+
+ timed_output_dev_unregister(&vibra->tdev);
+ destroy_workqueue(vibra->vibra_workqueue);
+ kfree(vibra);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver ab5500_vibra_driver = {
+ .probe = ab5500_vibra_probe,
+ .remove = __devexit_p(ab5500_vibra_remove),
+ .driver = {
+ .name = AB5500_VIBRA_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ab5500_vibra_module_init(void)
+{
+ return platform_driver_register(&ab5500_vibra_driver);
+}
+
+static void __exit ab5500_vibra_module_exit(void)
+{
+ platform_driver_unregister(&ab5500_vibra_driver);
+}
+
+module_init(ab5500_vibra_module_init);
+module_exit(ab5500_vibra_module_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>");
+MODULE_DESCRIPTION("Timed Output Driver for AB5500 Vibrator");
+
diff --git a/include/linux/ab5500-vibra.h b/include/linux/ab5500-vibra.h
new file mode 100644
index 00000000000..e85048dd801
--- /dev/null
+++ b/include/linux/ab5500-vibra.h
@@ -0,0 +1,57 @@
+/*----------------------------------------------------------------------------
+ * ab5500-vibra.h header file for ab5500 vibrator driver
+ *
+ * Copyright (C) 2011 ST-Ericsson SA.
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Author: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>
+ *
+ */
+
+#ifndef __AB5500_VIBRA_H__
+#define __AB5500_VIBRA_H__
+
+enum ab5500_vibra_type {
+ AB5500_VIB_ROTARY,
+ AB5500_VIB_LINEAR,
+};
+
+/* Vibrator Voltage */
+#define AB5500_VIB_VOLT_MIN (0x00) /* 1.3 Volt */
+#define AB5500_VIB_VOLT_MAX (0x0A) /* 3.5 Volt */
+#define AB5500_VIB_VOLT_STEP (0x01) /* 0.2 Volt */
+
+
+/* Linear Vibrator Resonance Frequncy */
+#define AB5500_VIB_RFREQ_100HZ (0xFB)
+#define AB5500_VIB_RFREQ_150HZ (0x52)
+#define AB5500_VIB_RFREQ_196HZ (0x03)
+
+/* Vibrator pulse duration in milliseconds */
+enum ab5500_vibra_pulse {
+ AB5500_VIB_PULSE_OFF,
+ AB5500_VIB_PULSE_20ms,
+ AB5500_VIB_PULSE_75ms,
+ AB5500_VIB_PULSE_130ms,
+ AB5500_VIB_PULSE_170ms,
+};
+
+/**
+ * struct ab5500_vibra_platform_data
+ * @voltage: Vibra output voltage
+ * @res_freq: Linear vibra resonance freq.
+ * @type: Vibra HW type
+ * @pulse: Vibra pulse duration in ms
+ * @eol_voltage: EOL voltage in mV
+ */
+struct ab5500_vibra_platform_data {
+ u8 voltage;
+ u8 res_freq;
+ u8 magnitude;
+ enum ab5500_vibra_type type;
+ enum ab5500_vibra_pulse pulse;
+ int eol_voltage;
+};
+
+#endif /* __AB5500_VIBRA_H__ */
diff --git a/include/linux/mfd/abx500/ab5500-gpadc.h b/include/linux/mfd/abx500/ab5500-gpadc.h
index 67dc3cc9034..8bddafc7f79 100644
--- a/include/linux/mfd/abx500/ab5500-gpadc.h
+++ b/include/linux/mfd/abx500/ab5500-gpadc.h
@@ -34,6 +34,7 @@
/* VBAT with TX off only min trigger */
#define MAIN_BAT_V_TRIG_MIN 14
#define GPADC0_V 15
+#define VIBRA_KELVIN 16
/*
* Frequency of auto adc conversion