1 Index: linux-2.6.33/drivers/hwmon/Kconfig
2 ===================================================================
3 --- linux-2.6.33.orig/drivers/hwmon/Kconfig
4 +++ linux-2.6.33/drivers/hwmon/Kconfig
5 @@ -63,6 +63,13 @@ config SENSORS_EMC1403
6 Threshold values can be configured using sysfs.
7 Data from the different diode are accessible via sysfs.
9 +config SENSORS_MRST_ANALOG_ACCEL
10 + tristate "Moorestown Analog Accelerometer"
13 + If you say yes here you get support for the Analog Accelerometer Devices
14 + x y Z data can be accessed via sysfs.
16 config HWMON_DEBUG_CHIP
17 bool "Hardware Monitoring Chip debugging messages"
19 Index: linux-2.6.33/drivers/hwmon/Makefile
20 ===================================================================
21 --- linux-2.6.33.orig/drivers/hwmon/Makefile
22 +++ linux-2.6.33/drivers/hwmon/Makefile
23 @@ -103,6 +103,7 @@ obj-$(CONFIG_SENSORS_ISL29020) += isl290
24 obj-$(CONFIG_SENSORS_HMC6352) += hmc6352.o
25 obj-$(CONFIG_SENSORS_LIS331DL) += lis331dl.o
26 obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
27 +obj-$(CONFIG_SENSORS_MRST_ANALOG_ACCEL) += mrst_analog_accel.o
29 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
30 EXTRA_CFLAGS += -DDEBUG
31 Index: linux-2.6.33/drivers/hwmon/mrst_analog_accel.c
32 ===================================================================
34 +++ linux-2.6.33/drivers/hwmon/mrst_analog_accel.c
37 + * mrst_analog_accel.c - Intel analog accelerometer driver for Moorestown
39 + * Copyright (C) 2009 Intel Corp
41 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
43 + * This program is free software; you can redistribute it and/or modify
44 + * it under the terms of the GNU General Public License as published by
45 + * the Free Software Foundation; version 2 of the License.
47 + * This program is distributed in the hope that it will be useful, but
48 + * WITHOUT ANY WARRANTY; without even the implied warranty of
49 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
50 + * General Public License for more details.
52 + * You should have received a copy of the GNU General Public License along
53 + * with this program; if not, write to the Free Software Foundation, Inc.,
54 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
55 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59 +#include <linux/module.h>
60 +#include <linux/platform_device.h>
61 +#include <linux/init.h>
62 +#include <linux/slab.h>
63 +#include <linux/i2c.h>
64 +#include <linux/hwmon.h>
65 +#include <linux/hwmon-sysfs.h>
66 +#include <linux/hwmon-vid.h>
67 +#include <linux/err.h>
68 +#include <linux/delay.h>
69 +#include <asm/ipc_defs.h>
71 +MODULE_AUTHOR("Ramesh Agarwal");
72 +MODULE_DESCRIPTION("Intel Moorestown Analog Accelerometer Driver");
73 +MODULE_LICENSE("GPL v2");
75 +/* PMIC ADC INTERRUPT REGISTERS */
76 +#define PMIC_ADC_ACC_REG_ADCINT 0x5F /*ADC interrupt register */
77 +#define PMIC_ADC_ACC_REG_MADCINT 0x60 /*ADC interrupt mask register */
79 +/* PMIC ADC CONTROL REGISTERS */
80 +#define PMIC_ADC_ACC_REG_ADCCNTL1 0x61 /*ADC control register */
81 +#define PMIC_ADC_ACC_REG_ADCCNTL2 0x62 /*ADC gain regs channel 10-17 */
82 +#define PMIC_ADC_ACC_REG_ADCCNTL3 0x63 /*ADC gain regs channel 18-21 */
84 +/* PMIC Data Register base */
85 +#define PMIC_ADC_DATA_REG_BASE 0x64
87 +/* PMIC Channel Mapping Register base */
88 +#define PMIC_ADC_MAPPING_BASE 0xA4
90 +/* Number of PMIC sample registers */
91 +#define PMIC_ADC_REG_MAX 32 /* Max no of available channel */
93 +#define PMIC_ADC_X_REG_HIGH(index) (PMIC_ADC_DATA_REG_BASE \
95 +#define PMIC_ADC_X_REG_LOW(index) (PMIC_ADC_DATA_REG_BASE \
97 +#define PMIC_ADC_Y_REG_HIGH(index) (PMIC_ADC_DATA_REG_BASE \
99 +#define PMIC_ADC_Y_REG_LOW(index) (PMIC_ADC_DATA_REG_BASE \
101 +#define PMIC_ADC_Z_REG_HIGH(index) (PMIC_ADC_DATA_REG_BASE \
103 +#define PMIC_ADC_Z_REG_LOW(index) (PMIC_ADC_DATA_REG_BASE \
106 +/* Number of registers to read at a time */
107 +#define REG_READ_PER_IPC 4 /* Read 4 at a time although the */
108 + /* IPC will support max 5 */
110 +#define END_OF_CHANNEL_VALUE 0x1F /* Used to indicate the last */
111 + /* channel being used */
113 +/* PMIC ADC channels for Accelero Meter */
114 +#define PMIC_ADC_ACC_ADC_ACC_CH14 0xE
115 +#define PMIC_ADC_ACC_ADC_ACC_CH15 0xF
116 +#define PMIC_ADC_ACC_ADC_ACC_CH16 0x10
118 +static unsigned int mrst_analog_reg_idx;
120 +/* Use IPC to read the value of the register and display
124 +mrst_analog_accel_x_axis_data_show(struct device *dev,
125 + struct device_attribute *attr, char *buf)
127 + unsigned int ret_val;
128 + struct ipc_pmic_reg_data ipc_data;
130 + ipc_data.ioc = FALSE; /* No need to generate MSI */
131 + ipc_data.num_entries = 2;
132 + ipc_data.pmic_reg_data[0].register_address =
133 + PMIC_ADC_X_REG_HIGH(mrst_analog_reg_idx); /* X Higher 8 bits */
134 + ipc_data.pmic_reg_data[1].register_address =
135 + PMIC_ADC_X_REG_LOW(mrst_analog_reg_idx); /* X lower 3 bits */
136 + if (ipc_pmic_register_read(&ipc_data) != 0) {
138 + "\nmrst_analog_accel:PMIC reg read using IPC failed\n");
141 + ret_val = ipc_data.pmic_reg_data[0].value << 3; /* X higher 8 bits */
143 + ret_val = ret_val | (ipc_data.pmic_reg_data[1].value & 0x07);
144 + return sprintf(buf, "%d\n", ret_val);
147 +/* Use IPC to read the value of the register and display
150 +mrst_analog_accel_y_axis_data_show(struct device *dev,
151 + struct device_attribute *attr, char *buf)
153 + unsigned int ret_val;
154 + struct ipc_pmic_reg_data ipc_data;
156 + ipc_data.ioc = FALSE; /* No need to generate MSI */
157 + ipc_data.num_entries = 2;
158 + ipc_data.pmic_reg_data[0].register_address =
159 + PMIC_ADC_Y_REG_HIGH(mrst_analog_reg_idx); /* Y higher 8 bits */
160 + ipc_data.pmic_reg_data[1].register_address =
161 + PMIC_ADC_Y_REG_LOW(mrst_analog_reg_idx); /* Y lower 3 bits */
162 + if (ipc_pmic_register_read(&ipc_data) != 0) {
164 + "\nmrst_analog_accel:PMIC reg read using IPC failed\n");
167 + ret_val = ipc_data.pmic_reg_data[0].value << 3; /* Y higher 8 bits */
168 + /* Y lower 3 bits */
169 + ret_val = ret_val | (ipc_data.pmic_reg_data[1].value & 0x07);
170 + return sprintf(buf, "%d\n", ret_val);
173 +/* Use IPC to read the value of the register and display
176 +mrst_analog_accel_z_axis_data_show(struct device *dev,
177 + struct device_attribute *attr, char *buf)
179 + unsigned int ret_val;
180 + struct ipc_pmic_reg_data ipc_data;
182 + ipc_data.ioc = FALSE; /* No need to generate MSI */
183 + ipc_data.num_entries = 2;
184 + ipc_data.pmic_reg_data[0].register_address =
185 + PMIC_ADC_Z_REG_HIGH(mrst_analog_reg_idx);
186 + ipc_data.pmic_reg_data[1].register_address =
187 + PMIC_ADC_Z_REG_LOW(mrst_analog_reg_idx); /* Z lower 3 bits */
188 + if (ipc_pmic_register_read(&ipc_data) != 0) {
190 + "\nmrst_analog_accel:PMIC reg read using IPC failed\n");
193 + ret_val = ipc_data.pmic_reg_data[0].value << 3; /* Z higher 8 bits */
194 + /* Z lower 3 bits */
195 + ret_val = ret_val | (ipc_data.pmic_reg_data[1].value & 0x07);
196 + return sprintf(buf, "%d\n", ret_val);
200 +static DEVICE_ATTR(acc_x_axis, S_IRUGO,
201 + mrst_analog_accel_x_axis_data_show, NULL);
202 +static DEVICE_ATTR(acc_y_axis, S_IRUGO,
203 + mrst_analog_accel_y_axis_data_show, NULL);
204 +static DEVICE_ATTR(acc_z_axis, S_IRUGO,
205 + mrst_analog_accel_z_axis_data_show, NULL);
207 +static struct attribute *mid_att_acc[] = {
208 + &dev_attr_acc_x_axis.attr,
209 + &dev_attr_acc_y_axis.attr,
210 + &dev_attr_acc_z_axis.attr,
214 +static struct attribute_group m_analog_gr = {
215 + .name = "mrst_analog_accel",
216 + .attrs = mid_att_acc
220 +mrst_analog_accel_initialize(void)
222 + struct ipc_pmic_mod_reg_data ipc_mod_data;
223 + struct ipc_pmic_reg_data ipc_data;
225 + u8 mad_cntrl = 0; /* MADCINT register value */
226 + u8 adc_cntrl2 = 0; /* ADCCNTL2 register value */
229 + /* Initialize the register index to use to be zero */
230 + mrst_analog_reg_idx = 0;
232 + /* check if the ADC is enabled or not
233 + * Read ADCCNTL1 registers */
234 + ipc_data.ioc = FALSE; /* No need to generate MSI */
235 + ipc_data.num_entries = 1;
236 + ipc_data.pmic_reg_data[0].register_address =
237 + PMIC_ADC_ACC_REG_ADCCNTL1;
238 + ipc_data.pmic_reg_data[0].value = 0;
240 + retval = ipc_pmic_register_read(&ipc_data);
243 + "\nmrst_analog_accel:PMIC register read failed\n");
247 + adc_cntrl2 = ipc_data.pmic_reg_data[0].value;
249 + if ((adc_cntrl2 >> 7) & 0x1) {
250 + /* If the ADC is enabled find the set of registers to use
251 + ** Loop through the channel mapping register to find out the
255 + (i < PMIC_ADC_REG_MAX) && (mrst_analog_reg_idx == 0);
256 + i += REG_READ_PER_IPC) {
258 + ipc_data.num_entries = REG_READ_PER_IPC;
259 + ipc_data.ioc = FALSE; /* No need to generate MSI */
261 + /* Reading 4 regs at a time instead of reading each
262 + * reg one by one since IPC is an expensive operation
264 + for (j = 0; j < REG_READ_PER_IPC; j++) {
265 + ipc_data.pmic_reg_data[j].register_address =
266 + PMIC_ADC_MAPPING_BASE + i + j;
267 + ipc_data.pmic_reg_data[j].value = 0;
269 + retval = ipc_pmic_register_read(&ipc_data);
272 + "\nmrst_analog_accel:PMIC regs read failed\n");
275 + for (j = 0; j < REG_READ_PER_IPC; j++) {
276 + if (ipc_data.pmic_reg_data[j].value
277 + == END_OF_CHANNEL_VALUE) {
278 + mrst_analog_reg_idx = i + j;
284 + /* Check to see if there are enough registers to map the channel */
285 + if ((mrst_analog_reg_idx + 3) >= PMIC_ADC_REG_MAX) {
287 + "\nmrst_analog_accel:Not enough regs to map the channels\n");
291 + /* Update the mapping registers for the accelerometer*/
292 + ipc_data.num_entries = 4;
293 + ipc_data.ioc = FALSE; /* No need to generate MSI */
294 + ipc_data.pmic_reg_data[0].register_address =
295 + PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx;
296 + ipc_data.pmic_reg_data[0].value = PMIC_ADC_ACC_ADC_ACC_CH14;
298 + ipc_data.pmic_reg_data[1].register_address =
299 + PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx + 1;
300 + ipc_data.pmic_reg_data[1].value = PMIC_ADC_ACC_ADC_ACC_CH15;
302 + ipc_data.pmic_reg_data[2].register_address =
303 + PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx + 2;
304 + ipc_data.pmic_reg_data[2].value = PMIC_ADC_ACC_ADC_ACC_CH16;
306 + ipc_data.pmic_reg_data[3].register_address =
307 + PMIC_ADC_MAPPING_BASE + mrst_analog_reg_idx + 3 ;
308 + ipc_data.pmic_reg_data[3].value = END_OF_CHANNEL_VALUE;
310 + retval = ipc_pmic_register_write(&ipc_data, FALSE);
313 + "\nmrst_analog_accel:PMIC reg write failed\n");
317 + /* If the ADC was not enabled, enable it now */
318 + if (!(adc_cntrl2 >> 7) & 0x1) {
319 + /* Mask the round robin completion interrupt */
320 + ipc_mod_data.ioc = FALSE; /* No need to generate MSI */
321 + ipc_mod_data.num_entries = 1;
323 + ipc_mod_data.pmic_mod_reg_data[0].register_address =
324 + PMIC_ADC_ACC_REG_MADCINT;
325 + ipc_mod_data.pmic_mod_reg_data[0].value = mad_cntrl;
326 + ipc_mod_data.pmic_mod_reg_data[0].bit_map = 0x01;
328 + retval = ipc_pmic_register_read_modify(&ipc_mod_data);
331 + "\nmrst_analog_accel:PMIC reg modify failed\n");
335 + adc_cntrl2 = 0xc6; /*27ms delay,start round robin,
336 + enable full power */
337 + ipc_data.ioc = FALSE; /* No need to generate MSI */
338 + ipc_data.num_entries = 1;
339 + ipc_data.pmic_reg_data[0].register_address =
340 + PMIC_ADC_ACC_REG_ADCCNTL1;
341 + ipc_data.pmic_reg_data[0].value = adc_cntrl2;
342 + retval = ipc_pmic_register_write(&ipc_data, FALSE);
349 +static struct platform_device *mrst_analog_accel_pdev;
350 +static struct device *mrst_analog_accel_hwmon;
353 +mrst_analog_accel_unregister(void)
356 + printk(KERN_ALERT "\nStart Exit\n\n");
357 + sysfs_remove_group(&mrst_analog_accel_hwmon->kobj, &m_analog_gr);
358 + hwmon_device_unregister(mrst_analog_accel_hwmon);
359 + platform_device_unregister(mrst_analog_accel_pdev);
360 + printk(KERN_ALERT "\n\nEnd Exit\n");
366 +mrst_analog_accel_module_init(void)
370 + mrst_analog_accel_pdev =
371 + platform_device_register_simple("mrst_analog_accel",
373 + if (IS_ERR(mrst_analog_accel_pdev)) {
374 + retval = PTR_ERR(mrst_analog_accel_pdev);
376 + "\nmrst_analog_accel:Registration with the platform failed\n");
377 + goto accelero_reg_failed;
380 + "\nmrst_analog_accel:Registered with the platform\n");
382 + retval = mrst_analog_accel_initialize();
384 + retval = sysfs_create_group(&mrst_analog_accel_pdev->dev.kobj,
388 + "\nmrst_analog_accel:device_create_file 1 failed\n");
389 + goto accelero_reg_failed;
391 + mrst_analog_accel_hwmon =
392 + hwmon_device_register(&mrst_analog_accel_pdev->dev);
393 + if (IS_ERR(mrst_analog_accel_hwmon)) {
394 + retval = PTR_ERR(mrst_analog_accel_hwmon);
395 + mrst_analog_accel_hwmon = NULL;
397 + "\nmrst_analog_accel:Registration with hwmon failed\n");
401 + "\nmrst_analog_accel:Initialization failed: %d\n", retval);
404 +accelero_reg_failed:
409 +mrst_analog_accel_module_exit(void)
412 + mrst_analog_accel_unregister();
415 +module_init(mrst_analog_accel_module_init);
416 +module_exit(mrst_analog_accel_module_exit);
417 Index: linux-2.6.33/drivers/hwmon/lis331dl.c
418 ===================================================================
419 --- linux-2.6.33.orig/drivers/hwmon/lis331dl.c
420 +++ linux-2.6.33/drivers/hwmon/lis331dl.c
421 @@ -186,33 +186,10 @@ invarg:
425 -static ssize_t reboot_mem_store(struct device *dev,
426 - struct device_attribute *attr, const char *buf, size_t count)
428 - struct i2c_client *client = to_i2c_client(dev);
429 - struct acclero_data *data = i2c_get_clientdata(client);
430 - unsigned int ret_val, set_val;
433 - if (strict_strtoul(buf, 10, &val))
435 - ret_val = i2c_smbus_read_byte_data(client, 0x21);
436 - if (val == ACCEL_MEMORY_REBOOT) {
437 - mutex_lock(&data->update_lock);
438 - set_val = (ret_val | (1 << 6)); /* setting the 6th bit */
439 - i2c_write_current_data(client, 0x21, set_val);
440 - mutex_unlock(&data->update_lock);
446 static DEVICE_ATTR(data_rate, S_IRUGO | S_IWUSR,
447 data_rate_show, data_rate_store);
448 static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
449 power_mode_show, power_mode_store);
450 -static DEVICE_ATTR(reboot_mem, S_IWUSR, NULL,
452 static DEVICE_ATTR(x, S_IRUGO, x_pos_show, NULL);
453 static DEVICE_ATTR(y, S_IRUGO, y_pos_show, NULL);
454 static DEVICE_ATTR(z, S_IRUGO, z_pos_show, NULL);
455 @@ -221,7 +198,6 @@ static DEVICE_ATTR(curr_pos, S_IRUGO, xy
456 static struct attribute *mid_att_acclero[] = {
457 &dev_attr_data_rate.attr,
458 &dev_attr_power_state.attr,
459 - &dev_attr_reboot_mem.attr,