summaryrefslogtreecommitdiff
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch1836
1 files changed, 0 insertions, 1836 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch
deleted file mode 100644
index fce452451..000000000
--- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch
+++ /dev/null
@@ -1,1836 +0,0 @@
-From cffaf6b15ff40cfbeafd0d4728ba3a5a5fb6155f Mon Sep 17 00:00:00 2001
-From: Alan Olsen <alan.r.olsen@intel.com>
-Date: Thu, 15 Oct 2009 14:26:47 -0700
-Subject: [PATCH 062/104] Moorestown Sensor drivers v1.1 consolidated patch
-
-This patch contains the following patches:
-
-Alpha2-1.1-1-5-mrst-Sensors-ALS-Driver-for-Moorestown.patch
-
- [PATCH] ALS Driver for Moorestown Sensors
-
- This patch single patch for Alpha2:2.0. ALS driver will read
- the latest Lux measurement based on the light brightness and
- will report the LUX output through sysfs interface.
-
- Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
-
-Alpha2-1.1-2-5-mrst-Sensors-Compass-Driver-for-Moorestown.patch
-
- [PATCH] Compass Driver for Moorestown Sensors
- This patch single patch for Alpha2:2.0.This driver will report
- the heading values in degrees to the sysfs interface.The vlaues
- returned are head . e.g. 245.6
-
- Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
-
-Alpha2-1.1-3-5-mrst-Sensors-Accelerometer-Driver-for-Moorestown.patch
-
- [PATCH] Accelerometer Driver for Moorestown Sensors
-
- This patch single patch for Alpha2:2.0.Accelerometer driver will
- read the x,y,z coordinate registers and provide the information to
- user through sysfs interface.
-
- Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
-
-Alpha2-1.1-4-5-mrst-Sensors-Vibrator-Driver-for-Moorestown.patch
-
- [PATCH] Vibrator Driver for Moorestown Sensors
-
- This patch single patch for Alpha2:2.0.Vibrator can be switched
- on/off using sysfs interface.
-
- Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
-
-Alpha2-1.1-5-5-mrst-Sensors-Thermal-Driver-for-Moorestown.patch
-
- [PATCH] Thermal Driver for Moorestown Sensors
-
- Moorestown Platform has EMC1403 chip which support three thermal
- devices, one thermal zone is used by the EMC1403 chip itself and
- second is used by processor and third one is used for platform
- (skin temperature).Driver support poll and interrupt
- mode,min/max/crit configuration can be done using sysfs interface.
-
- The driver also support interrupt mode when the temperature crosses the
- threshold configured value the min/max/crit. ALERT/THERM interrupt will
- be triggered and driver register its callback with GPE driver, and send
- the events to OSPM power management to take action. OSPM will take
- action and set the new threshold values till it doesnot get ALERT/THERM
- events.temp1 is used for configuring internal EMC1403 chip diode, temp2
- is used to configure processor diode and temp3 is used to configure the
- platform diode.
-
- The interrupt mode code has dependency MRST PMIC_GPIO/MAX7315/OSPM.Flag
- is added to differentiate the generic functionality of the driver with
- moorestown specific.
-
- Signed-off-by: Kalhan Trisal <kalhan.trisal at intel.com>
-
-Signed-off-by: Alan Olsen <alan.r.olsen@intel.com>
----
- drivers/hwmon/Kconfig | 35 ++
- drivers/hwmon/Makefile | 4
- drivers/hwmon/emc1403.c | 731 +++++++++++++++++++++++++++++++++++++++++++++++
- drivers/hwmon/hmc6352.c | 250 ++++++++++++++++
- drivers/hwmon/isl29020.c | 248 +++++++++++++++
- drivers/hwmon/lis331dl.c | 322 ++++++++++++++++++++
- drivers/misc/Kconfig | 7
- drivers/misc/Makefile | 1
- drivers/misc/mrst_vib.c | 99 ++++++
- 9 files changed, 1697 insertions(+)
- create mode 100644 drivers/hwmon/emc1403.c
- create mode 100644 drivers/hwmon/hmc6352.c
- create mode 100644 drivers/hwmon/isl29020.c
- create mode 100644 drivers/hwmon/lis331dl.c
- create mode 100644 drivers/misc/mrst_vib.c
-
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -28,6 +28,41 @@ config HWMON_VID
- tristate
- default n
-
-+config SENSORS_ISL29020
-+ tristate "Intersil ISL29020 ALS"
-+ depends on I2C_MRST
-+ help
-+ If you say yes here you get support for the ALS Devices
-+ Ambient Light Sensor monitoring chip.
-+ Range values can be configured using sysfs.
-+ Lux Data are accessible via sysfs.
-+
-+config SENSORS_HMC6352
-+ tristate "Honeywell HMC6352 compass"
-+ depends on I2C_MRST
-+ help
-+ If you say yes here you get support for the Compass Devices
-+ Device can be configured using sysfs.
-+ heading data can be accessible via sysfs.
-+
-+config SENSORS_LIS331DL
-+ tristate "STMicroeletronics LIS331DL three-axis digital accelerometer"
-+ depends on I2C_MRST
-+ help
-+ If you say yes here you get support for the Accelerometer Devices
-+ Device can be configured using sysfs.
-+ x y Z data can be accessible via sysfs.
-+
-+config SENSORS_EMC1403
-+ tristate "SMSC EMC1403 Thermal"
-+ depends on I2C_MRST && GPE && GPIO_MAX7315 && MSTWN_POWER_MGMT
-+ help
-+ If you say yes here you get support for the SMSC Devices
-+ EMC1403 temperature monitoring chip.
-+
-+ Threshold values can be configured using sysfs.
-+ Data from the different diode are accessible via sysfs.
-+
- config HWMON_DEBUG_CHIP
- bool "Hardware Monitoring Chip debugging messages"
- default n
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -99,6 +99,10 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l7
- obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
- obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
- obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
-+obj-$(CONFIG_SENSORS_ISL29020) += isl29020.o
-+obj-$(CONFIG_SENSORS_HMC6352) += hmc6352.o
-+obj-$(CONFIG_SENSORS_LIS331DL) += lis331dl.o
-+obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
-
- ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
- EXTRA_CFLAGS += -DDEBUG
---- /dev/null
-+++ b/drivers/hwmon/emc1403.c
-@@ -0,0 +1,731 @@
-+/*
-+ * emc1403.c - SMSC Thermal Driver
-+ *
-+ * Copyright (C) 2008 Intel Corp
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/i2c.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/hwmon-vid.h>
-+#include <linux/interrupt.h>
-+#include <linux/workqueue.h>
-+#include <linux/err.h>
-+#include <linux/delay.h>
-+#include <linux/mutex.h>
-+#include <linux/sysfs.h>
-+#include <linux/gpe.h>
-+#include <linux/intel_mid.h>
-+
-+
-+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
-+MODULE_DESCRIPTION("emc1403 Thermal Driver");
-+MODULE_LICENSE("GPL v2");
-+
-+/* To support the interrupt mechanism for moorestown interrupt flag is added
-+ * If the flag is not enabled it support generic emc1403 chip */
-+
-+#if defined(CONFIG_GPIO_LNWPMIC) && defined(CONFIG_GPIO_MAX7315) \
-+ && defined(CONFIG_MSTWN_POWER_MGMT)
-+#define MOORESTOWN_INTERRUPT_ENABLE
-+#endif
-+
-+/* Limit status reg Therm/High/Low/Fault*/
-+static const u8 THM_STAT_REG_TEMP[] = { 0x37, 0x35, 0x36, 0x1B, 0x02};
-+
-+/* Channel diode temp set */
-+static const u8 THM_CHAN_TEMP[] = { 0x10, 0x08, 0x04, 0x02, 0x01 };
-+
-+/* Therm Limit reg store values */
-+static const u8 THM_LIMIT_REG_TEMP[] = { 0x05, 0x06, 0x07, 0x08, 0x15, 0x16,
-+ 0x19, 0x1A, 0x20, 0x21 };
-+
-+/* DATA REGISTERS */
-+static const u8 THM_REG_CURR_TEMP[] = { 0x00, 0x01, 0x23 };
-+
-+#define THERMAL_PID_REG 0xfd
-+#define THERMAL_SMSC_ID_REG 0xfe
-+#define THERMAL_REVISION_REG 0xff
-+#define THERMAL_ADC_UPDATE_BUSY 0x80
-+#define I2C_THERMAL_SLAVE_ADDR 0x4C
-+#define TEMP1 1
-+#define TEMP2 2
-+#define TEMP3 4
-+#define IRQ_TYPE_MASK (1 << 15)
-+#define HIGH_EVENT 1
-+#define LOW_EVENT 2
-+#define THERM_EVENT 3
-+#define FAULT_EVENT 4
-+#define ALERT_EVENT 1
-+#define POWER_STA_ENABLE 0
-+#define POWER_STA_DISABLE 1
-+#define INTERRUPT_MODE_ENABLE 0
-+#define INTERRUPT_MODE_DISABLE 1
-+
-+struct thermal_data {
-+ struct i2c_client *client;
-+ struct device *hwmon_dev;
-+ int therm_irq;
-+ int alert_irq;
-+ struct work_struct therm_handler;
-+ struct work_struct alert_handler;
-+};
-+
-+static unsigned int i2c_read_current_data(struct i2c_client *client, u8 reg)
-+{
-+ unsigned int ret_val;
-+
-+ ret_val = i2c_smbus_read_byte_data(client, reg);
-+ return ret_val;
-+}
-+
-+static unsigned int i2c_write_current_data(struct i2c_client *client,
-+ unsigned int reg, unsigned int value)
-+{
-+ int ret_val;
-+
-+ ret_val = i2c_smbus_write_byte_data(client, reg, value);
-+ return ret_val;
-+}
-+
-+static int calculate_offset(int type, int temp_ofs)
-+{
-+ int offset = 0;
-+
-+ switch (type) {
-+ case TEMP1:
-+ if (temp_ofs == 0)
-+ offset = 1;
-+ else if (temp_ofs == 1)
-+ offset = 0;
-+ else if (temp_ofs == 2)
-+ offset = 8;
-+ break;
-+ case TEMP2:
-+ if (temp_ofs == 0)
-+ offset = 3;
-+ else if (temp_ofs == 1)
-+ offset = 2;
-+ else if (temp_ofs == 2)
-+ offset = 6;
-+ break;
-+ case TEMP3:
-+ if (temp_ofs == 0)
-+ offset = 5;
-+ else if (temp_ofs == 1)
-+ offset = 4;
-+ else if (temp_ofs == 2)
-+ offset = 7;
-+ break;
-+ default:
-+ offset = -1;
-+ printk(KERN_WARNING "emc1403: Invalid arg \n");
-+ break;
-+ }
-+ return offset;
-+
-+}
-+
-+#ifdef MOORESTOWN_INTERRUPT_ENABLE
-+static void status_reg_read(struct i2c_client *client)
-+{
-+ i2c_read_current_data(client, 0x36);
-+ i2c_read_current_data(client, 0x35);
-+ i2c_read_current_data(client, 0x1B);
-+}
-+
-+/* when the thermal governor takes action we unmask the bit
-+ * if the temp is lower tham threshold values then no new event will
-+ * be raised else if the current temperature is still high the interrupt
-+ * will be sent again */
-+
-+static void reg_unmask_intr(struct i2c_client *client, int offset,
-+ int value)
-+{
-+ u8 ret_val, set_mask, ret = 0, alert = 0;
-+
-+ ret_val = i2c_read_current_data(client, 0x1F);
-+ if (offset == 6 || offset == 7 || offset == 8) {
-+ ret = i2c_read_current_data(client, 0x37); /* Themal status */
-+ } else if (offset == 2 || offset == 3) {
-+ if (((ret_val >> 1) & 1)) {
-+ set_mask = (ret_val & 0x05);
-+ alert = 1;
-+ }
-+ } else if (offset == 4 || offset == 5) {
-+ if (((ret_val >> 2) & 1)) {
-+ set_mask = (ret_val & 0x03);
-+ alert = 1;
-+ }
-+ } else if (offset == 0 || offset == 1) {
-+ if (ret_val & 1) {
-+ set_mask = (ret_val & 0x06);
-+ alert = 1;
-+ }
-+ }
-+ /* only rest set the mask for alert events */
-+ if (alert == 1) {
-+ status_reg_read(client);
-+ i2c_write_current_data(client, 0x1F, set_mask);
-+ }
-+}
-+#endif
-+
-+static ssize_t show_temp_auto_offset(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr);
-+ int temp_index = s_attr->index;
-+ int temp_ofs = s_attr->nr;
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val = 0;
-+ int ret_offset = 0;
-+
-+ ret_offset = calculate_offset(temp_index, temp_ofs);
-+ if (ret_offset != -1) {
-+ ret_val = i2c_read_current_data(client,
-+ THM_LIMIT_REG_TEMP[ret_offset]);
-+ return sprintf(buf, "%d\n", ret_val);
-+ } else {
-+ return -EINVAL;
-+ }
-+}
-+
-+static ssize_t store_temp_auto_offset(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr);
-+ int temp_index = s_attr->index;
-+ int temp_ofs = s_attr->nr;
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned long val;
-+ int ret_offset = 0;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ ret_offset = calculate_offset(temp_index, temp_ofs);
-+ if (ret_offset != -1) {
-+ i2c_write_current_data(client,
-+ THM_LIMIT_REG_TEMP[ret_offset], val);
-+#ifdef MOORESTOWN_INTERRUPT_ENABLE
-+ reg_unmask_intr(client, ret_offset, val);
-+#endif
-+ return count;
-+ } else {
-+ return -EINVAL;
-+ }
-+}
-+
-+static ssize_t show_temp_hyst(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_read_current_data(client, THM_LIMIT_REG_TEMP[9]);
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t store_temp_hyst(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned long val = 0;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ i2c_write_current_data(client, THM_LIMIT_REG_TEMP[9], val);
-+ return count;
-+}
-+
-+static ssize_t show_temp1_curr_temp(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[0]);
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t show_temp2_curr_temp(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[1]);
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t show_temp3_curr_temp(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[2]);
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t show_status_reg(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val1, ret_val2, ret_val3, ret_val4;
-+
-+ ret_val1 = i2c_read_current_data(client, 0x1F);
-+ ret_val2 = i2c_read_current_data(client, 0x35);
-+ ret_val3 = i2c_read_current_data(client, 0x36);
-+ ret_val4 = i2c_read_current_data(client, 0x37);
-+ return sprintf(buf, "alarm=%x,High=%x,Low=%x,Therm=%x \n",
-+ ret_val1, ret_val2, ret_val3, ret_val4);
-+}
-+
-+static ssize_t show_power_state(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_read_current_data(client, 0x03);
-+ ret_val = ret_val & 0x40;
-+ if (ret_val == 0x40)
-+ ret_val = 1;
-+ return sprintf(buf, "%x", ret_val);
-+}
-+
-+static ssize_t store_power_state(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned long val = 0;
-+ char curr_val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+
-+ curr_val = i2c_read_current_data(client, 0x03);
-+ if (val == POWER_STA_ENABLE)
-+ curr_val = curr_val & 0xBF;
-+ else if (val == POWER_STA_DISABLE)
-+ curr_val = curr_val | 0x40;
-+ else
-+ return -EINVAL;
-+ i2c_write_current_data(client, 0x03, curr_val);
-+ return count;
-+}
-+
-+static ssize_t show_mode(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_read_current_data(client, 0x03);
-+ ret_val = ret_val & 0x80;
-+ if (ret_val == 0x80)
-+ ret_val = 1;
-+ return sprintf(buf, "%x", ret_val);
-+}
-+
-+static ssize_t store_mode(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned long val = 0;
-+ char curr_val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+
-+ curr_val = i2c_read_current_data(client, 0x03);
-+ if (val == INTERRUPT_MODE_ENABLE)
-+ curr_val = curr_val & 0x7F;
-+ else if (val == INTERRUPT_MODE_DISABLE)
-+ curr_val = curr_val | 0x80;
-+ else
-+ return -EINVAL;
-+ i2c_write_current_data(client, 0x03, curr_val);
-+ return count;
-+}
-+
-+static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 0, 1);
-+static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 1, 1);
-+static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 2, 1);
-+static DEVICE_ATTR(temp1_curr, S_IRUGO, show_temp1_curr_temp, NULL);
-+
-+static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 0, 2);
-+static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 1, 2);
-+static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 2, 2);
-+static DEVICE_ATTR(temp2_curr, S_IRUGO, show_temp2_curr_temp, NULL);
-+
-+static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 0, 4);
-+static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 1, 4);
-+static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR,
-+ show_temp_auto_offset, store_temp_auto_offset, 2, 4);
-+static DEVICE_ATTR(temp3_curr, S_IRUGO, show_temp3_curr_temp, NULL);
-+
-+static DEVICE_ATTR(hyster, S_IRUGO | S_IWUSR, show_temp_hyst, store_temp_hyst);
-+static DEVICE_ATTR(status, S_IRUGO, show_status_reg, NULL);
-+
-+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
-+ show_power_state, store_power_state);
-+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode);
-+
-+static struct attribute *mid_att_thermal[] = {
-+ &sensor_dev_attr_temp1_min.dev_attr.attr,
-+ &sensor_dev_attr_temp1_max.dev_attr.attr,
-+ &sensor_dev_attr_temp1_crit.dev_attr.attr,
-+ &dev_attr_temp1_curr.attr,
-+ &sensor_dev_attr_temp2_min.dev_attr.attr,
-+ &sensor_dev_attr_temp2_max.dev_attr.attr,
-+ &sensor_dev_attr_temp2_crit.dev_attr.attr,
-+ &dev_attr_temp2_curr.attr,
-+ &sensor_dev_attr_temp3_min.dev_attr.attr,
-+ &sensor_dev_attr_temp3_max.dev_attr.attr,
-+ &sensor_dev_attr_temp3_crit.dev_attr.attr,
-+ &dev_attr_temp3_curr.attr,
-+ &dev_attr_hyster.attr,
-+ &dev_attr_status.attr,
-+ &dev_attr_power_state.attr,
-+ &dev_attr_mode.attr,
-+ NULL
-+};
-+
-+static struct attribute_group m_thermal_gr = {
-+ .name = "emc1403",
-+ .attrs = mid_att_thermal
-+};
-+
-+static void emc1403_set_default_config(struct i2c_client *client)
-+{
-+ i2c_smbus_write_byte_data(client, 0x03, 0x00);
-+ i2c_smbus_write_byte_data(client, 0x04, 0x02);
-+ i2c_smbus_write_byte_data(client, 0x22, 0x00);
-+}
-+
-+#ifdef MOORESTOWN_INTERRUPT_ENABLE
-+static irqreturn_t therm_interrupt_handler(int id, void *dev)
-+{
-+ struct thermal_data *data = (struct thermal_data *)dev;
-+ schedule_work(&data->therm_handler);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t alert_interrupt_handler(int id, void *dev)
-+{
-+ struct thermal_data *data = (struct thermal_data *)dev;
-+ schedule_work(&data->alert_handler);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+/* when the device raise the interrupt we mask the interrupt
-+ * bit for that device as the status register is R-C
-+ * so that till thermal governor doesnot take action we need
-+ * not to send continuous events */
-+
-+static int interrupt_status(struct i2c_client *client, u8 diode_reg_val,
-+ u8 *status, u8 event)
-+{
-+ u8 crit_st = 0, set_mask = 0;
-+
-+ set_mask = i2c_read_current_data(client, 0x1F);
-+ if (diode_reg_val & THM_CHAN_TEMP[3]) {
-+ set_mask = (set_mask | 0x02);
-+ crit_st = (crit_st | 2);
-+ }
-+ if (diode_reg_val & THM_CHAN_TEMP[2]) {
-+ set_mask = (set_mask | 0x04);
-+ crit_st = (crit_st | 4);
-+ }
-+ if (diode_reg_val & THM_CHAN_TEMP[4]) {
-+ set_mask = (set_mask | 0x01);
-+ crit_st = (crit_st | 1);
-+ }
-+ if (event == ALERT_EVENT)
-+ i2c_smbus_write_byte_data(client, 0x1F, set_mask);
-+ *status = crit_st;
-+ return 0;
-+}
-+
-+static void ospm_event(int event_id, int sensor_id, int curr_temp)
-+{
-+ if (event_id == THERM_EVENT) {
-+ printk(KERN_ALERT "emc1403: Sensor Id = %d crit event \
-+ temp = %d \n", sensor_id, curr_temp);
-+ ospm_generate_netlink_event(sensor_id,
-+ OSPM_EVENT_THERMAL_CRITICAL);
-+ }
-+ if (event_id == HIGH_EVENT) {
-+ printk(KERN_ALERT "emc1403: Sensor Id = %d AUX1 event \
-+ temp = %d \n", sensor_id, curr_temp);
-+ ospm_generate_netlink_event(sensor_id,
-+ OSPM_EVENT_THERMAL_AUX1);
-+ }
-+ if (event_id == LOW_EVENT) {
-+ printk(KERN_ALERT "emc1403: Sensor Id = %d AUX0 event \
-+ temp = %d \n", sensor_id, curr_temp);
-+ ospm_generate_netlink_event(sensor_id,
-+ OSPM_EVENT_THERMAL_AUX0);
-+ }
-+ if (event_id == FAULT_EVENT) {
-+ printk(KERN_ALERT "emc1403: Sensor Id = %d Fault event \
-+ temp = %d \n", sensor_id, curr_temp);
-+ ospm_generate_netlink_event(sensor_id,
-+ OSPM_EVENT_THERMAL_DEV_FAULT);
-+ }
-+}
-+
-+static void send_event(struct i2c_client *client, int status, int event_id)
-+{
-+ int ret_val;
-+
-+ if (status & TEMP1) {
-+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[0]);
-+ ospm_event(event_id, TEMP_DEV_ID1, ret_val);
-+ }
-+ if (status & TEMP2) {
-+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[1]);
-+ ospm_event(event_id, TEMP_DEV_ID2, ret_val);
-+ }
-+ if (status & TEMP3) {
-+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[2]);
-+ ospm_event(event_id, TEMP_DEV_ID3, ret_val);
-+ }
-+}
-+
-+static void therm_handle_intrpt(struct work_struct *work)
-+{
-+ u8 status, reg_val;
-+ struct thermal_data *data = container_of(work,
-+ struct thermal_data, therm_handler);
-+
-+ /* check if therm_module_info is initialized */
-+ if (!data)
-+ return;
-+ /* Which DIODE has raised the interrupt 0x1B
-+ internal/External1/External2 */
-+ reg_val = i2c_smbus_read_byte_data(data->client,
-+ THM_STAT_REG_TEMP[0]);
-+ interrupt_status(data->client, reg_val, &status, THERM_EVENT);
-+ send_event(data->client, status, THERM_EVENT);
-+}
-+
-+static void alert_handle_intrpt(struct work_struct *work)
-+{
-+ int sta_reg_val, reg_val;
-+ u8 status;
-+ struct thermal_data *data = container_of(work,
-+ struct thermal_data, alert_handler);
-+ if (!data)
-+ return;
-+ /* HIGH/ LOW / FAULT Alert has occured for */
-+ reg_val = i2c_smbus_read_byte_data(data->client, THM_STAT_REG_TEMP[4]);
-+ /* High status bit is set */
-+ if (reg_val & THM_CHAN_TEMP[0]) {
-+ /* Which DIODE has raised the interrupt 0x1B
-+ internal/External1/External2 */
-+ sta_reg_val = i2c_smbus_read_byte_data(data->client,
-+ THM_STAT_REG_TEMP[1]);
-+ interrupt_status(data->client, sta_reg_val, &status,
-+ ALERT_EVENT);
-+ send_event(data->client, status, HIGH_EVENT);
-+ }
-+ /* Low status bit is set */
-+ if (reg_val & THM_CHAN_TEMP[1]) {
-+ sta_reg_val = i2c_smbus_read_byte_data(data->client,
-+ THM_STAT_REG_TEMP[2]);
-+ interrupt_status(data->client, sta_reg_val, &status,
-+ ALERT_EVENT);
-+ send_event(data->client, status, LOW_EVENT);
-+ }
-+ /* Fault status bit is set */
-+ if (reg_val & THM_CHAN_TEMP[2]) {
-+ sta_reg_val = i2c_smbus_read_byte_data(data->client,
-+ THM_STAT_REG_TEMP[3]);
-+ interrupt_status(data->client, sta_reg_val, &status,
-+ ALERT_EVENT);
-+ send_event(data->client, status, FAULT_EVENT);
-+ }
-+}
-+#endif
-+
-+static int emc1403_probe(struct i2c_client *new_client,
-+ const struct i2c_device_id *id)
-+{
-+ int res = 0;
-+ struct thermal_data *data;
-+ u16 pid, smsc_id, revision;
-+
-+#ifdef MOORESTOWN_INTERRUPT_ENABLE
-+ u16 t_irq, a_irq;
-+#endif
-+ data = kzalloc(sizeof(struct thermal_data), GFP_KERNEL);
-+
-+ if (data == NULL) {
-+ printk(KERN_WARNING "emc1403: Memory allocation failed");
-+ return -ENOMEM;
-+ }
-+ data->client = new_client;
-+ i2c_set_clientdata(new_client, data);
-+
-+ /* Check if thermal chip is SMSC and EMC1403 */
-+ smsc_id = i2c_read_current_data(new_client,
-+ THERMAL_SMSC_ID_REG);
-+ if (smsc_id != 0x5d) {
-+ printk(KERN_WARNING "emc1403: vendor id mismatch \n");
-+ goto thermal_error1;
-+ }
-+ pid = i2c_read_current_data(new_client, THERMAL_PID_REG);
-+ if (pid != 0x21) {
-+ printk(KERN_WARNING "emc1403: Prod id mismatch \n");
-+ goto thermal_error1;
-+ }
-+ revision = i2c_read_current_data(new_client,
-+ THERMAL_REVISION_REG);
-+ if (revision != 0x01) {
-+ printk(KERN_WARNING "emc1403: Rev id mismatch is \n");
-+ goto thermal_error1;
-+ }
-+ res = sysfs_create_group(&new_client->dev.kobj, &m_thermal_gr);
-+ if (res) {
-+ printk(KERN_WARNING "emc1403: create group failed! \n");
-+ hwmon_device_unregister(data->hwmon_dev);
-+ goto thermal_error1;
-+ }
-+ data->hwmon_dev = hwmon_device_register(&new_client->dev);
-+ if (IS_ERR(data->hwmon_dev)) {
-+ res = PTR_ERR(data->hwmon_dev);
-+ data->hwmon_dev = NULL;
-+ printk(KERN_WARNING "emc1403:Register hwmon dev Failed\n");
-+ goto thermal_error1;
-+ }
-+#ifdef MOORESTOWN_INTERRUPT_ENABLE
-+ INIT_WORK(&data->therm_handler, (void *)therm_handle_intrpt);
-+ INIT_WORK(&data->alert_handler, (void *)alert_handle_intrpt);
-+ t_irq = new_client->irq;
-+ a_irq = *(short *)new_client->dev.platform_data;
-+ data->therm_irq = t_irq & ~IRQ_TYPE_MASK;
-+ data->alert_irq = a_irq & ~IRQ_TYPE_MASK;
-+ /* interpret irq field */
-+ if (data->therm_irq == 0x113) {
-+ if (t_irq & IRQ_TYPE_MASK) {
-+ /* irq -> GPE_ID */
-+ res = request_gpe(data->therm_irq,
-+ (gpio_function_t)therm_interrupt_handler,
-+ data, DETECT_LEVEL_LOW);
-+ if (res)
-+ dev_crit(&new_client->dev, "%s(): cannot \
-+ register therm gpe \n", __func__);
-+ } else {
-+ res = request_irq(data->therm_irq,
-+ therm_interrupt_handler,
-+ DETECT_LEVEL_LOW, "emc1403", data);
-+ if (res)
-+ dev_crit(&new_client->dev, "%s(): \
-+ cannot get therm IRQ\n", __func__);
-+ }
-+ } else {
-+ printk(KERN_WARNING"emc1403: IRQ mismatch \
-+ sent for therm registration");
-+ }
-+ if (data->alert_irq == 0x114) {
-+ if (a_irq & IRQ_TYPE_MASK) {
-+ /* irq -> GPE_ID */
-+ res = request_gpe(data->alert_irq,
-+ (gpio_function_t)alert_interrupt_handler,
-+ data, DETECT_LEVEL_LOW);
-+ if (res)
-+ dev_crit(&new_client->dev, "%s(): \
-+ cannot register alert gpe \n", __func__);
-+ } else {
-+ res = request_irq(data->alert_irq,
-+ alert_interrupt_handler, DETECT_LEVEL_LOW,
-+ "emc1403", data);
-+ if (res)
-+ dev_crit(&new_client->dev, "%s(): cannot \
-+ get alert IRQ\n", __func__);
-+ }
-+ } else {
-+ printk(KERN_WARNING"emc1403: IRQ mismatch \
-+ sent for alert registration");
-+ }
-+#endif
-+ emc1403_set_default_config(new_client);
-+ dev_info(&new_client->dev, "%s EMC1403 Thermal chip found \n",
-+ new_client->name);
-+ return res;
-+thermal_error1:
-+ i2c_set_clientdata(new_client, NULL);
-+ kfree(data);
-+ return res;
-+}
-+
-+static int emc1403_remove(struct i2c_client *client)
-+{
-+ struct thermal_data *data = i2c_get_clientdata(client);
-+
-+ hwmon_device_unregister(data->hwmon_dev);
-+ sysfs_remove_group(&client->dev.kobj, &m_thermal_gr);
-+ kfree(data);
-+ return 0;
-+}
-+
-+static struct i2c_device_id emc1403_idtable[] = {
-+ { "i2c_thermal", 0 },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(i2c, emc1403_idtable);
-+
-+static struct i2c_driver sensor_emc1403 = {
-+ .driver = {
-+ .name = "emc1403",
-+ },
-+ .probe = emc1403_probe,
-+ .remove = emc1403_remove,
-+ .id_table = emc1403_idtable,
-+};
-+
-+static int __init sensor_emc1403_init(void)
-+{
-+ return i2c_add_driver(&sensor_emc1403);
-+}
-+
-+static void __exit sensor_emc1403_exit(void)
-+{
-+ i2c_del_driver(&sensor_emc1403);
-+}
-+
-+module_init(sensor_emc1403_init);
-+module_exit(sensor_emc1403_exit);
---- /dev/null
-+++ b/drivers/hwmon/hmc6352.c
-@@ -0,0 +1,250 @@
-+/*
-+ * hmc6352.c - Honeywell Compass Driver
-+ *
-+ * Copyright (C) 2009 Intel Corp
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/i2c.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/hwmon-vid.h>
-+#include <linux/err.h>
-+#include <linux/delay.h>
-+#include <linux/mutex.h>
-+#include <linux/sysfs.h>
-+#include <asm/ipc_defs.h>
-+
-+
-+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
-+MODULE_DESCRIPTION("hmc6352 Compass Driver");
-+MODULE_LICENSE("GPL v2");
-+
-+/* internal return values */
-+#define COMP_CALIB_START 1
-+#define COMP_CALIB_STOP 2
-+#define COMP_SLEEP_MODE 0
-+#define COMP_ACTIVE_MODE 1
-+
-+struct compass_data {
-+ struct device *hwmon_dev;
-+};
-+
-+static ssize_t compass_calibration_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret;
-+ unsigned long val;
-+ char cmd[] = {0x43};
-+ char cmd1[] = {0x45};
-+ struct i2c_msg msg[] = {
-+ { client->addr, 0, 1, cmd },
-+ };
-+ struct i2c_msg msg1[] = {
-+ { client->addr, 0, 1, cmd1 },
-+ };
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ if (val == COMP_CALIB_START) {
-+ client->addr = 0x21;
-+ ret = i2c_transfer(client->adapter, msg, 1);
-+ if (ret != 1) {
-+ printk(KERN_WARNING "hmc6352_comp : i2c callib start \
-+ cmd failed \n");
-+ return ret;
-+ }
-+ } else if (val == COMP_CALIB_STOP) {
-+ client->addr = 0x21;
-+ ret = i2c_transfer(client->adapter, msg1, 1);
-+ if (ret != 1) {
-+ printk(KERN_WARNING " hmc6352_comp : i2c callib stop \
-+ cmd failed \n");
-+ return ret;
-+ }
-+ } else
-+ return -EINVAL;
-+
-+ return count;
-+}
-+
-+static ssize_t compass_heading_data_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+
-+ struct i2c_client *client = to_i2c_client(dev);
-+ char cmd[] = {0x41};
-+ unsigned char i2c_data[2] = {0, 0};
-+ unsigned int ret, ret_val;
-+ struct i2c_msg msg[] = {
-+ { client->addr, 0, 1, cmd },
-+ };
-+ struct i2c_msg msg1[] = {
-+ { client->addr, I2C_M_RD, 2, i2c_data },
-+ };
-+
-+ client->addr = 0x21;
-+ ret = i2c_transfer(client->adapter, msg, 1);
-+ if (ret != 1) {
-+ printk(KERN_WARNING "hmc6352 : i2c cmd 0x41 failed \n");
-+ return ret;
-+ }
-+ msleep(10); /* sending 0x41 cmd we need to wait for 7-10 milli second*/
-+ ret = i2c_transfer(client->adapter, msg1, 1);
-+ if (ret != 1) {
-+ printk(KERN_WARNING "hmc6352 : i2c read data cmd failed \n");
-+ return ret;
-+ }
-+ ret_val = i2c_data[0];
-+ ret_val = ((ret_val << 8) | i2c_data[1]);
-+ return sprintf(buf, "%d.%d\n", ret_val/10, ret_val%10);
-+}
-+
-+static ssize_t compass_power_mode_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned long val;
-+ unsigned int ret;
-+ char cmd[] = {0x53};
-+ char cmd1[] = {0x57};
-+ struct i2c_msg msg[] = {
-+ { client->addr, 0, 1, cmd },
-+ };
-+ struct i2c_msg msg1[] = {
-+ { client->addr, 0, 1, cmd1 },
-+ };
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+
-+ if (val == COMP_SLEEP_MODE) {
-+ ret = i2c_transfer(client->adapter, msg, 1);
-+ if (ret != 1)
-+ printk(KERN_WARNING "hmc6352: i2c cmd sleep mode \
-+ failed \n");
-+ } else if (val == COMP_ACTIVE_MODE) {
-+ ret = i2c_transfer(client->adapter, msg1, 1);
-+ if (ret != 1)
-+ printk(KERN_WARNING "hmc6352: i2c cmd active mode \
-+ failed \n");
-+ } else
-+ return -EINVAL;
-+
-+ return count;
-+}
-+
-+static DEVICE_ATTR(heading, S_IRUGO, compass_heading_data_show, NULL);
-+static DEVICE_ATTR(calibration, S_IWUSR, NULL, compass_calibration_store);
-+static DEVICE_ATTR(power_state, S_IWUSR, NULL, compass_power_mode_store);
-+
-+static struct attribute *mid_att_compass[] = {
-+ &dev_attr_heading.attr,
-+ &dev_attr_calibration.attr,
-+ &dev_attr_power_state.attr,
-+ NULL
-+};
-+
-+static struct attribute_group m_compass_gr = {
-+ .name = "hmc6352",
-+ .attrs = mid_att_compass
-+};
-+
-+static int hmc6352_probe(struct i2c_client *client,
-+ const struct i2c_device_id *id)
-+{
-+ int res;
-+ struct compass_data *data;
-+
-+ data = kzalloc(sizeof(struct compass_data), GFP_KERNEL);
-+ if (data == NULL) {
-+ printk(KERN_WARNING "hmc6352: Memory initialization failed");
-+ return -ENOMEM;
-+ }
-+ i2c_set_clientdata(client, data);
-+
-+ res = sysfs_create_group(&client->dev.kobj, &m_compass_gr);
-+ if (res) {
-+ printk(KERN_WARNING "hmc6352: device_create_file failed!!\n");
-+ goto compass_error1;
-+ }
-+ data->hwmon_dev = hwmon_device_register(&client->dev);
-+ if (IS_ERR(data->hwmon_dev)) {
-+ res = PTR_ERR(data->hwmon_dev);
-+ data->hwmon_dev = NULL;
-+ printk(KERN_WARNING "hmc6352: fail to register hwmon device\n");
-+ sysfs_remove_group(&client->dev.kobj, &m_compass_gr);
-+ goto compass_error1;
-+ }
-+ dev_info(&client->dev, "%s HMC6352 compass chip found \n",
-+ client->name);
-+ return res;
-+
-+compass_error1:
-+ i2c_set_clientdata(client, NULL);
-+ kfree(data);
-+ return res;
-+}
-+
-+static int hmc6352_remove(struct i2c_client *client)
-+{
-+ struct compass_data *data = i2c_get_clientdata(client);
-+
-+ hwmon_device_unregister(data->hwmon_dev);
-+ sysfs_remove_group(&client->dev.kobj, &m_compass_gr);
-+ kfree(data);
-+ return 0;
-+}
-+
-+static struct i2c_device_id hmc6352_id[] = {
-+ { "i2c_compass", 0 },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(i2c, hmc6352_id);
-+
-+static struct i2c_driver hmc6352_driver = {
-+ .driver = {
-+ .name = "hmc6352",
-+ },
-+ .probe = hmc6352_probe,
-+ .remove = hmc6352_remove,
-+ .id_table = hmc6352_id,
-+};
-+
-+static int __init sensor_hmc6352_init(void)
-+{
-+ int res;
-+
-+ res = i2c_add_driver(&hmc6352_driver);
-+ return res;
-+}
-+
-+static void __exit sensor_hmc6352_exit(void)
-+{
-+ i2c_del_driver(&hmc6352_driver);
-+}
-+
-+module_init(sensor_hmc6352_init);
-+module_exit(sensor_hmc6352_exit);
---- /dev/null
-+++ b/drivers/hwmon/isl29020.c
-@@ -0,0 +1,248 @@
-+/*
-+ * isl29020.c - Intersil ALS Driver
-+ *
-+ * Copyright (C) 2008 Intel Corp
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/i2c.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/hwmon-vid.h>
-+#include <linux/err.h>
-+#include <linux/delay.h>
-+#include <linux/mutex.h>
-+#include <linux/sysfs.h>
-+#include <asm/ipc_defs.h>
-+
-+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
-+MODULE_DESCRIPTION("intersil isl29020 ALS Driver");
-+MODULE_LICENSE("GPL v2");
-+
-+#define ALS_MIN_RANGE_VAL 0
-+#define ALS_MAX_RANGE_VAL 5
-+#define POWER_STA_ENABLE 1
-+#define POWER_STA_DISABLE 0
-+
-+struct als_data {
-+ struct device *hwmon_dev;
-+};
-+
-+static unsigned int i2c_write_current_data(struct i2c_client *client,
-+ unsigned int reg, unsigned int value)
-+{
-+ int ret_val;
-+
-+ ret_val = i2c_smbus_write_byte_data(client, reg, value);
-+ return ret_val;
-+}
-+
-+static ssize_t als_sensing_range_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int val;
-+
-+ val = i2c_smbus_read_byte_data(client, 0x00);
-+ return sprintf(buf, "%d000\n", 1 << (2 * (val & 3)));
-+
-+}
-+
-+static ssize_t als_lux_output_data_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned int ret_val, val;
-+ unsigned long int lux, max_count;
-+ int tempv1, tempv2;
-+
-+ max_count = 65535;
-+ tempv1 = i2c_smbus_read_byte_data(client, 0x02); /* MSB data */
-+ tempv2 = i2c_smbus_read_byte_data(client, 0x01); /* LSB data */
-+ ret_val = tempv1;
-+ ret_val = (ret_val << 8 | tempv2);
-+ val = i2c_smbus_read_byte_data(client, 0x00);
-+ lux = ((((1 << (2 * (val & 3))))*1000) * ret_val) / max_count;
-+ return sprintf(buf, "%ld\n", lux);
-+}
-+
-+static ssize_t als_sensing_range_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned int ret_val, set_val = 0;
-+ unsigned long val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ ret_val = i2c_smbus_read_byte_data(client, 0x00);
-+ ret_val = ret_val & 0xFC; /*reset the bit before setting them */
-+ if (val == 1)
-+ set_val = (ret_val | 0x00); /* setting the 1:0 bit */
-+ else if (val == 2)
-+ set_val = (ret_val | 0x01);
-+ else if (val == 3)
-+ set_val = (ret_val | 0x02);
-+ else if (val == 4)
-+ set_val = (ret_val | 0x03);
-+ else
-+ goto invarg;
-+ i2c_write_current_data(client, 0x00, set_val);
-+ return count;
-+invarg:
-+ return -EINVAL;
-+}
-+
-+static ssize_t als_power_status_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_smbus_read_byte_data(client, 0x00);
-+ ret_val = ret_val & 0x80;
-+ if (ret_val == 0x80)
-+ ret_val = 1;
-+ return sprintf(buf, "%x", ret_val);
-+}
-+
-+static ssize_t als_power_status_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ unsigned long val = 0;
-+ char curr_val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+
-+ curr_val = i2c_smbus_read_byte_data(client, 0x00);
-+ if (val == POWER_STA_ENABLE)
-+ curr_val = curr_val | 0x80;
-+ else if (val == POWER_STA_DISABLE)
-+ curr_val = curr_val & 0x7F;
-+ else
-+ return -EINVAL;
-+ i2c_write_current_data(client, 0x00, curr_val);
-+ return count;
-+}
-+
-+static DEVICE_ATTR(sensing_range, S_IRUGO | S_IWUSR,
-+ als_sensing_range_show, als_sensing_range_store);
-+static DEVICE_ATTR(lux_output, S_IRUGO, als_lux_output_data_show, NULL);
-+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
-+ als_power_status_show, als_power_status_store);
-+
-+static struct attribute *mid_att_als[] = {
-+ &dev_attr_sensing_range.attr,
-+ &dev_attr_lux_output.attr,
-+ &dev_attr_power_state.attr,
-+ NULL
-+};
-+
-+static struct attribute_group m_als_gr = {
-+ .name = "isl29020",
-+ .attrs = mid_att_als
-+};
-+
-+static void als_set_default_config(struct i2c_client *client)
-+{
-+ i2c_write_current_data(client, 0x00, 0xc0);
-+}
-+
-+static int isl29020_probe(struct i2c_client *client,
-+ const struct i2c_device_id *id)
-+{
-+ int res;
-+ struct als_data *data;
-+
-+ data = kzalloc(sizeof(struct als_data), GFP_KERNEL);
-+ if (data == NULL) {
-+ printk(KERN_WARNING " isl29020: Memory initialization failed");
-+ return -ENOMEM;
-+ }
-+ i2c_set_clientdata(client, data);
-+
-+ res = sysfs_create_group(&client->dev.kobj, &m_als_gr);
-+ if (res) {
-+ printk(KERN_WARNING "isl29020: device create file failed!!\n");
-+ goto als_error1;
-+ }
-+ data->hwmon_dev = hwmon_device_register(&client->dev);
-+ if (IS_ERR(data->hwmon_dev)) {
-+ res = PTR_ERR(data->hwmon_dev);
-+ data->hwmon_dev = NULL;
-+ sysfs_remove_group(&client->dev.kobj, &m_als_gr);
-+ printk(KERN_ALERT "isl29020:unable to register hwmon device\n");
-+ goto als_error1;
-+ }
-+ dev_info(&client->dev, "%s isl29020: ALS chip found \n", client->name);
-+ als_set_default_config(client);
-+ return res;
-+
-+als_error1:
-+ i2c_set_clientdata(client, NULL);
-+ kfree(data);
-+ return res;
-+}
-+
-+static int isl29020_remove(struct i2c_client *client)
-+{
-+ struct als_data *data = i2c_get_clientdata(client);
-+
-+ hwmon_device_unregister(data->hwmon_dev);
-+ sysfs_remove_group(&client->dev.kobj, &m_als_gr);
-+ kfree(data);
-+ return 0;
-+}
-+
-+static struct i2c_device_id isl29020_id[] = {
-+ { "i2c_als", 0 },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(i2c, isl29020_id);
-+
-+static struct i2c_driver isl29020_driver = {
-+ .driver = {
-+ .name = "isl29020",
-+ },
-+ .probe = isl29020_probe,
-+ .remove = isl29020_remove,
-+ .id_table = isl29020_id,
-+};
-+
-+static int __init sensor_isl29020_init(void)
-+{
-+ int res;
-+
-+ res = i2c_add_driver(&isl29020_driver);
-+ return res;
-+}
-+
-+static void __exit sensor_isl29020_exit(void)
-+{
-+ i2c_del_driver(&isl29020_driver);
-+}
-+
-+module_init(sensor_isl29020_init);
-+module_exit(sensor_isl29020_exit);
---- /dev/null
-+++ b/drivers/hwmon/lis331dl.c
-@@ -0,0 +1,322 @@
-+/*
-+ * lis331dl.c - ST LIS331DL Accelerometer Driver
-+ *
-+ * Copyright (C) 2009 Intel Corp
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/i2c.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/hwmon-vid.h>
-+#include <linux/err.h>
-+#include <linux/delay.h>
-+#include <linux/mutex.h>
-+#include <linux/sysfs.h>
-+
-+
-+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
-+MODULE_DESCRIPTION("STMacroelectronics LIS331DL Accelerometer Driver");
-+MODULE_LICENSE("GPL v2");
-+
-+#define ACCEL_DATA_RATE_100HZ 0
-+#define ACCEL_DATA_RATE_400HZ 1
-+#define ACCEL_POWER_MODE_DOWN 0
-+#define ACCEL_POWER_MODE_ACTIVE 1
-+#define ACCEL_NORMAL_MODE 0
-+#define ACCEL_MEMORY_REBOOT 1
-+
-+/* internal return values */
-+
-+struct acclero_data {
-+ struct device *hwmon_dev;
-+ struct mutex update_lock;
-+};
-+
-+static unsigned int i2c_write_current_data(struct i2c_client *client,
-+ unsigned int reg, unsigned int value)
-+{
-+ int ret_val;
-+
-+ ret_val = i2c_smbus_write_byte_data(client, reg, value);
-+ return ret_val;
-+}
-+
-+static ssize_t data_rate_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val, val;
-+
-+ val = i2c_smbus_read_byte_data(client, 0x20);
-+ ret_val = (val & 0x80); /* 1= 400HZ 0= 100HZ */
-+ if (ret_val == 0x80)
-+ ret_val = 1;
-+ return sprintf(buf, "%d\n", ret_val);
-+
-+}
-+
-+static ssize_t power_mode_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val, val;
-+
-+ val = i2c_smbus_read_byte_data(client, 0x20);
-+ ret_val = (val & 0x40);
-+ if (ret_val == 0x40)
-+ ret_val = 1;
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t x_pos_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_smbus_read_byte_data(client, 0x29);
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t y_pos_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_smbus_read_byte_data(client, 0x2B);
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t z_pos_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ int ret_val;
-+
-+ ret_val = i2c_smbus_read_byte_data(client, 0x2D);
-+ return sprintf(buf, "%d\n", ret_val);
-+}
-+
-+static ssize_t xyz_pos_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ int x, y, z;
-+ struct i2c_client *client = to_i2c_client(dev);
-+
-+ x = i2c_smbus_read_byte_data(client, 0x29);
-+ y = i2c_smbus_read_byte_data(client, 0x2B);
-+ z = i2c_smbus_read_byte_data(client, 0x2D);
-+ return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
-+}
-+
-+static ssize_t data_rate_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct acclero_data *data = i2c_get_clientdata(client);
-+ unsigned int ret_val, set_val;
-+ unsigned long val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ ret_val = i2c_smbus_read_byte_data(client, 0x20);
-+
-+ mutex_lock(&data->update_lock);
-+ if (val == ACCEL_DATA_RATE_100HZ)
-+ set_val = (ret_val & 0x7F); /* setting the 8th bit to 0 */
-+ else if (val == ACCEL_DATA_RATE_400HZ)
-+ set_val = (ret_val | (1 << 7));
-+ else
-+ goto invarg;
-+
-+ i2c_write_current_data(client, 0x20, set_val);
-+ mutex_unlock(&data->update_lock);
-+ return count;
-+invarg:
-+ mutex_unlock(&data->update_lock);
-+ return -EINVAL;
-+}
-+
-+static ssize_t power_mode_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct acclero_data *data = i2c_get_clientdata(client);
-+ unsigned int ret_val, set_val;
-+ unsigned long val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ ret_val = i2c_smbus_read_byte_data(client, 0x20);
-+
-+ mutex_lock(&data->update_lock);
-+ if (val == ACCEL_POWER_MODE_DOWN)
-+ set_val = ret_val & 0xBF; /* if value id 0 */
-+ else if (val == ACCEL_POWER_MODE_ACTIVE)
-+ set_val = (ret_val | (1<<6)); /* if value is 1 */
-+ else
-+ goto invarg;
-+
-+ i2c_write_current_data(client, 0x20, set_val);
-+ mutex_unlock(&data->update_lock);
-+ return count;
-+invarg:
-+ mutex_unlock(&data->update_lock);
-+ return -EINVAL;
-+}
-+
-+static ssize_t reboot_mem_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct i2c_client *client = to_i2c_client(dev);
-+ struct acclero_data *data = i2c_get_clientdata(client);
-+ unsigned int ret_val, set_val;
-+ unsigned long val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ ret_val = i2c_smbus_read_byte_data(client, 0x21);
-+ if (val == ACCEL_MEMORY_REBOOT) {
-+ mutex_lock(&data->update_lock);
-+ set_val = (ret_val | (1 << 6)); /* setting the 6th bit */
-+ i2c_write_current_data(client, 0x21, set_val);
-+ mutex_unlock(&data->update_lock);
-+ } else
-+ return -EINVAL;
-+ return count;
-+}
-+
-+static DEVICE_ATTR(data_rate, S_IRUGO | S_IWUSR,
-+ data_rate_show, data_rate_store);
-+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
-+ power_mode_show, power_mode_store);
-+static DEVICE_ATTR(reboot_mem, S_IWUSR, NULL,
-+ reboot_mem_store);
-+static DEVICE_ATTR(x, S_IRUGO, x_pos_show, NULL);
-+static DEVICE_ATTR(y, S_IRUGO, y_pos_show, NULL);
-+static DEVICE_ATTR(z, S_IRUGO, z_pos_show, NULL);
-+static DEVICE_ATTR(curr_pos, S_IRUGO, xyz_pos_show, NULL);
-+
-+static struct attribute *mid_att_acclero[] = {
-+ &dev_attr_data_rate.attr,
-+ &dev_attr_power_state.attr,
-+ &dev_attr_reboot_mem.attr,
-+ &dev_attr_x.attr,
-+ &dev_attr_y.attr,
-+ &dev_attr_z.attr,
-+ &dev_attr_curr_pos.attr,
-+ NULL
-+};
-+
-+static struct attribute_group m_acclero_gr = {
-+ .name = "lis331dl",
-+ .attrs = mid_att_acclero
-+};
-+
-+static void accel_set_default_config(struct i2c_client *client)
-+{
-+ i2c_write_current_data(client, 0x20, 0x47);
-+}
-+
-+static int lis331dl_probe(struct i2c_client *client,
-+ const struct i2c_device_id *id)
-+{
-+ int res;
-+ struct acclero_data *data;
-+
-+ data = kzalloc(sizeof(struct acclero_data), GFP_KERNEL);
-+ if (data == NULL) {
-+ printk(KERN_WARNING "lis331dl: Memory initi failed \n");
-+ return -ENOMEM;
-+ }
-+ mutex_init(&data->update_lock);
-+ i2c_set_clientdata(client, data);
-+
-+ res = sysfs_create_group(&client->dev.kobj, &m_acclero_gr);
-+ if (res) {
-+ printk(KERN_WARNING "lis331dl: Sysfs group failed!!\n");
-+ goto acclero_error1;
-+ }
-+ data->hwmon_dev = hwmon_device_register(&client->dev);
-+ if (IS_ERR(data->hwmon_dev)) {
-+ res = PTR_ERR(data->hwmon_dev);
-+ data->hwmon_dev = NULL;
-+ sysfs_remove_group(&client->dev.kobj, &m_acclero_gr);
-+ printk(KERN_WARNING "lis331dl: unable to register \
-+ hwmon device\n");
-+ goto acclero_error1;
-+ }
-+ accel_set_default_config(client);
-+
-+ dev_info(&client->dev, "%s lis331dl: Accelerometer chip \
-+ foundn", client->name);
-+ return res;
-+
-+acclero_error1:
-+ i2c_set_clientdata(client, NULL);
-+ kfree(data);
-+ return res;
-+}
-+
-+static int lis331dl_remove(struct i2c_client *client)
-+{
-+ struct acclero_data *data = i2c_get_clientdata(client);
-+
-+ hwmon_device_unregister(data->hwmon_dev);
-+ sysfs_remove_group(&client->dev.kobj, &m_acclero_gr);
-+ kfree(data);
-+ return 0;
-+}
-+
-+static struct i2c_device_id lis331dl_id[] = {
-+ { "i2c_accel", 0 },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(i2c, lis331dl_id);
-+
-+static struct i2c_driver lis331dl_driver = {
-+ .driver = {
-+ .name = "lis331dl",
-+ },
-+ .probe = lis331dl_probe,
-+ .remove = lis331dl_remove,
-+ .id_table = lis331dl_id,
-+};
-+
-+static int __init sensor_lis331dl_init(void)
-+{
-+ int res;
-+
-+ res = i2c_add_driver(&lis331dl_driver);
-+ return res;
-+}
-+
-+static void __exit sensor_lis331dl_exit(void)
-+{
-+ i2c_del_driver(&lis331dl_driver);
-+}
-+
-+module_init(sensor_lis331dl_init);
-+module_exit(sensor_lis331dl_exit);
---- a/drivers/misc/Kconfig
-+++ b/drivers/misc/Kconfig
-@@ -249,6 +249,13 @@ config SGI_GRU_DEBUG
- This option enables addition debugging code for the SGI GRU driver. If
- you are unsure, say N.
-
-+config MRST_VIB
-+ tristate "vibrator driver for Intel Moorestown platform"
-+ help
-+ Vibrator for Intel Moorestown platform.
-+
-+ If unsure, say N.
-+
- config ISL29003
- tristate "Intersil ISL29003 ambient light sensor"
- depends on I2C && SYSFS
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -22,6 +22,7 @@ obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfg
- obj-$(CONFIG_HP_ILO) += hpilo.o
- obj-$(CONFIG_MRST) += intel_mrst.o
- obj-$(CONFIG_ISL29003) += isl29003.o
-+obj-$(CONFIG_MRST_VIB) += mrst_vib.o
- obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
- obj-$(CONFIG_DS1682) += ds1682.o
- obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
---- /dev/null
-+++ b/drivers/misc/mrst_vib.c
-@@ -0,0 +1,99 @@
-+/*
-+ * mrst_vib.c - Intel vibrator Driver
-+ *
-+ * Copyright (C) 2008 Intel Corp
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <linux/kernel.h>
-+#include <linux/sysfs.h>
-+#include <asm/ipc_defs.h>
-+
-+
-+MODULE_AUTHOR("Kalhan Trisal");
-+MODULE_DESCRIPTION("Intel Moorestown Thermal Driver");
-+MODULE_LICENSE("GPL v2");
-+
-+#define VIB_START 1
-+#define VIB_STOP 2
-+static struct platform_device *vib_pdev;
-+
-+static ssize_t vib_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+
-+ struct ipc_pmic_reg_data vib_power_reg_write = {0};
-+ unsigned long val;
-+
-+ if (strict_strtoul(buf, 10, &val))
-+ return -EINVAL;
-+ if (val == VIB_START) {
-+ vib_power_reg_write.ioc = TRUE;
-+ vib_power_reg_write.pmic_reg_data[0].register_address = 0x49;
-+ vib_power_reg_write.pmic_reg_data[0].value = 0xAD;
-+ vib_power_reg_write.num_entries = 1;
-+ if (ipc_pmic_register_write(&vib_power_reg_write, TRUE)) {
-+ printk(KERN_WARNING "mrst_vib: failed to turn ON \
-+ vib \n");
-+ return -EINVAL;
-+ }
-+ } else if (val == VIB_STOP) {
-+ vib_power_reg_write.ioc = TRUE;
-+ vib_power_reg_write.pmic_reg_data[0].register_address = 0x49;
-+ vib_power_reg_write.pmic_reg_data[0].value = 0x14;
-+ vib_power_reg_write.num_entries = 1;
-+ if (ipc_pmic_register_write(&vib_power_reg_write, TRUE)) {
-+ printk(KERN_WARNING "mrst_vib: failed to turn OFF \
-+ Vibrator \n");
-+ return -EINVAL;
-+ }
-+ } else
-+ return -EINVAL;
-+
-+ return count;
-+}
-+
-+static struct device_attribute dev_attr_vib =
-+ __ATTR(vib, S_IWUSR, NULL, vib_store);
-+
-+static int __init mrst_vib_init(void)
-+{
-+ int res = 0;
-+
-+ vib_pdev = platform_device_register_simple("mrst_vib", -1, NULL, 0);
-+ if (IS_ERR(vib_pdev)) {
-+ res = PTR_ERR(vib_pdev);
-+ vib_pdev = NULL;
-+ printk(KERN_WARNING "mrst_vib: unable to register platform \
-+ device\n");
-+ return res;
-+ }
-+ res = device_create_file(&vib_pdev->dev, &dev_attr_vib);
-+ return res;
-+}
-+
-+static void __exit mrst_vib_exit(void)
-+{
-+ device_remove_file(&vib_pdev->dev, &dev_attr_vib);
-+ platform_device_unregister(vib_pdev);
-+}
-+
-+module_init(mrst_vib_init);
-+module_exit(mrst_vib_exit);