diff options
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.patch | 1836 |
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); |