summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch
diff options
context:
space:
mode:
authorSaul Wold <Saul.Wold@intel.com>2010-09-24 15:36:24 -0700
committerSaul Wold <Saul.Wold@intel.com>2010-09-24 16:43:21 -0700
commit239a368d5715d8f5b7733f9400339c2350c49369 (patch)
tree2953f12b45e590d9e14b6f72f8e4ee7188e41508 /meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch
parentc5b9525263dac6844d152e40acf8cee4d27b60bc (diff)
downloadpoky-239a368d5715d8f5b7733f9400339c2350c49369.tar.gz
netbook: Correct netbook build by moving netbook configuration from moblin to meta
Signed-off-by: Saul Wold <Saul.Wold@intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch1836
1 files changed, 1836 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch
new file mode 100644
index 0000000000..fce4524518
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-sensor-driver-1.1.patch
@@ -0,0 +1,1836 @@
1From cffaf6b15ff40cfbeafd0d4728ba3a5a5fb6155f Mon Sep 17 00:00:00 2001
2From: Alan Olsen <alan.r.olsen@intel.com>
3Date: Thu, 15 Oct 2009 14:26:47 -0700
4Subject: [PATCH 062/104] Moorestown Sensor drivers v1.1 consolidated patch
5
6This patch contains the following patches:
7
8Alpha2-1.1-1-5-mrst-Sensors-ALS-Driver-for-Moorestown.patch
9
10 [PATCH] ALS Driver for Moorestown Sensors
11
12 This patch single patch for Alpha2:2.0. ALS driver will read
13 the latest Lux measurement based on the light brightness and
14 will report the LUX output through sysfs interface.
15
16 Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
17
18Alpha2-1.1-2-5-mrst-Sensors-Compass-Driver-for-Moorestown.patch
19
20 [PATCH] Compass Driver for Moorestown Sensors
21 This patch single patch for Alpha2:2.0.This driver will report
22 the heading values in degrees to the sysfs interface.The vlaues
23 returned are head . e.g. 245.6
24
25 Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
26
27Alpha2-1.1-3-5-mrst-Sensors-Accelerometer-Driver-for-Moorestown.patch
28
29 [PATCH] Accelerometer Driver for Moorestown Sensors
30
31 This patch single patch for Alpha2:2.0.Accelerometer driver will
32 read the x,y,z coordinate registers and provide the information to
33 user through sysfs interface.
34
35 Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
36
37Alpha2-1.1-4-5-mrst-Sensors-Vibrator-Driver-for-Moorestown.patch
38
39 [PATCH] Vibrator Driver for Moorestown Sensors
40
41 This patch single patch for Alpha2:2.0.Vibrator can be switched
42 on/off using sysfs interface.
43
44 Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com>
45
46Alpha2-1.1-5-5-mrst-Sensors-Thermal-Driver-for-Moorestown.patch
47
48 [PATCH] Thermal Driver for Moorestown Sensors
49
50 Moorestown Platform has EMC1403 chip which support three thermal
51 devices, one thermal zone is used by the EMC1403 chip itself and
52 second is used by processor and third one is used for platform
53 (skin temperature).Driver support poll and interrupt
54 mode,min/max/crit configuration can be done using sysfs interface.
55
56 The driver also support interrupt mode when the temperature crosses the
57 threshold configured value the min/max/crit. ALERT/THERM interrupt will
58 be triggered and driver register its callback with GPE driver, and send
59 the events to OSPM power management to take action. OSPM will take
60 action and set the new threshold values till it doesnot get ALERT/THERM
61 events.temp1 is used for configuring internal EMC1403 chip diode, temp2
62 is used to configure processor diode and temp3 is used to configure the
63 platform diode.
64
65 The interrupt mode code has dependency MRST PMIC_GPIO/MAX7315/OSPM.Flag
66 is added to differentiate the generic functionality of the driver with
67 moorestown specific.
68
69 Signed-off-by: Kalhan Trisal <kalhan.trisal at intel.com>
70
71Signed-off-by: Alan Olsen <alan.r.olsen@intel.com>
72---
73 drivers/hwmon/Kconfig | 35 ++
74 drivers/hwmon/Makefile | 4
75 drivers/hwmon/emc1403.c | 731 +++++++++++++++++++++++++++++++++++++++++++++++
76 drivers/hwmon/hmc6352.c | 250 ++++++++++++++++
77 drivers/hwmon/isl29020.c | 248 +++++++++++++++
78 drivers/hwmon/lis331dl.c | 322 ++++++++++++++++++++
79 drivers/misc/Kconfig | 7
80 drivers/misc/Makefile | 1
81 drivers/misc/mrst_vib.c | 99 ++++++
82 9 files changed, 1697 insertions(+)
83 create mode 100644 drivers/hwmon/emc1403.c
84 create mode 100644 drivers/hwmon/hmc6352.c
85 create mode 100644 drivers/hwmon/isl29020.c
86 create mode 100644 drivers/hwmon/lis331dl.c
87 create mode 100644 drivers/misc/mrst_vib.c
88
89--- a/drivers/hwmon/Kconfig
90+++ b/drivers/hwmon/Kconfig
91@@ -28,6 +28,41 @@ config HWMON_VID
92 tristate
93 default n
94
95+config SENSORS_ISL29020
96+ tristate "Intersil ISL29020 ALS"
97+ depends on I2C_MRST
98+ help
99+ If you say yes here you get support for the ALS Devices
100+ Ambient Light Sensor monitoring chip.
101+ Range values can be configured using sysfs.
102+ Lux Data are accessible via sysfs.
103+
104+config SENSORS_HMC6352
105+ tristate "Honeywell HMC6352 compass"
106+ depends on I2C_MRST
107+ help
108+ If you say yes here you get support for the Compass Devices
109+ Device can be configured using sysfs.
110+ heading data can be accessible via sysfs.
111+
112+config SENSORS_LIS331DL
113+ tristate "STMicroeletronics LIS331DL three-axis digital accelerometer"
114+ depends on I2C_MRST
115+ help
116+ If you say yes here you get support for the Accelerometer Devices
117+ Device can be configured using sysfs.
118+ x y Z data can be accessible via sysfs.
119+
120+config SENSORS_EMC1403
121+ tristate "SMSC EMC1403 Thermal"
122+ depends on I2C_MRST && GPE && GPIO_MAX7315 && MSTWN_POWER_MGMT
123+ help
124+ If you say yes here you get support for the SMSC Devices
125+ EMC1403 temperature monitoring chip.
126+
127+ Threshold values can be configured using sysfs.
128+ Data from the different diode are accessible via sysfs.
129+
130 config HWMON_DEBUG_CHIP
131 bool "Hardware Monitoring Chip debugging messages"
132 default n
133--- a/drivers/hwmon/Makefile
134+++ b/drivers/hwmon/Makefile
135@@ -99,6 +99,10 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l7
136 obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
137 obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
138 obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
139+obj-$(CONFIG_SENSORS_ISL29020) += isl29020.o
140+obj-$(CONFIG_SENSORS_HMC6352) += hmc6352.o
141+obj-$(CONFIG_SENSORS_LIS331DL) += lis331dl.o
142+obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
143
144 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
145 EXTRA_CFLAGS += -DDEBUG
146--- /dev/null
147+++ b/drivers/hwmon/emc1403.c
148@@ -0,0 +1,731 @@
149+/*
150+ * emc1403.c - SMSC Thermal Driver
151+ *
152+ * Copyright (C) 2008 Intel Corp
153+ *
154+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
155+ *
156+ * This program is free software; you can redistribute it and/or modify
157+ * it under the terms of the GNU General Public License as published by
158+ * the Free Software Foundation; version 2 of the License.
159+ *
160+ * This program is distributed in the hope that it will be useful, but
161+ * WITHOUT ANY WARRANTY; without even the implied warranty of
162+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
163+ * General Public License for more details.
164+ *
165+ * You should have received a copy of the GNU General Public License along
166+ * with this program; if not, write to the Free Software Foundation, Inc.,
167+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
168+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169+ */
170+
171+#include <linux/module.h>
172+#include <linux/init.h>
173+#include <linux/slab.h>
174+#include <linux/i2c.h>
175+#include <linux/hwmon.h>
176+#include <linux/hwmon-sysfs.h>
177+#include <linux/hwmon-vid.h>
178+#include <linux/interrupt.h>
179+#include <linux/workqueue.h>
180+#include <linux/err.h>
181+#include <linux/delay.h>
182+#include <linux/mutex.h>
183+#include <linux/sysfs.h>
184+#include <linux/gpe.h>
185+#include <linux/intel_mid.h>
186+
187+
188+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
189+MODULE_DESCRIPTION("emc1403 Thermal Driver");
190+MODULE_LICENSE("GPL v2");
191+
192+/* To support the interrupt mechanism for moorestown interrupt flag is added
193+ * If the flag is not enabled it support generic emc1403 chip */
194+
195+#if defined(CONFIG_GPIO_LNWPMIC) && defined(CONFIG_GPIO_MAX7315) \
196+ && defined(CONFIG_MSTWN_POWER_MGMT)
197+#define MOORESTOWN_INTERRUPT_ENABLE
198+#endif
199+
200+/* Limit status reg Therm/High/Low/Fault*/
201+static const u8 THM_STAT_REG_TEMP[] = { 0x37, 0x35, 0x36, 0x1B, 0x02};
202+
203+/* Channel diode temp set */
204+static const u8 THM_CHAN_TEMP[] = { 0x10, 0x08, 0x04, 0x02, 0x01 };
205+
206+/* Therm Limit reg store values */
207+static const u8 THM_LIMIT_REG_TEMP[] = { 0x05, 0x06, 0x07, 0x08, 0x15, 0x16,
208+ 0x19, 0x1A, 0x20, 0x21 };
209+
210+/* DATA REGISTERS */
211+static const u8 THM_REG_CURR_TEMP[] = { 0x00, 0x01, 0x23 };
212+
213+#define THERMAL_PID_REG 0xfd
214+#define THERMAL_SMSC_ID_REG 0xfe
215+#define THERMAL_REVISION_REG 0xff
216+#define THERMAL_ADC_UPDATE_BUSY 0x80
217+#define I2C_THERMAL_SLAVE_ADDR 0x4C
218+#define TEMP1 1
219+#define TEMP2 2
220+#define TEMP3 4
221+#define IRQ_TYPE_MASK (1 << 15)
222+#define HIGH_EVENT 1
223+#define LOW_EVENT 2
224+#define THERM_EVENT 3
225+#define FAULT_EVENT 4
226+#define ALERT_EVENT 1
227+#define POWER_STA_ENABLE 0
228+#define POWER_STA_DISABLE 1
229+#define INTERRUPT_MODE_ENABLE 0
230+#define INTERRUPT_MODE_DISABLE 1
231+
232+struct thermal_data {
233+ struct i2c_client *client;
234+ struct device *hwmon_dev;
235+ int therm_irq;
236+ int alert_irq;
237+ struct work_struct therm_handler;
238+ struct work_struct alert_handler;
239+};
240+
241+static unsigned int i2c_read_current_data(struct i2c_client *client, u8 reg)
242+{
243+ unsigned int ret_val;
244+
245+ ret_val = i2c_smbus_read_byte_data(client, reg);
246+ return ret_val;
247+}
248+
249+static unsigned int i2c_write_current_data(struct i2c_client *client,
250+ unsigned int reg, unsigned int value)
251+{
252+ int ret_val;
253+
254+ ret_val = i2c_smbus_write_byte_data(client, reg, value);
255+ return ret_val;
256+}
257+
258+static int calculate_offset(int type, int temp_ofs)
259+{
260+ int offset = 0;
261+
262+ switch (type) {
263+ case TEMP1:
264+ if (temp_ofs == 0)
265+ offset = 1;
266+ else if (temp_ofs == 1)
267+ offset = 0;
268+ else if (temp_ofs == 2)
269+ offset = 8;
270+ break;
271+ case TEMP2:
272+ if (temp_ofs == 0)
273+ offset = 3;
274+ else if (temp_ofs == 1)
275+ offset = 2;
276+ else if (temp_ofs == 2)
277+ offset = 6;
278+ break;
279+ case TEMP3:
280+ if (temp_ofs == 0)
281+ offset = 5;
282+ else if (temp_ofs == 1)
283+ offset = 4;
284+ else if (temp_ofs == 2)
285+ offset = 7;
286+ break;
287+ default:
288+ offset = -1;
289+ printk(KERN_WARNING "emc1403: Invalid arg \n");
290+ break;
291+ }
292+ return offset;
293+
294+}
295+
296+#ifdef MOORESTOWN_INTERRUPT_ENABLE
297+static void status_reg_read(struct i2c_client *client)
298+{
299+ i2c_read_current_data(client, 0x36);
300+ i2c_read_current_data(client, 0x35);
301+ i2c_read_current_data(client, 0x1B);
302+}
303+
304+/* when the thermal governor takes action we unmask the bit
305+ * if the temp is lower tham threshold values then no new event will
306+ * be raised else if the current temperature is still high the interrupt
307+ * will be sent again */
308+
309+static void reg_unmask_intr(struct i2c_client *client, int offset,
310+ int value)
311+{
312+ u8 ret_val, set_mask, ret = 0, alert = 0;
313+
314+ ret_val = i2c_read_current_data(client, 0x1F);
315+ if (offset == 6 || offset == 7 || offset == 8) {
316+ ret = i2c_read_current_data(client, 0x37); /* Themal status */
317+ } else if (offset == 2 || offset == 3) {
318+ if (((ret_val >> 1) & 1)) {
319+ set_mask = (ret_val & 0x05);
320+ alert = 1;
321+ }
322+ } else if (offset == 4 || offset == 5) {
323+ if (((ret_val >> 2) & 1)) {
324+ set_mask = (ret_val & 0x03);
325+ alert = 1;
326+ }
327+ } else if (offset == 0 || offset == 1) {
328+ if (ret_val & 1) {
329+ set_mask = (ret_val & 0x06);
330+ alert = 1;
331+ }
332+ }
333+ /* only rest set the mask for alert events */
334+ if (alert == 1) {
335+ status_reg_read(client);
336+ i2c_write_current_data(client, 0x1F, set_mask);
337+ }
338+}
339+#endif
340+
341+static ssize_t show_temp_auto_offset(struct device *dev,
342+ struct device_attribute *attr, char *buf)
343+{
344+ struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr);
345+ int temp_index = s_attr->index;
346+ int temp_ofs = s_attr->nr;
347+ struct i2c_client *client = to_i2c_client(dev);
348+ int ret_val = 0;
349+ int ret_offset = 0;
350+
351+ ret_offset = calculate_offset(temp_index, temp_ofs);
352+ if (ret_offset != -1) {
353+ ret_val = i2c_read_current_data(client,
354+ THM_LIMIT_REG_TEMP[ret_offset]);
355+ return sprintf(buf, "%d\n", ret_val);
356+ } else {
357+ return -EINVAL;
358+ }
359+}
360+
361+static ssize_t store_temp_auto_offset(struct device *dev,
362+ struct device_attribute *attr, const char *buf, size_t count)
363+{
364+ struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr);
365+ int temp_index = s_attr->index;
366+ int temp_ofs = s_attr->nr;
367+ struct i2c_client *client = to_i2c_client(dev);
368+ unsigned long val;
369+ int ret_offset = 0;
370+
371+ if (strict_strtoul(buf, 10, &val))
372+ return -EINVAL;
373+ ret_offset = calculate_offset(temp_index, temp_ofs);
374+ if (ret_offset != -1) {
375+ i2c_write_current_data(client,
376+ THM_LIMIT_REG_TEMP[ret_offset], val);
377+#ifdef MOORESTOWN_INTERRUPT_ENABLE
378+ reg_unmask_intr(client, ret_offset, val);
379+#endif
380+ return count;
381+ } else {
382+ return -EINVAL;
383+ }
384+}
385+
386+static ssize_t show_temp_hyst(struct device *dev,
387+ struct device_attribute *attr, char *buf)
388+{
389+ struct i2c_client *client = to_i2c_client(dev);
390+ int ret_val;
391+
392+ ret_val = i2c_read_current_data(client, THM_LIMIT_REG_TEMP[9]);
393+ return sprintf(buf, "%d\n", ret_val);
394+}
395+
396+static ssize_t store_temp_hyst(struct device *dev,
397+ struct device_attribute *attr, const char *buf, size_t count)
398+{
399+ struct i2c_client *client = to_i2c_client(dev);
400+ unsigned long val = 0;
401+
402+ if (strict_strtoul(buf, 10, &val))
403+ return -EINVAL;
404+ i2c_write_current_data(client, THM_LIMIT_REG_TEMP[9], val);
405+ return count;
406+}
407+
408+static ssize_t show_temp1_curr_temp(struct device *dev,
409+ struct device_attribute *attr, char *buf)
410+{
411+ struct i2c_client *client = to_i2c_client(dev);
412+ int ret_val;
413+
414+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[0]);
415+ return sprintf(buf, "%d\n", ret_val);
416+}
417+
418+static ssize_t show_temp2_curr_temp(struct device *dev,
419+ struct device_attribute *attr, char *buf)
420+{
421+ struct i2c_client *client = to_i2c_client(dev);
422+ int ret_val;
423+
424+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[1]);
425+ return sprintf(buf, "%d\n", ret_val);
426+}
427+
428+static ssize_t show_temp3_curr_temp(struct device *dev,
429+ struct device_attribute *attr, char *buf)
430+{
431+ struct i2c_client *client = to_i2c_client(dev);
432+ int ret_val;
433+
434+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[2]);
435+ return sprintf(buf, "%d\n", ret_val);
436+}
437+
438+static ssize_t show_status_reg(struct device *dev,
439+ struct device_attribute *attr, char *buf)
440+{
441+ struct i2c_client *client = to_i2c_client(dev);
442+ int ret_val1, ret_val2, ret_val3, ret_val4;
443+
444+ ret_val1 = i2c_read_current_data(client, 0x1F);
445+ ret_val2 = i2c_read_current_data(client, 0x35);
446+ ret_val3 = i2c_read_current_data(client, 0x36);
447+ ret_val4 = i2c_read_current_data(client, 0x37);
448+ return sprintf(buf, "alarm=%x,High=%x,Low=%x,Therm=%x \n",
449+ ret_val1, ret_val2, ret_val3, ret_val4);
450+}
451+
452+static ssize_t show_power_state(struct device *dev,
453+ struct device_attribute *attr, char *buf)
454+{
455+ struct i2c_client *client = to_i2c_client(dev);
456+ int ret_val;
457+
458+ ret_val = i2c_read_current_data(client, 0x03);
459+ ret_val = ret_val & 0x40;
460+ if (ret_val == 0x40)
461+ ret_val = 1;
462+ return sprintf(buf, "%x", ret_val);
463+}
464+
465+static ssize_t store_power_state(struct device *dev,
466+ struct device_attribute *attr, const char *buf, size_t count)
467+{
468+ struct i2c_client *client = to_i2c_client(dev);
469+ unsigned long val = 0;
470+ char curr_val;
471+
472+ if (strict_strtoul(buf, 10, &val))
473+ return -EINVAL;
474+
475+ curr_val = i2c_read_current_data(client, 0x03);
476+ if (val == POWER_STA_ENABLE)
477+ curr_val = curr_val & 0xBF;
478+ else if (val == POWER_STA_DISABLE)
479+ curr_val = curr_val | 0x40;
480+ else
481+ return -EINVAL;
482+ i2c_write_current_data(client, 0x03, curr_val);
483+ return count;
484+}
485+
486+static ssize_t show_mode(struct device *dev,
487+ struct device_attribute *attr, char *buf)
488+{
489+ struct i2c_client *client = to_i2c_client(dev);
490+ int ret_val;
491+
492+ ret_val = i2c_read_current_data(client, 0x03);
493+ ret_val = ret_val & 0x80;
494+ if (ret_val == 0x80)
495+ ret_val = 1;
496+ return sprintf(buf, "%x", ret_val);
497+}
498+
499+static ssize_t store_mode(struct device *dev,
500+ struct device_attribute *attr, const char *buf, size_t count)
501+{
502+ struct i2c_client *client = to_i2c_client(dev);
503+ unsigned long val = 0;
504+ char curr_val;
505+
506+ if (strict_strtoul(buf, 10, &val))
507+ return -EINVAL;
508+
509+ curr_val = i2c_read_current_data(client, 0x03);
510+ if (val == INTERRUPT_MODE_ENABLE)
511+ curr_val = curr_val & 0x7F;
512+ else if (val == INTERRUPT_MODE_DISABLE)
513+ curr_val = curr_val | 0x80;
514+ else
515+ return -EINVAL;
516+ i2c_write_current_data(client, 0x03, curr_val);
517+ return count;
518+}
519+
520+static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR,
521+ show_temp_auto_offset, store_temp_auto_offset, 0, 1);
522+static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR,
523+ show_temp_auto_offset, store_temp_auto_offset, 1, 1);
524+static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR,
525+ show_temp_auto_offset, store_temp_auto_offset, 2, 1);
526+static DEVICE_ATTR(temp1_curr, S_IRUGO, show_temp1_curr_temp, NULL);
527+
528+static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR,
529+ show_temp_auto_offset, store_temp_auto_offset, 0, 2);
530+static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR,
531+ show_temp_auto_offset, store_temp_auto_offset, 1, 2);
532+static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR,
533+ show_temp_auto_offset, store_temp_auto_offset, 2, 2);
534+static DEVICE_ATTR(temp2_curr, S_IRUGO, show_temp2_curr_temp, NULL);
535+
536+static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR,
537+ show_temp_auto_offset, store_temp_auto_offset, 0, 4);
538+static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR,
539+ show_temp_auto_offset, store_temp_auto_offset, 1, 4);
540+static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR,
541+ show_temp_auto_offset, store_temp_auto_offset, 2, 4);
542+static DEVICE_ATTR(temp3_curr, S_IRUGO, show_temp3_curr_temp, NULL);
543+
544+static DEVICE_ATTR(hyster, S_IRUGO | S_IWUSR, show_temp_hyst, store_temp_hyst);
545+static DEVICE_ATTR(status, S_IRUGO, show_status_reg, NULL);
546+
547+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
548+ show_power_state, store_power_state);
549+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode);
550+
551+static struct attribute *mid_att_thermal[] = {
552+ &sensor_dev_attr_temp1_min.dev_attr.attr,
553+ &sensor_dev_attr_temp1_max.dev_attr.attr,
554+ &sensor_dev_attr_temp1_crit.dev_attr.attr,
555+ &dev_attr_temp1_curr.attr,
556+ &sensor_dev_attr_temp2_min.dev_attr.attr,
557+ &sensor_dev_attr_temp2_max.dev_attr.attr,
558+ &sensor_dev_attr_temp2_crit.dev_attr.attr,
559+ &dev_attr_temp2_curr.attr,
560+ &sensor_dev_attr_temp3_min.dev_attr.attr,
561+ &sensor_dev_attr_temp3_max.dev_attr.attr,
562+ &sensor_dev_attr_temp3_crit.dev_attr.attr,
563+ &dev_attr_temp3_curr.attr,
564+ &dev_attr_hyster.attr,
565+ &dev_attr_status.attr,
566+ &dev_attr_power_state.attr,
567+ &dev_attr_mode.attr,
568+ NULL
569+};
570+
571+static struct attribute_group m_thermal_gr = {
572+ .name = "emc1403",
573+ .attrs = mid_att_thermal
574+};
575+
576+static void emc1403_set_default_config(struct i2c_client *client)
577+{
578+ i2c_smbus_write_byte_data(client, 0x03, 0x00);
579+ i2c_smbus_write_byte_data(client, 0x04, 0x02);
580+ i2c_smbus_write_byte_data(client, 0x22, 0x00);
581+}
582+
583+#ifdef MOORESTOWN_INTERRUPT_ENABLE
584+static irqreturn_t therm_interrupt_handler(int id, void *dev)
585+{
586+ struct thermal_data *data = (struct thermal_data *)dev;
587+ schedule_work(&data->therm_handler);
588+
589+ return IRQ_HANDLED;
590+}
591+
592+static irqreturn_t alert_interrupt_handler(int id, void *dev)
593+{
594+ struct thermal_data *data = (struct thermal_data *)dev;
595+ schedule_work(&data->alert_handler);
596+
597+ return IRQ_HANDLED;
598+}
599+
600+/* when the device raise the interrupt we mask the interrupt
601+ * bit for that device as the status register is R-C
602+ * so that till thermal governor doesnot take action we need
603+ * not to send continuous events */
604+
605+static int interrupt_status(struct i2c_client *client, u8 diode_reg_val,
606+ u8 *status, u8 event)
607+{
608+ u8 crit_st = 0, set_mask = 0;
609+
610+ set_mask = i2c_read_current_data(client, 0x1F);
611+ if (diode_reg_val & THM_CHAN_TEMP[3]) {
612+ set_mask = (set_mask | 0x02);
613+ crit_st = (crit_st | 2);
614+ }
615+ if (diode_reg_val & THM_CHAN_TEMP[2]) {
616+ set_mask = (set_mask | 0x04);
617+ crit_st = (crit_st | 4);
618+ }
619+ if (diode_reg_val & THM_CHAN_TEMP[4]) {
620+ set_mask = (set_mask | 0x01);
621+ crit_st = (crit_st | 1);
622+ }
623+ if (event == ALERT_EVENT)
624+ i2c_smbus_write_byte_data(client, 0x1F, set_mask);
625+ *status = crit_st;
626+ return 0;
627+}
628+
629+static void ospm_event(int event_id, int sensor_id, int curr_temp)
630+{
631+ if (event_id == THERM_EVENT) {
632+ printk(KERN_ALERT "emc1403: Sensor Id = %d crit event \
633+ temp = %d \n", sensor_id, curr_temp);
634+ ospm_generate_netlink_event(sensor_id,
635+ OSPM_EVENT_THERMAL_CRITICAL);
636+ }
637+ if (event_id == HIGH_EVENT) {
638+ printk(KERN_ALERT "emc1403: Sensor Id = %d AUX1 event \
639+ temp = %d \n", sensor_id, curr_temp);
640+ ospm_generate_netlink_event(sensor_id,
641+ OSPM_EVENT_THERMAL_AUX1);
642+ }
643+ if (event_id == LOW_EVENT) {
644+ printk(KERN_ALERT "emc1403: Sensor Id = %d AUX0 event \
645+ temp = %d \n", sensor_id, curr_temp);
646+ ospm_generate_netlink_event(sensor_id,
647+ OSPM_EVENT_THERMAL_AUX0);
648+ }
649+ if (event_id == FAULT_EVENT) {
650+ printk(KERN_ALERT "emc1403: Sensor Id = %d Fault event \
651+ temp = %d \n", sensor_id, curr_temp);
652+ ospm_generate_netlink_event(sensor_id,
653+ OSPM_EVENT_THERMAL_DEV_FAULT);
654+ }
655+}
656+
657+static void send_event(struct i2c_client *client, int status, int event_id)
658+{
659+ int ret_val;
660+
661+ if (status & TEMP1) {
662+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[0]);
663+ ospm_event(event_id, TEMP_DEV_ID1, ret_val);
664+ }
665+ if (status & TEMP2) {
666+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[1]);
667+ ospm_event(event_id, TEMP_DEV_ID2, ret_val);
668+ }
669+ if (status & TEMP3) {
670+ ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[2]);
671+ ospm_event(event_id, TEMP_DEV_ID3, ret_val);
672+ }
673+}
674+
675+static void therm_handle_intrpt(struct work_struct *work)
676+{
677+ u8 status, reg_val;
678+ struct thermal_data *data = container_of(work,
679+ struct thermal_data, therm_handler);
680+
681+ /* check if therm_module_info is initialized */
682+ if (!data)
683+ return;
684+ /* Which DIODE has raised the interrupt 0x1B
685+ internal/External1/External2 */
686+ reg_val = i2c_smbus_read_byte_data(data->client,
687+ THM_STAT_REG_TEMP[0]);
688+ interrupt_status(data->client, reg_val, &status, THERM_EVENT);
689+ send_event(data->client, status, THERM_EVENT);
690+}
691+
692+static void alert_handle_intrpt(struct work_struct *work)
693+{
694+ int sta_reg_val, reg_val;
695+ u8 status;
696+ struct thermal_data *data = container_of(work,
697+ struct thermal_data, alert_handler);
698+ if (!data)
699+ return;
700+ /* HIGH/ LOW / FAULT Alert has occured for */
701+ reg_val = i2c_smbus_read_byte_data(data->client, THM_STAT_REG_TEMP[4]);
702+ /* High status bit is set */
703+ if (reg_val & THM_CHAN_TEMP[0]) {
704+ /* Which DIODE has raised the interrupt 0x1B
705+ internal/External1/External2 */
706+ sta_reg_val = i2c_smbus_read_byte_data(data->client,
707+ THM_STAT_REG_TEMP[1]);
708+ interrupt_status(data->client, sta_reg_val, &status,
709+ ALERT_EVENT);
710+ send_event(data->client, status, HIGH_EVENT);
711+ }
712+ /* Low status bit is set */
713+ if (reg_val & THM_CHAN_TEMP[1]) {
714+ sta_reg_val = i2c_smbus_read_byte_data(data->client,
715+ THM_STAT_REG_TEMP[2]);
716+ interrupt_status(data->client, sta_reg_val, &status,
717+ ALERT_EVENT);
718+ send_event(data->client, status, LOW_EVENT);
719+ }
720+ /* Fault status bit is set */
721+ if (reg_val & THM_CHAN_TEMP[2]) {
722+ sta_reg_val = i2c_smbus_read_byte_data(data->client,
723+ THM_STAT_REG_TEMP[3]);
724+ interrupt_status(data->client, sta_reg_val, &status,
725+ ALERT_EVENT);
726+ send_event(data->client, status, FAULT_EVENT);
727+ }
728+}
729+#endif
730+
731+static int emc1403_probe(struct i2c_client *new_client,
732+ const struct i2c_device_id *id)
733+{
734+ int res = 0;
735+ struct thermal_data *data;
736+ u16 pid, smsc_id, revision;
737+
738+#ifdef MOORESTOWN_INTERRUPT_ENABLE
739+ u16 t_irq, a_irq;
740+#endif
741+ data = kzalloc(sizeof(struct thermal_data), GFP_KERNEL);
742+
743+ if (data == NULL) {
744+ printk(KERN_WARNING "emc1403: Memory allocation failed");
745+ return -ENOMEM;
746+ }
747+ data->client = new_client;
748+ i2c_set_clientdata(new_client, data);
749+
750+ /* Check if thermal chip is SMSC and EMC1403 */
751+ smsc_id = i2c_read_current_data(new_client,
752+ THERMAL_SMSC_ID_REG);
753+ if (smsc_id != 0x5d) {
754+ printk(KERN_WARNING "emc1403: vendor id mismatch \n");
755+ goto thermal_error1;
756+ }
757+ pid = i2c_read_current_data(new_client, THERMAL_PID_REG);
758+ if (pid != 0x21) {
759+ printk(KERN_WARNING "emc1403: Prod id mismatch \n");
760+ goto thermal_error1;
761+ }
762+ revision = i2c_read_current_data(new_client,
763+ THERMAL_REVISION_REG);
764+ if (revision != 0x01) {
765+ printk(KERN_WARNING "emc1403: Rev id mismatch is \n");
766+ goto thermal_error1;
767+ }
768+ res = sysfs_create_group(&new_client->dev.kobj, &m_thermal_gr);
769+ if (res) {
770+ printk(KERN_WARNING "emc1403: create group failed! \n");
771+ hwmon_device_unregister(data->hwmon_dev);
772+ goto thermal_error1;
773+ }
774+ data->hwmon_dev = hwmon_device_register(&new_client->dev);
775+ if (IS_ERR(data->hwmon_dev)) {
776+ res = PTR_ERR(data->hwmon_dev);
777+ data->hwmon_dev = NULL;
778+ printk(KERN_WARNING "emc1403:Register hwmon dev Failed\n");
779+ goto thermal_error1;
780+ }
781+#ifdef MOORESTOWN_INTERRUPT_ENABLE
782+ INIT_WORK(&data->therm_handler, (void *)therm_handle_intrpt);
783+ INIT_WORK(&data->alert_handler, (void *)alert_handle_intrpt);
784+ t_irq = new_client->irq;
785+ a_irq = *(short *)new_client->dev.platform_data;
786+ data->therm_irq = t_irq & ~IRQ_TYPE_MASK;
787+ data->alert_irq = a_irq & ~IRQ_TYPE_MASK;
788+ /* interpret irq field */
789+ if (data->therm_irq == 0x113) {
790+ if (t_irq & IRQ_TYPE_MASK) {
791+ /* irq -> GPE_ID */
792+ res = request_gpe(data->therm_irq,
793+ (gpio_function_t)therm_interrupt_handler,
794+ data, DETECT_LEVEL_LOW);
795+ if (res)
796+ dev_crit(&new_client->dev, "%s(): cannot \
797+ register therm gpe \n", __func__);
798+ } else {
799+ res = request_irq(data->therm_irq,
800+ therm_interrupt_handler,
801+ DETECT_LEVEL_LOW, "emc1403", data);
802+ if (res)
803+ dev_crit(&new_client->dev, "%s(): \
804+ cannot get therm IRQ\n", __func__);
805+ }
806+ } else {
807+ printk(KERN_WARNING"emc1403: IRQ mismatch \
808+ sent for therm registration");
809+ }
810+ if (data->alert_irq == 0x114) {
811+ if (a_irq & IRQ_TYPE_MASK) {
812+ /* irq -> GPE_ID */
813+ res = request_gpe(data->alert_irq,
814+ (gpio_function_t)alert_interrupt_handler,
815+ data, DETECT_LEVEL_LOW);
816+ if (res)
817+ dev_crit(&new_client->dev, "%s(): \
818+ cannot register alert gpe \n", __func__);
819+ } else {
820+ res = request_irq(data->alert_irq,
821+ alert_interrupt_handler, DETECT_LEVEL_LOW,
822+ "emc1403", data);
823+ if (res)
824+ dev_crit(&new_client->dev, "%s(): cannot \
825+ get alert IRQ\n", __func__);
826+ }
827+ } else {
828+ printk(KERN_WARNING"emc1403: IRQ mismatch \
829+ sent for alert registration");
830+ }
831+#endif
832+ emc1403_set_default_config(new_client);
833+ dev_info(&new_client->dev, "%s EMC1403 Thermal chip found \n",
834+ new_client->name);
835+ return res;
836+thermal_error1:
837+ i2c_set_clientdata(new_client, NULL);
838+ kfree(data);
839+ return res;
840+}
841+
842+static int emc1403_remove(struct i2c_client *client)
843+{
844+ struct thermal_data *data = i2c_get_clientdata(client);
845+
846+ hwmon_device_unregister(data->hwmon_dev);
847+ sysfs_remove_group(&client->dev.kobj, &m_thermal_gr);
848+ kfree(data);
849+ return 0;
850+}
851+
852+static struct i2c_device_id emc1403_idtable[] = {
853+ { "i2c_thermal", 0 },
854+ { }
855+};
856+
857+MODULE_DEVICE_TABLE(i2c, emc1403_idtable);
858+
859+static struct i2c_driver sensor_emc1403 = {
860+ .driver = {
861+ .name = "emc1403",
862+ },
863+ .probe = emc1403_probe,
864+ .remove = emc1403_remove,
865+ .id_table = emc1403_idtable,
866+};
867+
868+static int __init sensor_emc1403_init(void)
869+{
870+ return i2c_add_driver(&sensor_emc1403);
871+}
872+
873+static void __exit sensor_emc1403_exit(void)
874+{
875+ i2c_del_driver(&sensor_emc1403);
876+}
877+
878+module_init(sensor_emc1403_init);
879+module_exit(sensor_emc1403_exit);
880--- /dev/null
881+++ b/drivers/hwmon/hmc6352.c
882@@ -0,0 +1,250 @@
883+/*
884+ * hmc6352.c - Honeywell Compass Driver
885+ *
886+ * Copyright (C) 2009 Intel Corp
887+ *
888+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
889+ *
890+ * This program is free software; you can redistribute it and/or modify
891+ * it under the terms of the GNU General Public License as published by
892+ * the Free Software Foundation; version 2 of the License.
893+ *
894+ * This program is distributed in the hope that it will be useful, but
895+ * WITHOUT ANY WARRANTY; without even the implied warranty of
896+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
897+ * General Public License for more details.
898+ *
899+ * You should have received a copy of the GNU General Public License along
900+ * with this program; if not, write to the Free Software Foundation, Inc.,
901+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
902+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
903+ *
904+ */
905+
906+#include <linux/module.h>
907+#include <linux/init.h>
908+#include <linux/slab.h>
909+#include <linux/i2c.h>
910+#include <linux/hwmon.h>
911+#include <linux/hwmon-sysfs.h>
912+#include <linux/hwmon-vid.h>
913+#include <linux/err.h>
914+#include <linux/delay.h>
915+#include <linux/mutex.h>
916+#include <linux/sysfs.h>
917+#include <asm/ipc_defs.h>
918+
919+
920+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
921+MODULE_DESCRIPTION("hmc6352 Compass Driver");
922+MODULE_LICENSE("GPL v2");
923+
924+/* internal return values */
925+#define COMP_CALIB_START 1
926+#define COMP_CALIB_STOP 2
927+#define COMP_SLEEP_MODE 0
928+#define COMP_ACTIVE_MODE 1
929+
930+struct compass_data {
931+ struct device *hwmon_dev;
932+};
933+
934+static ssize_t compass_calibration_store(struct device *dev,
935+ struct device_attribute *attr, const char *buf, size_t count)
936+{
937+ struct i2c_client *client = to_i2c_client(dev);
938+ int ret;
939+ unsigned long val;
940+ char cmd[] = {0x43};
941+ char cmd1[] = {0x45};
942+ struct i2c_msg msg[] = {
943+ { client->addr, 0, 1, cmd },
944+ };
945+ struct i2c_msg msg1[] = {
946+ { client->addr, 0, 1, cmd1 },
947+ };
948+
949+ if (strict_strtoul(buf, 10, &val))
950+ return -EINVAL;
951+ if (val == COMP_CALIB_START) {
952+ client->addr = 0x21;
953+ ret = i2c_transfer(client->adapter, msg, 1);
954+ if (ret != 1) {
955+ printk(KERN_WARNING "hmc6352_comp : i2c callib start \
956+ cmd failed \n");
957+ return ret;
958+ }
959+ } else if (val == COMP_CALIB_STOP) {
960+ client->addr = 0x21;
961+ ret = i2c_transfer(client->adapter, msg1, 1);
962+ if (ret != 1) {
963+ printk(KERN_WARNING " hmc6352_comp : i2c callib stop \
964+ cmd failed \n");
965+ return ret;
966+ }
967+ } else
968+ return -EINVAL;
969+
970+ return count;
971+}
972+
973+static ssize_t compass_heading_data_show(struct device *dev,
974+ struct device_attribute *attr, char *buf)
975+{
976+
977+ struct i2c_client *client = to_i2c_client(dev);
978+ char cmd[] = {0x41};
979+ unsigned char i2c_data[2] = {0, 0};
980+ unsigned int ret, ret_val;
981+ struct i2c_msg msg[] = {
982+ { client->addr, 0, 1, cmd },
983+ };
984+ struct i2c_msg msg1[] = {
985+ { client->addr, I2C_M_RD, 2, i2c_data },
986+ };
987+
988+ client->addr = 0x21;
989+ ret = i2c_transfer(client->adapter, msg, 1);
990+ if (ret != 1) {
991+ printk(KERN_WARNING "hmc6352 : i2c cmd 0x41 failed \n");
992+ return ret;
993+ }
994+ msleep(10); /* sending 0x41 cmd we need to wait for 7-10 milli second*/
995+ ret = i2c_transfer(client->adapter, msg1, 1);
996+ if (ret != 1) {
997+ printk(KERN_WARNING "hmc6352 : i2c read data cmd failed \n");
998+ return ret;
999+ }
1000+ ret_val = i2c_data[0];
1001+ ret_val = ((ret_val << 8) | i2c_data[1]);
1002+ return sprintf(buf, "%d.%d\n", ret_val/10, ret_val%10);
1003+}
1004+
1005+static ssize_t compass_power_mode_store(struct device *dev,
1006+ struct device_attribute *attr, const char *buf, size_t count)
1007+{
1008+
1009+ struct i2c_client *client = to_i2c_client(dev);
1010+ unsigned long val;
1011+ unsigned int ret;
1012+ char cmd[] = {0x53};
1013+ char cmd1[] = {0x57};
1014+ struct i2c_msg msg[] = {
1015+ { client->addr, 0, 1, cmd },
1016+ };
1017+ struct i2c_msg msg1[] = {
1018+ { client->addr, 0, 1, cmd1 },
1019+ };
1020+
1021+ if (strict_strtoul(buf, 10, &val))
1022+ return -EINVAL;
1023+
1024+ if (val == COMP_SLEEP_MODE) {
1025+ ret = i2c_transfer(client->adapter, msg, 1);
1026+ if (ret != 1)
1027+ printk(KERN_WARNING "hmc6352: i2c cmd sleep mode \
1028+ failed \n");
1029+ } else if (val == COMP_ACTIVE_MODE) {
1030+ ret = i2c_transfer(client->adapter, msg1, 1);
1031+ if (ret != 1)
1032+ printk(KERN_WARNING "hmc6352: i2c cmd active mode \
1033+ failed \n");
1034+ } else
1035+ return -EINVAL;
1036+
1037+ return count;
1038+}
1039+
1040+static DEVICE_ATTR(heading, S_IRUGO, compass_heading_data_show, NULL);
1041+static DEVICE_ATTR(calibration, S_IWUSR, NULL, compass_calibration_store);
1042+static DEVICE_ATTR(power_state, S_IWUSR, NULL, compass_power_mode_store);
1043+
1044+static struct attribute *mid_att_compass[] = {
1045+ &dev_attr_heading.attr,
1046+ &dev_attr_calibration.attr,
1047+ &dev_attr_power_state.attr,
1048+ NULL
1049+};
1050+
1051+static struct attribute_group m_compass_gr = {
1052+ .name = "hmc6352",
1053+ .attrs = mid_att_compass
1054+};
1055+
1056+static int hmc6352_probe(struct i2c_client *client,
1057+ const struct i2c_device_id *id)
1058+{
1059+ int res;
1060+ struct compass_data *data;
1061+
1062+ data = kzalloc(sizeof(struct compass_data), GFP_KERNEL);
1063+ if (data == NULL) {
1064+ printk(KERN_WARNING "hmc6352: Memory initialization failed");
1065+ return -ENOMEM;
1066+ }
1067+ i2c_set_clientdata(client, data);
1068+
1069+ res = sysfs_create_group(&client->dev.kobj, &m_compass_gr);
1070+ if (res) {
1071+ printk(KERN_WARNING "hmc6352: device_create_file failed!!\n");
1072+ goto compass_error1;
1073+ }
1074+ data->hwmon_dev = hwmon_device_register(&client->dev);
1075+ if (IS_ERR(data->hwmon_dev)) {
1076+ res = PTR_ERR(data->hwmon_dev);
1077+ data->hwmon_dev = NULL;
1078+ printk(KERN_WARNING "hmc6352: fail to register hwmon device\n");
1079+ sysfs_remove_group(&client->dev.kobj, &m_compass_gr);
1080+ goto compass_error1;
1081+ }
1082+ dev_info(&client->dev, "%s HMC6352 compass chip found \n",
1083+ client->name);
1084+ return res;
1085+
1086+compass_error1:
1087+ i2c_set_clientdata(client, NULL);
1088+ kfree(data);
1089+ return res;
1090+}
1091+
1092+static int hmc6352_remove(struct i2c_client *client)
1093+{
1094+ struct compass_data *data = i2c_get_clientdata(client);
1095+
1096+ hwmon_device_unregister(data->hwmon_dev);
1097+ sysfs_remove_group(&client->dev.kobj, &m_compass_gr);
1098+ kfree(data);
1099+ return 0;
1100+}
1101+
1102+static struct i2c_device_id hmc6352_id[] = {
1103+ { "i2c_compass", 0 },
1104+ { }
1105+};
1106+
1107+MODULE_DEVICE_TABLE(i2c, hmc6352_id);
1108+
1109+static struct i2c_driver hmc6352_driver = {
1110+ .driver = {
1111+ .name = "hmc6352",
1112+ },
1113+ .probe = hmc6352_probe,
1114+ .remove = hmc6352_remove,
1115+ .id_table = hmc6352_id,
1116+};
1117+
1118+static int __init sensor_hmc6352_init(void)
1119+{
1120+ int res;
1121+
1122+ res = i2c_add_driver(&hmc6352_driver);
1123+ return res;
1124+}
1125+
1126+static void __exit sensor_hmc6352_exit(void)
1127+{
1128+ i2c_del_driver(&hmc6352_driver);
1129+}
1130+
1131+module_init(sensor_hmc6352_init);
1132+module_exit(sensor_hmc6352_exit);
1133--- /dev/null
1134+++ b/drivers/hwmon/isl29020.c
1135@@ -0,0 +1,248 @@
1136+/*
1137+ * isl29020.c - Intersil ALS Driver
1138+ *
1139+ * Copyright (C) 2008 Intel Corp
1140+ *
1141+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1142+ *
1143+ * This program is free software; you can redistribute it and/or modify
1144+ * it under the terms of the GNU General Public License as published by
1145+ * the Free Software Foundation; version 2 of the License.
1146+ *
1147+ * This program is distributed in the hope that it will be useful, but
1148+ * WITHOUT ANY WARRANTY; without even the implied warranty of
1149+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1150+ * General Public License for more details.
1151+ *
1152+ * You should have received a copy of the GNU General Public License along
1153+ * with this program; if not, write to the Free Software Foundation, Inc.,
1154+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
1155+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1156+ *
1157+ */
1158+
1159+#include <linux/module.h>
1160+#include <linux/init.h>
1161+#include <linux/slab.h>
1162+#include <linux/i2c.h>
1163+#include <linux/hwmon.h>
1164+#include <linux/hwmon-sysfs.h>
1165+#include <linux/hwmon-vid.h>
1166+#include <linux/err.h>
1167+#include <linux/delay.h>
1168+#include <linux/mutex.h>
1169+#include <linux/sysfs.h>
1170+#include <asm/ipc_defs.h>
1171+
1172+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
1173+MODULE_DESCRIPTION("intersil isl29020 ALS Driver");
1174+MODULE_LICENSE("GPL v2");
1175+
1176+#define ALS_MIN_RANGE_VAL 0
1177+#define ALS_MAX_RANGE_VAL 5
1178+#define POWER_STA_ENABLE 1
1179+#define POWER_STA_DISABLE 0
1180+
1181+struct als_data {
1182+ struct device *hwmon_dev;
1183+};
1184+
1185+static unsigned int i2c_write_current_data(struct i2c_client *client,
1186+ unsigned int reg, unsigned int value)
1187+{
1188+ int ret_val;
1189+
1190+ ret_val = i2c_smbus_write_byte_data(client, reg, value);
1191+ return ret_val;
1192+}
1193+
1194+static ssize_t als_sensing_range_show(struct device *dev,
1195+ struct device_attribute *attr, char *buf)
1196+{
1197+ struct i2c_client *client = to_i2c_client(dev);
1198+ int val;
1199+
1200+ val = i2c_smbus_read_byte_data(client, 0x00);
1201+ return sprintf(buf, "%d000\n", 1 << (2 * (val & 3)));
1202+
1203+}
1204+
1205+static ssize_t als_lux_output_data_show(struct device *dev,
1206+ struct device_attribute *attr, char *buf)
1207+{
1208+ struct i2c_client *client = to_i2c_client(dev);
1209+ unsigned int ret_val, val;
1210+ unsigned long int lux, max_count;
1211+ int tempv1, tempv2;
1212+
1213+ max_count = 65535;
1214+ tempv1 = i2c_smbus_read_byte_data(client, 0x02); /* MSB data */
1215+ tempv2 = i2c_smbus_read_byte_data(client, 0x01); /* LSB data */
1216+ ret_val = tempv1;
1217+ ret_val = (ret_val << 8 | tempv2);
1218+ val = i2c_smbus_read_byte_data(client, 0x00);
1219+ lux = ((((1 << (2 * (val & 3))))*1000) * ret_val) / max_count;
1220+ return sprintf(buf, "%ld\n", lux);
1221+}
1222+
1223+static ssize_t als_sensing_range_store(struct device *dev,
1224+ struct device_attribute *attr, const char *buf, size_t count)
1225+{
1226+ struct i2c_client *client = to_i2c_client(dev);
1227+ unsigned int ret_val, set_val = 0;
1228+ unsigned long val;
1229+
1230+ if (strict_strtoul(buf, 10, &val))
1231+ return -EINVAL;
1232+ ret_val = i2c_smbus_read_byte_data(client, 0x00);
1233+ ret_val = ret_val & 0xFC; /*reset the bit before setting them */
1234+ if (val == 1)
1235+ set_val = (ret_val | 0x00); /* setting the 1:0 bit */
1236+ else if (val == 2)
1237+ set_val = (ret_val | 0x01);
1238+ else if (val == 3)
1239+ set_val = (ret_val | 0x02);
1240+ else if (val == 4)
1241+ set_val = (ret_val | 0x03);
1242+ else
1243+ goto invarg;
1244+ i2c_write_current_data(client, 0x00, set_val);
1245+ return count;
1246+invarg:
1247+ return -EINVAL;
1248+}
1249+
1250+static ssize_t als_power_status_show(struct device *dev,
1251+ struct device_attribute *attr, char *buf)
1252+{
1253+ struct i2c_client *client = to_i2c_client(dev);
1254+ int ret_val;
1255+
1256+ ret_val = i2c_smbus_read_byte_data(client, 0x00);
1257+ ret_val = ret_val & 0x80;
1258+ if (ret_val == 0x80)
1259+ ret_val = 1;
1260+ return sprintf(buf, "%x", ret_val);
1261+}
1262+
1263+static ssize_t als_power_status_store(struct device *dev,
1264+ struct device_attribute *attr, const char *buf, size_t count)
1265+{
1266+ struct i2c_client *client = to_i2c_client(dev);
1267+ unsigned long val = 0;
1268+ char curr_val;
1269+
1270+ if (strict_strtoul(buf, 10, &val))
1271+ return -EINVAL;
1272+
1273+ curr_val = i2c_smbus_read_byte_data(client, 0x00);
1274+ if (val == POWER_STA_ENABLE)
1275+ curr_val = curr_val | 0x80;
1276+ else if (val == POWER_STA_DISABLE)
1277+ curr_val = curr_val & 0x7F;
1278+ else
1279+ return -EINVAL;
1280+ i2c_write_current_data(client, 0x00, curr_val);
1281+ return count;
1282+}
1283+
1284+static DEVICE_ATTR(sensing_range, S_IRUGO | S_IWUSR,
1285+ als_sensing_range_show, als_sensing_range_store);
1286+static DEVICE_ATTR(lux_output, S_IRUGO, als_lux_output_data_show, NULL);
1287+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
1288+ als_power_status_show, als_power_status_store);
1289+
1290+static struct attribute *mid_att_als[] = {
1291+ &dev_attr_sensing_range.attr,
1292+ &dev_attr_lux_output.attr,
1293+ &dev_attr_power_state.attr,
1294+ NULL
1295+};
1296+
1297+static struct attribute_group m_als_gr = {
1298+ .name = "isl29020",
1299+ .attrs = mid_att_als
1300+};
1301+
1302+static void als_set_default_config(struct i2c_client *client)
1303+{
1304+ i2c_write_current_data(client, 0x00, 0xc0);
1305+}
1306+
1307+static int isl29020_probe(struct i2c_client *client,
1308+ const struct i2c_device_id *id)
1309+{
1310+ int res;
1311+ struct als_data *data;
1312+
1313+ data = kzalloc(sizeof(struct als_data), GFP_KERNEL);
1314+ if (data == NULL) {
1315+ printk(KERN_WARNING " isl29020: Memory initialization failed");
1316+ return -ENOMEM;
1317+ }
1318+ i2c_set_clientdata(client, data);
1319+
1320+ res = sysfs_create_group(&client->dev.kobj, &m_als_gr);
1321+ if (res) {
1322+ printk(KERN_WARNING "isl29020: device create file failed!!\n");
1323+ goto als_error1;
1324+ }
1325+ data->hwmon_dev = hwmon_device_register(&client->dev);
1326+ if (IS_ERR(data->hwmon_dev)) {
1327+ res = PTR_ERR(data->hwmon_dev);
1328+ data->hwmon_dev = NULL;
1329+ sysfs_remove_group(&client->dev.kobj, &m_als_gr);
1330+ printk(KERN_ALERT "isl29020:unable to register hwmon device\n");
1331+ goto als_error1;
1332+ }
1333+ dev_info(&client->dev, "%s isl29020: ALS chip found \n", client->name);
1334+ als_set_default_config(client);
1335+ return res;
1336+
1337+als_error1:
1338+ i2c_set_clientdata(client, NULL);
1339+ kfree(data);
1340+ return res;
1341+}
1342+
1343+static int isl29020_remove(struct i2c_client *client)
1344+{
1345+ struct als_data *data = i2c_get_clientdata(client);
1346+
1347+ hwmon_device_unregister(data->hwmon_dev);
1348+ sysfs_remove_group(&client->dev.kobj, &m_als_gr);
1349+ kfree(data);
1350+ return 0;
1351+}
1352+
1353+static struct i2c_device_id isl29020_id[] = {
1354+ { "i2c_als", 0 },
1355+ { }
1356+};
1357+
1358+MODULE_DEVICE_TABLE(i2c, isl29020_id);
1359+
1360+static struct i2c_driver isl29020_driver = {
1361+ .driver = {
1362+ .name = "isl29020",
1363+ },
1364+ .probe = isl29020_probe,
1365+ .remove = isl29020_remove,
1366+ .id_table = isl29020_id,
1367+};
1368+
1369+static int __init sensor_isl29020_init(void)
1370+{
1371+ int res;
1372+
1373+ res = i2c_add_driver(&isl29020_driver);
1374+ return res;
1375+}
1376+
1377+static void __exit sensor_isl29020_exit(void)
1378+{
1379+ i2c_del_driver(&isl29020_driver);
1380+}
1381+
1382+module_init(sensor_isl29020_init);
1383+module_exit(sensor_isl29020_exit);
1384--- /dev/null
1385+++ b/drivers/hwmon/lis331dl.c
1386@@ -0,0 +1,322 @@
1387+/*
1388+ * lis331dl.c - ST LIS331DL Accelerometer Driver
1389+ *
1390+ * Copyright (C) 2009 Intel Corp
1391+ *
1392+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1393+ *
1394+ * This program is free software; you can redistribute it and/or modify
1395+ * it under the terms of the GNU General Public License as published by
1396+ * the Free Software Foundation; version 2 of the License.
1397+ *
1398+ * This program is distributed in the hope that it will be useful, but
1399+ * WITHOUT ANY WARRANTY; without even the implied warranty of
1400+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1401+ * General Public License for more details.
1402+ *
1403+ * You should have received a copy of the GNU General Public License along
1404+ * with this program; if not, write to the Free Software Foundation, Inc.,
1405+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
1406+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1407+ *
1408+ */
1409+
1410+#include <linux/module.h>
1411+#include <linux/init.h>
1412+#include <linux/slab.h>
1413+#include <linux/i2c.h>
1414+#include <linux/hwmon.h>
1415+#include <linux/hwmon-sysfs.h>
1416+#include <linux/hwmon-vid.h>
1417+#include <linux/err.h>
1418+#include <linux/delay.h>
1419+#include <linux/mutex.h>
1420+#include <linux/sysfs.h>
1421+
1422+
1423+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
1424+MODULE_DESCRIPTION("STMacroelectronics LIS331DL Accelerometer Driver");
1425+MODULE_LICENSE("GPL v2");
1426+
1427+#define ACCEL_DATA_RATE_100HZ 0
1428+#define ACCEL_DATA_RATE_400HZ 1
1429+#define ACCEL_POWER_MODE_DOWN 0
1430+#define ACCEL_POWER_MODE_ACTIVE 1
1431+#define ACCEL_NORMAL_MODE 0
1432+#define ACCEL_MEMORY_REBOOT 1
1433+
1434+/* internal return values */
1435+
1436+struct acclero_data {
1437+ struct device *hwmon_dev;
1438+ struct mutex update_lock;
1439+};
1440+
1441+static unsigned int i2c_write_current_data(struct i2c_client *client,
1442+ unsigned int reg, unsigned int value)
1443+{
1444+ int ret_val;
1445+
1446+ ret_val = i2c_smbus_write_byte_data(client, reg, value);
1447+ return ret_val;
1448+}
1449+
1450+static ssize_t data_rate_show(struct device *dev,
1451+ struct device_attribute *attr, char *buf)
1452+{
1453+ struct i2c_client *client = to_i2c_client(dev);
1454+ int ret_val, val;
1455+
1456+ val = i2c_smbus_read_byte_data(client, 0x20);
1457+ ret_val = (val & 0x80); /* 1= 400HZ 0= 100HZ */
1458+ if (ret_val == 0x80)
1459+ ret_val = 1;
1460+ return sprintf(buf, "%d\n", ret_val);
1461+
1462+}
1463+
1464+static ssize_t power_mode_show(struct device *dev,
1465+ struct device_attribute *attr, char *buf)
1466+{
1467+ struct i2c_client *client = to_i2c_client(dev);
1468+ int ret_val, val;
1469+
1470+ val = i2c_smbus_read_byte_data(client, 0x20);
1471+ ret_val = (val & 0x40);
1472+ if (ret_val == 0x40)
1473+ ret_val = 1;
1474+ return sprintf(buf, "%d\n", ret_val);
1475+}
1476+
1477+static ssize_t x_pos_show(struct device *dev,
1478+ struct device_attribute *attr, char *buf)
1479+{
1480+ struct i2c_client *client = to_i2c_client(dev);
1481+ int ret_val;
1482+
1483+ ret_val = i2c_smbus_read_byte_data(client, 0x29);
1484+ return sprintf(buf, "%d\n", ret_val);
1485+}
1486+
1487+static ssize_t y_pos_show(struct device *dev,
1488+ struct device_attribute *attr, char *buf)
1489+{
1490+ struct i2c_client *client = to_i2c_client(dev);
1491+ int ret_val;
1492+
1493+ ret_val = i2c_smbus_read_byte_data(client, 0x2B);
1494+ return sprintf(buf, "%d\n", ret_val);
1495+}
1496+
1497+static ssize_t z_pos_show(struct device *dev,
1498+ struct device_attribute *attr, char *buf)
1499+{
1500+ struct i2c_client *client = to_i2c_client(dev);
1501+ int ret_val;
1502+
1503+ ret_val = i2c_smbus_read_byte_data(client, 0x2D);
1504+ return sprintf(buf, "%d\n", ret_val);
1505+}
1506+
1507+static ssize_t xyz_pos_show(struct device *dev,
1508+ struct device_attribute *attr, char *buf)
1509+{
1510+ int x, y, z;
1511+ struct i2c_client *client = to_i2c_client(dev);
1512+
1513+ x = i2c_smbus_read_byte_data(client, 0x29);
1514+ y = i2c_smbus_read_byte_data(client, 0x2B);
1515+ z = i2c_smbus_read_byte_data(client, 0x2D);
1516+ return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
1517+}
1518+
1519+static ssize_t data_rate_store(struct device *dev,
1520+ struct device_attribute *attr, const char *buf, size_t count)
1521+{
1522+ struct i2c_client *client = to_i2c_client(dev);
1523+ struct acclero_data *data = i2c_get_clientdata(client);
1524+ unsigned int ret_val, set_val;
1525+ unsigned long val;
1526+
1527+ if (strict_strtoul(buf, 10, &val))
1528+ return -EINVAL;
1529+ ret_val = i2c_smbus_read_byte_data(client, 0x20);
1530+
1531+ mutex_lock(&data->update_lock);
1532+ if (val == ACCEL_DATA_RATE_100HZ)
1533+ set_val = (ret_val & 0x7F); /* setting the 8th bit to 0 */
1534+ else if (val == ACCEL_DATA_RATE_400HZ)
1535+ set_val = (ret_val | (1 << 7));
1536+ else
1537+ goto invarg;
1538+
1539+ i2c_write_current_data(client, 0x20, set_val);
1540+ mutex_unlock(&data->update_lock);
1541+ return count;
1542+invarg:
1543+ mutex_unlock(&data->update_lock);
1544+ return -EINVAL;
1545+}
1546+
1547+static ssize_t power_mode_store(struct device *dev,
1548+ struct device_attribute *attr, const char *buf, size_t count)
1549+{
1550+ struct i2c_client *client = to_i2c_client(dev);
1551+ struct acclero_data *data = i2c_get_clientdata(client);
1552+ unsigned int ret_val, set_val;
1553+ unsigned long val;
1554+
1555+ if (strict_strtoul(buf, 10, &val))
1556+ return -EINVAL;
1557+ ret_val = i2c_smbus_read_byte_data(client, 0x20);
1558+
1559+ mutex_lock(&data->update_lock);
1560+ if (val == ACCEL_POWER_MODE_DOWN)
1561+ set_val = ret_val & 0xBF; /* if value id 0 */
1562+ else if (val == ACCEL_POWER_MODE_ACTIVE)
1563+ set_val = (ret_val | (1<<6)); /* if value is 1 */
1564+ else
1565+ goto invarg;
1566+
1567+ i2c_write_current_data(client, 0x20, set_val);
1568+ mutex_unlock(&data->update_lock);
1569+ return count;
1570+invarg:
1571+ mutex_unlock(&data->update_lock);
1572+ return -EINVAL;
1573+}
1574+
1575+static ssize_t reboot_mem_store(struct device *dev,
1576+ struct device_attribute *attr, const char *buf, size_t count)
1577+{
1578+ struct i2c_client *client = to_i2c_client(dev);
1579+ struct acclero_data *data = i2c_get_clientdata(client);
1580+ unsigned int ret_val, set_val;
1581+ unsigned long val;
1582+
1583+ if (strict_strtoul(buf, 10, &val))
1584+ return -EINVAL;
1585+ ret_val = i2c_smbus_read_byte_data(client, 0x21);
1586+ if (val == ACCEL_MEMORY_REBOOT) {
1587+ mutex_lock(&data->update_lock);
1588+ set_val = (ret_val | (1 << 6)); /* setting the 6th bit */
1589+ i2c_write_current_data(client, 0x21, set_val);
1590+ mutex_unlock(&data->update_lock);
1591+ } else
1592+ return -EINVAL;
1593+ return count;
1594+}
1595+
1596+static DEVICE_ATTR(data_rate, S_IRUGO | S_IWUSR,
1597+ data_rate_show, data_rate_store);
1598+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
1599+ power_mode_show, power_mode_store);
1600+static DEVICE_ATTR(reboot_mem, S_IWUSR, NULL,
1601+ reboot_mem_store);
1602+static DEVICE_ATTR(x, S_IRUGO, x_pos_show, NULL);
1603+static DEVICE_ATTR(y, S_IRUGO, y_pos_show, NULL);
1604+static DEVICE_ATTR(z, S_IRUGO, z_pos_show, NULL);
1605+static DEVICE_ATTR(curr_pos, S_IRUGO, xyz_pos_show, NULL);
1606+
1607+static struct attribute *mid_att_acclero[] = {
1608+ &dev_attr_data_rate.attr,
1609+ &dev_attr_power_state.attr,
1610+ &dev_attr_reboot_mem.attr,
1611+ &dev_attr_x.attr,
1612+ &dev_attr_y.attr,
1613+ &dev_attr_z.attr,
1614+ &dev_attr_curr_pos.attr,
1615+ NULL
1616+};
1617+
1618+static struct attribute_group m_acclero_gr = {
1619+ .name = "lis331dl",
1620+ .attrs = mid_att_acclero
1621+};
1622+
1623+static void accel_set_default_config(struct i2c_client *client)
1624+{
1625+ i2c_write_current_data(client, 0x20, 0x47);
1626+}
1627+
1628+static int lis331dl_probe(struct i2c_client *client,
1629+ const struct i2c_device_id *id)
1630+{
1631+ int res;
1632+ struct acclero_data *data;
1633+
1634+ data = kzalloc(sizeof(struct acclero_data), GFP_KERNEL);
1635+ if (data == NULL) {
1636+ printk(KERN_WARNING "lis331dl: Memory initi failed \n");
1637+ return -ENOMEM;
1638+ }
1639+ mutex_init(&data->update_lock);
1640+ i2c_set_clientdata(client, data);
1641+
1642+ res = sysfs_create_group(&client->dev.kobj, &m_acclero_gr);
1643+ if (res) {
1644+ printk(KERN_WARNING "lis331dl: Sysfs group failed!!\n");
1645+ goto acclero_error1;
1646+ }
1647+ data->hwmon_dev = hwmon_device_register(&client->dev);
1648+ if (IS_ERR(data->hwmon_dev)) {
1649+ res = PTR_ERR(data->hwmon_dev);
1650+ data->hwmon_dev = NULL;
1651+ sysfs_remove_group(&client->dev.kobj, &m_acclero_gr);
1652+ printk(KERN_WARNING "lis331dl: unable to register \
1653+ hwmon device\n");
1654+ goto acclero_error1;
1655+ }
1656+ accel_set_default_config(client);
1657+
1658+ dev_info(&client->dev, "%s lis331dl: Accelerometer chip \
1659+ foundn", client->name);
1660+ return res;
1661+
1662+acclero_error1:
1663+ i2c_set_clientdata(client, NULL);
1664+ kfree(data);
1665+ return res;
1666+}
1667+
1668+static int lis331dl_remove(struct i2c_client *client)
1669+{
1670+ struct acclero_data *data = i2c_get_clientdata(client);
1671+
1672+ hwmon_device_unregister(data->hwmon_dev);
1673+ sysfs_remove_group(&client->dev.kobj, &m_acclero_gr);
1674+ kfree(data);
1675+ return 0;
1676+}
1677+
1678+static struct i2c_device_id lis331dl_id[] = {
1679+ { "i2c_accel", 0 },
1680+ { }
1681+};
1682+
1683+MODULE_DEVICE_TABLE(i2c, lis331dl_id);
1684+
1685+static struct i2c_driver lis331dl_driver = {
1686+ .driver = {
1687+ .name = "lis331dl",
1688+ },
1689+ .probe = lis331dl_probe,
1690+ .remove = lis331dl_remove,
1691+ .id_table = lis331dl_id,
1692+};
1693+
1694+static int __init sensor_lis331dl_init(void)
1695+{
1696+ int res;
1697+
1698+ res = i2c_add_driver(&lis331dl_driver);
1699+ return res;
1700+}
1701+
1702+static void __exit sensor_lis331dl_exit(void)
1703+{
1704+ i2c_del_driver(&lis331dl_driver);
1705+}
1706+
1707+module_init(sensor_lis331dl_init);
1708+module_exit(sensor_lis331dl_exit);
1709--- a/drivers/misc/Kconfig
1710+++ b/drivers/misc/Kconfig
1711@@ -249,6 +249,13 @@ config SGI_GRU_DEBUG
1712 This option enables addition debugging code for the SGI GRU driver. If
1713 you are unsure, say N.
1714
1715+config MRST_VIB
1716+ tristate "vibrator driver for Intel Moorestown platform"
1717+ help
1718+ Vibrator for Intel Moorestown platform.
1719+
1720+ If unsure, say N.
1721+
1722 config ISL29003
1723 tristate "Intersil ISL29003 ambient light sensor"
1724 depends on I2C && SYSFS
1725--- a/drivers/misc/Makefile
1726+++ b/drivers/misc/Makefile
1727@@ -22,6 +22,7 @@ obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfg
1728 obj-$(CONFIG_HP_ILO) += hpilo.o
1729 obj-$(CONFIG_MRST) += intel_mrst.o
1730 obj-$(CONFIG_ISL29003) += isl29003.o
1731+obj-$(CONFIG_MRST_VIB) += mrst_vib.o
1732 obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
1733 obj-$(CONFIG_DS1682) += ds1682.o
1734 obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
1735--- /dev/null
1736+++ b/drivers/misc/mrst_vib.c
1737@@ -0,0 +1,99 @@
1738+/*
1739+ * mrst_vib.c - Intel vibrator Driver
1740+ *
1741+ * Copyright (C) 2008 Intel Corp
1742+ *
1743+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1744+ *
1745+ * This program is free software; you can redistribute it and/or modify
1746+ * it under the terms of the GNU General Public License as published by
1747+ * the Free Software Foundation; version 2 of the License.
1748+ *
1749+ * This program is distributed in the hope that it will be useful, but
1750+ * WITHOUT ANY WARRANTY; without even the implied warranty of
1751+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1752+ * General Public License for more details.
1753+ *
1754+ * You should have received a copy of the GNU General Public License along
1755+ * with this program; if not, write to the Free Software Foundation, Inc.,
1756+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
1757+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1758+ *
1759+ */
1760+
1761+#include <linux/platform_device.h>
1762+#include <linux/kernel.h>
1763+#include <linux/sysfs.h>
1764+#include <asm/ipc_defs.h>
1765+
1766+
1767+MODULE_AUTHOR("Kalhan Trisal");
1768+MODULE_DESCRIPTION("Intel Moorestown Thermal Driver");
1769+MODULE_LICENSE("GPL v2");
1770+
1771+#define VIB_START 1
1772+#define VIB_STOP 2
1773+static struct platform_device *vib_pdev;
1774+
1775+static ssize_t vib_store(struct device *dev, struct device_attribute *attr,
1776+ const char *buf, size_t count)
1777+{
1778+
1779+ struct ipc_pmic_reg_data vib_power_reg_write = {0};
1780+ unsigned long val;
1781+
1782+ if (strict_strtoul(buf, 10, &val))
1783+ return -EINVAL;
1784+ if (val == VIB_START) {
1785+ vib_power_reg_write.ioc = TRUE;
1786+ vib_power_reg_write.pmic_reg_data[0].register_address = 0x49;
1787+ vib_power_reg_write.pmic_reg_data[0].value = 0xAD;
1788+ vib_power_reg_write.num_entries = 1;
1789+ if (ipc_pmic_register_write(&vib_power_reg_write, TRUE)) {
1790+ printk(KERN_WARNING "mrst_vib: failed to turn ON \
1791+ vib \n");
1792+ return -EINVAL;
1793+ }
1794+ } else if (val == VIB_STOP) {
1795+ vib_power_reg_write.ioc = TRUE;
1796+ vib_power_reg_write.pmic_reg_data[0].register_address = 0x49;
1797+ vib_power_reg_write.pmic_reg_data[0].value = 0x14;
1798+ vib_power_reg_write.num_entries = 1;
1799+ if (ipc_pmic_register_write(&vib_power_reg_write, TRUE)) {
1800+ printk(KERN_WARNING "mrst_vib: failed to turn OFF \
1801+ Vibrator \n");
1802+ return -EINVAL;
1803+ }
1804+ } else
1805+ return -EINVAL;
1806+
1807+ return count;
1808+}
1809+
1810+static struct device_attribute dev_attr_vib =
1811+ __ATTR(vib, S_IWUSR, NULL, vib_store);
1812+
1813+static int __init mrst_vib_init(void)
1814+{
1815+ int res = 0;
1816+
1817+ vib_pdev = platform_device_register_simple("mrst_vib", -1, NULL, 0);
1818+ if (IS_ERR(vib_pdev)) {
1819+ res = PTR_ERR(vib_pdev);
1820+ vib_pdev = NULL;
1821+ printk(KERN_WARNING "mrst_vib: unable to register platform \
1822+ device\n");
1823+ return res;
1824+ }
1825+ res = device_create_file(&vib_pdev->dev, &dev_attr_vib);
1826+ return res;
1827+}
1828+
1829+static void __exit mrst_vib_exit(void)
1830+{
1831+ device_remove_file(&vib_pdev->dev, &dev_attr_vib);
1832+ platform_device_unregister(vib_pdev);
1833+}
1834+
1835+module_init(mrst_vib_init);
1836+module_exit(mrst_vib_exit);