]> code.ossystems Code Review - openembedded-core.git/blob
c8264db6936edd180603ed8414d9d40da1c458f8
[openembedded-core.git] /
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.
8  
9 +config SENSORS_MRST_ANALOG_ACCEL
10 +       tristate "Moorestown Analog Accelerometer"
11 +       depends on LNW_IPC
12 +       help
13 +         If you say yes here you get support for the Analog Accelerometer  Devices
14 +         x y Z data can be accessed via sysfs.
15 +
16  config HWMON_DEBUG_CHIP
17         bool "Hardware Monitoring Chip debugging messages"
18         default n
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
28  
29  ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
30  EXTRA_CFLAGS += -DDEBUG
31 Index: linux-2.6.33/drivers/hwmon/mrst_analog_accel.c
32 ===================================================================
33 --- /dev/null
34 +++ linux-2.6.33/drivers/hwmon/mrst_analog_accel.c
35 @@ -0,0 +1,381 @@
36 +/*
37 + * mrst_analog_accel.c - Intel analog accelerometer driver for Moorestown
38 + *
39 + * Copyright (C) 2009 Intel Corp
40 + *
41 + *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42 + *
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.
46 + *
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.
51 + *
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 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56 + *
57 + */
58 +
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>
70 +
71 +MODULE_AUTHOR("Ramesh Agarwal");
72 +MODULE_DESCRIPTION("Intel Moorestown Analog Accelerometer Driver");
73 +MODULE_LICENSE("GPL v2");
74 +
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 */
78 +
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 */
83 +
84 +/* PMIC Data Register base */
85 +#define PMIC_ADC_DATA_REG_BASE         0x64
86 +
87 +/* PMIC Channel Mapping Register base */
88 +#define PMIC_ADC_MAPPING_BASE          0xA4
89 +
90 +/* Number of PMIC sample registers */
91 +#define PMIC_ADC_REG_MAX       32      /* Max no of available channel */
92 +
93 +#define PMIC_ADC_X_REG_HIGH(index)     (PMIC_ADC_DATA_REG_BASE \
94 +                                               + (index * 2))
95 +#define PMIC_ADC_X_REG_LOW(index)      (PMIC_ADC_DATA_REG_BASE \
96 +                                               + (index * 2) + 1)
97 +#define PMIC_ADC_Y_REG_HIGH(index)     (PMIC_ADC_DATA_REG_BASE \
98 +                                               + (index * 2) + 2)
99 +#define PMIC_ADC_Y_REG_LOW(index)      (PMIC_ADC_DATA_REG_BASE \
100 +                                               + (index * 2) + 3)
101 +#define PMIC_ADC_Z_REG_HIGH(index)     (PMIC_ADC_DATA_REG_BASE \
102 +                                               + (index * 2) + 4)
103 +#define PMIC_ADC_Z_REG_LOW(index)      (PMIC_ADC_DATA_REG_BASE \
104 +                                               + (index * 2) + 5)
105 +
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 */
109 +
110 +#define END_OF_CHANNEL_VALUE   0x1F    /* Used to indicate the last */
111 +                                       /* channel being used */
112 +
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
117 +
118 +static unsigned int mrst_analog_reg_idx;
119 +
120 +/* Use IPC to read the value of the register and display
121 + * X value
122 + */
123 +static ssize_t
124 +mrst_analog_accel_x_axis_data_show(struct device *dev,
125 +                         struct device_attribute *attr, char *buf)
126 +{
127 +       unsigned int ret_val;
128 +       struct ipc_pmic_reg_data ipc_data;
129 +
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) {
137 +               printk(KERN_ALERT
138 +                       "\nmrst_analog_accel:PMIC reg read using IPC failed\n");
139 +               return -1;
140 +       }
141 +       ret_val = ipc_data.pmic_reg_data[0].value << 3; /* X higher 8 bits */
142 +       /* lower 3 bits */
143 +       ret_val = ret_val | (ipc_data.pmic_reg_data[1].value & 0x07);
144 +       return sprintf(buf, "%d\n", ret_val);
145 +}
146 +
147 +/* Use IPC to read the value of the register and display
148 + * Y value */
149 +static ssize_t
150 +mrst_analog_accel_y_axis_data_show(struct device *dev,
151 +                         struct device_attribute *attr, char *buf)
152 +{
153 +       unsigned int ret_val;
154 +       struct ipc_pmic_reg_data ipc_data;
155 +
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) {
163 +               printk(KERN_ALERT
164 +               "\nmrst_analog_accel:PMIC reg read using IPC failed\n");
165 +               return -1;
166 +       }
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);
171 +}
172 +
173 +/* Use IPC to read the value of the register and display
174 + * Z value */
175 +static ssize_t
176 +mrst_analog_accel_z_axis_data_show(struct device *dev,
177 +                         struct device_attribute *attr, char *buf)
178 +{
179 +       unsigned int ret_val;
180 +       struct ipc_pmic_reg_data ipc_data;
181 +
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) {
189 +               printk(KERN_ALERT
190 +               "\nmrst_analog_accel:PMIC reg read using IPC failed\n");
191 +               return -1;
192 +       }
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);
197 +}
198 +
199 +
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);
206 +
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,
211 +       NULL
212 +};
213 +
214 +static struct attribute_group m_analog_gr = {
215 +       .name = "mrst_analog_accel",
216 +       .attrs = mid_att_acc
217 +};
218 +
219 +static int
220 +mrst_analog_accel_initialize(void)
221 +{
222 +       struct ipc_pmic_mod_reg_data ipc_mod_data;
223 +       struct ipc_pmic_reg_data ipc_data;
224 +       u8 retval = 0;
225 +       u8 mad_cntrl = 0;       /* MADCINT register value */
226 +       u8 adc_cntrl2 = 0;      /* ADCCNTL2 register value */
227 +       int i, j;
228 +
229 +       /* Initialize the register index to use to be zero */
230 +       mrst_analog_reg_idx = 0;
231 +
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;
239 +
240 +       retval = ipc_pmic_register_read(&ipc_data);
241 +       if (retval != 0) {
242 +               printk(KERN_ALERT
243 +                       "\nmrst_analog_accel:PMIC register read failed\n");
244 +               return retval;
245 +       }
246 +
247 +       adc_cntrl2 = ipc_data.pmic_reg_data[0].value;
248 +
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
252 +               ** first free one
253 +               */
254 +               for (i = 0;
255 +                       (i < PMIC_ADC_REG_MAX) && (mrst_analog_reg_idx == 0);
256 +                       i += REG_READ_PER_IPC) {
257 +
258 +                       ipc_data.num_entries = REG_READ_PER_IPC;
259 +                       ipc_data.ioc = FALSE;   /* No need to generate MSI */
260 +
261 +                       /* Reading 4 regs at a time instead of reading each
262 +                        * reg one by one since IPC is an expensive operation
263 +                        */
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;
268 +                       }
269 +                       retval = ipc_pmic_register_read(&ipc_data);
270 +                       if (retval != 0) {
271 +                               printk(KERN_ALERT
272 +                               "\nmrst_analog_accel:PMIC regs read failed\n");
273 +                               return retval;
274 +                       }
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;
279 +                                       break;
280 +                               }
281 +                       }
282 +               }
283 +       }
284 +       /* Check to see if there are enough registers to map the channel */
285 +       if ((mrst_analog_reg_idx + 3) >= PMIC_ADC_REG_MAX) {
286 +               printk(KERN_ALERT
287 +               "\nmrst_analog_accel:Not enough regs to map the channels\n");
288 +               return -1;
289 +       }
290 +
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;
297 +
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;
301 +
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;
305 +
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;
309 +
310 +       retval = ipc_pmic_register_write(&ipc_data, FALSE);
311 +       if (retval != 0) {
312 +               printk(KERN_ALERT
313 +                       "\nmrst_analog_accel:PMIC reg write failed\n");
314 +               return retval;
315 +       }
316 +
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;
322 +               mad_cntrl = 0x01;
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;
327 +
328 +               retval = ipc_pmic_register_read_modify(&ipc_mod_data);
329 +               if (retval != 0) {
330 +                       printk(KERN_ALERT
331 +                       "\nmrst_analog_accel:PMIC reg modify failed\n");
332 +                       return retval;
333 +               }
334 +
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);
343 +               if (retval != 0)
344 +                       return retval;
345 +       }
346 +       return retval;
347 +}
348 +
349 +static struct platform_device *mrst_analog_accel_pdev;
350 +static struct device *mrst_analog_accel_hwmon;
351 +
352 +static int
353 +mrst_analog_accel_unregister(void)
354 +{
355 +
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");
361 +       return 0;
362 +}
363 +
364 +
365 +static int __init
366 +mrst_analog_accel_module_init(void)
367 +{
368 +       int retval = 0;
369 +
370 +       mrst_analog_accel_pdev =
371 +               platform_device_register_simple("mrst_analog_accel",
372 +                       0, NULL, 0);
373 +       if (IS_ERR(mrst_analog_accel_pdev)) {
374 +               retval = PTR_ERR(mrst_analog_accel_pdev);
375 +               printk(KERN_ALERT
376 +               "\nmrst_analog_accel:Registration with the platform failed\n");
377 +               goto accelero_reg_failed;
378 +       }
379 +       printk(KERN_ALERT
380 +               "\nmrst_analog_accel:Registered with the platform\n");
381 +
382 +       retval = mrst_analog_accel_initialize();
383 +       if (retval == 0) {
384 +               retval = sysfs_create_group(&mrst_analog_accel_pdev->dev.kobj,
385 +                       &m_analog_gr);
386 +               if (retval) {
387 +                       printk(KERN_ALERT
388 +                       "\nmrst_analog_accel:device_create_file 1 failed\n");
389 +                       goto accelero_reg_failed;
390 +               }
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;
396 +                       printk(KERN_ALERT
397 +                       "\nmrst_analog_accel:Registration with hwmon failed\n");
398 +               }
399 +       } else {
400 +               printk(KERN_ALERT
401 +               "\nmrst_analog_accel:Initialization failed: %d\n", retval);
402 +       }
403 +
404 +accelero_reg_failed:
405 +       return retval;
406 +}
407 +
408 +static void __exit
409 +mrst_analog_accel_module_exit(void)
410 +{
411 +
412 +       mrst_analog_accel_unregister();
413 +}
414 +
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:
422         return -EINVAL;
423  }
424  
425 -static ssize_t reboot_mem_store(struct device *dev,
426 -               struct device_attribute *attr, const char *buf, size_t count)
427 -{
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;
431 -       unsigned long val;
432 -
433 -       if (strict_strtoul(buf, 10, &val))
434 -               return -EINVAL;
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);
441 -       } else
442 -               return -EINVAL;
443 -       return count;
444 -}
445 -
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,
451 -                       reboot_mem_store);
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,
460         &dev_attr_x.attr,
461         &dev_attr_y.attr,
462         &dev_attr_z.attr,