aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig31
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/bh1780gli.c273
-rw-r--r--drivers/misc/bmp085.c482
-rw-r--r--drivers/misc/hmc6352.c166
-rw-r--r--drivers/misc/hpilo.c17
-rw-r--r--drivers/misc/hpilo.h8
7 files changed, 966 insertions, 14 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 9b089dfb173e..0b591b658243 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -72,7 +72,7 @@ config ATMEL_TCLIB
72 72
73config ATMEL_TCB_CLKSRC 73config ATMEL_TCB_CLKSRC
74 bool "TC Block Clocksource" 74 bool "TC Block Clocksource"
75 depends on ATMEL_TCLIB && GENERIC_TIME 75 depends on ATMEL_TCLIB
76 default y 76 default y
77 help 77 help
78 Select this to get a high precision clocksource based on a 78 Select this to get a high precision clocksource based on a
@@ -240,7 +240,7 @@ config CS5535_MFGPT_DEFAULT_IRQ
240 240
241config CS5535_CLOCK_EVENT_SRC 241config CS5535_CLOCK_EVENT_SRC
242 tristate "CS5535/CS5536 high-res timer (MFGPT) events" 242 tristate "CS5535/CS5536 high-res timer (MFGPT) events"
243 depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT 243 depends on GENERIC_CLOCKEVENTS && CS5535_MFGPT
244 help 244 help
245 This driver provides a clock event source based on the MFGPT 245 This driver provides a clock event source based on the MFGPT
246 timer(s) in the CS5535 and CS5536 companion chips. 246 timer(s) in the CS5535 and CS5536 companion chips.
@@ -304,6 +304,23 @@ config SENSORS_TSL2550
304 This driver can also be built as a module. If so, the module 304 This driver can also be built as a module. If so, the module
305 will be called tsl2550. 305 will be called tsl2550.
306 306
307config SENSORS_BH1780
308 tristate "ROHM BH1780GLI ambient light sensor"
309 depends on I2C && SYSFS
310 help
311 If you say yes here you get support for the ROHM BH1780GLI
312 ambient light sensor.
313
314 This driver can also be built as a module. If so, the module
315 will be called bh1780gli.
316
317config HMC6352
318 tristate "Honeywell HMC6352 compass"
319 depends on I2C
320 help
321 This driver provides support for the Honeywell HMC6352 compass,
322 providing configuration and heading data via sysfs.
323
307config EP93XX_PWM 324config EP93XX_PWM
308 tristate "EP93xx PWM support" 325 tristate "EP93xx PWM support"
309 depends on ARCH_EP93XX 326 depends on ARCH_EP93XX
@@ -363,6 +380,16 @@ config ARM_CHARLCD
363 line and the Linux version on the second line, but that's 380 line and the Linux version on the second line, but that's
364 still useful. 381 still useful.
365 382
383config BMP085
384 tristate "BMP085 digital pressure sensor"
385 depends on I2C && SYSFS
386 help
387 If you say yes here you get support for the Bosch Sensortec
388 BMP086 digital pressure sensor.
389
390 To compile this driver as a module, choose M here: the
391 module will be called bmp085.
392
366source "drivers/misc/c2port/Kconfig" 393source "drivers/misc/c2port/Kconfig"
367source "drivers/misc/eeprom/Kconfig" 394source "drivers/misc/eeprom/Kconfig"
368source "drivers/misc/cb710/Kconfig" 395source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 67552d6e9327..255a80dc9d73 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -9,11 +9,13 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
9obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o 9obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
10obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o 10obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
11obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o 11obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
12obj-$(CONFIG_BMP085) += bmp085.o
12obj-$(CONFIG_ICS932S401) += ics932s401.o 13obj-$(CONFIG_ICS932S401) += ics932s401.o
13obj-$(CONFIG_LKDTM) += lkdtm.o 14obj-$(CONFIG_LKDTM) += lkdtm.o
14obj-$(CONFIG_TIFM_CORE) += tifm_core.o 15obj-$(CONFIG_TIFM_CORE) += tifm_core.o
15obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 16obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
16obj-$(CONFIG_PHANTOM) += phantom.o 17obj-$(CONFIG_PHANTOM) += phantom.o
18obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o
17obj-$(CONFIG_SGI_IOC4) += ioc4.o 19obj-$(CONFIG_SGI_IOC4) += ioc4.o
18obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o 20obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
19obj-$(CONFIG_KGDB_TESTS) += kgdbts.o 21obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
@@ -28,6 +30,7 @@ obj-$(CONFIG_DS1682) += ds1682.o
28obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o 30obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
29obj-$(CONFIG_C2PORT) += c2port/ 31obj-$(CONFIG_C2PORT) += c2port/
30obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ 32obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
33obj-$(CONFIG_HMC6352) += hmc6352.o
31obj-y += eeprom/ 34obj-y += eeprom/
32obj-y += cb710/ 35obj-y += cb710/
33obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o 36obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c
new file mode 100644
index 000000000000..714c6b487313
--- /dev/null
+++ b/drivers/misc/bh1780gli.c
@@ -0,0 +1,273 @@
1/*
2 * bh1780gli.c
3 * ROHM Ambient Light Sensor Driver
4 *
5 * Copyright (C) 2010 Texas Instruments
6 * Author: Hemanth V <hemanthv@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <linux/mutex.h>
23#include <linux/platform_device.h>
24#include <linux/delay.h>
25
26#define BH1780_REG_CONTROL 0x80
27#define BH1780_REG_PARTID 0x8A
28#define BH1780_REG_MANFID 0x8B
29#define BH1780_REG_DLOW 0x8C
30#define BH1780_REG_DHIGH 0x8D
31
32#define BH1780_REVMASK (0xf)
33#define BH1780_POWMASK (0x3)
34#define BH1780_POFF (0x0)
35#define BH1780_PON (0x3)
36
37/* power on settling time in ms */
38#define BH1780_PON_DELAY 2
39
40struct bh1780_data {
41 struct i2c_client *client;
42 int power_state;
43 /* lock for sysfs operations */
44 struct mutex lock;
45};
46
47static int bh1780_write(struct bh1780_data *ddata, u8 reg, u8 val, char *msg)
48{
49 int ret = i2c_smbus_write_byte_data(ddata->client, reg, val);
50 if (ret < 0)
51 dev_err(&ddata->client->dev,
52 "i2c_smbus_write_byte_data failed error %d\
53 Register (%s)\n", ret, msg);
54 return ret;
55}
56
57static int bh1780_read(struct bh1780_data *ddata, u8 reg, char *msg)
58{
59 int ret = i2c_smbus_read_byte_data(ddata->client, reg);
60 if (ret < 0)
61 dev_err(&ddata->client->dev,
62 "i2c_smbus_read_byte_data failed error %d\
63 Register (%s)\n", ret, msg);
64 return ret;
65}
66
67static ssize_t bh1780_show_lux(struct device *dev,
68 struct device_attribute *attr, char *buf)
69{
70 struct platform_device *pdev = to_platform_device(dev);
71 struct bh1780_data *ddata = platform_get_drvdata(pdev);
72 int lsb, msb;
73
74 lsb = bh1780_read(ddata, BH1780_REG_DLOW, "DLOW");
75 if (lsb < 0)
76 return lsb;
77
78 msb = bh1780_read(ddata, BH1780_REG_DHIGH, "DHIGH");
79 if (msb < 0)
80 return msb;
81
82 return sprintf(buf, "%d\n", (msb << 8) | lsb);
83}
84
85static ssize_t bh1780_show_power_state(struct device *dev,
86 struct device_attribute *attr,
87 char *buf)
88{
89 struct platform_device *pdev = to_platform_device(dev);
90 struct bh1780_data *ddata = platform_get_drvdata(pdev);
91 int state;
92
93 state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL");
94 if (state < 0)
95 return state;
96
97 return sprintf(buf, "%d\n", state & BH1780_POWMASK);
98}
99
100static ssize_t bh1780_store_power_state(struct device *dev,
101 struct device_attribute *attr,
102 const char *buf, size_t count)
103{
104 struct platform_device *pdev = to_platform_device(dev);
105 struct bh1780_data *ddata = platform_get_drvdata(pdev);
106 unsigned long val;
107 int error;
108
109 error = strict_strtoul(buf, 0, &val);
110 if (error)
111 return error;
112
113 if (val < BH1780_POFF || val > BH1780_PON)
114 return -EINVAL;
115
116 mutex_lock(&ddata->lock);
117
118 error = bh1780_write(ddata, BH1780_REG_CONTROL, val, "CONTROL");
119 if (error < 0) {
120 mutex_unlock(&ddata->lock);
121 return error;
122 }
123
124 msleep(BH1780_PON_DELAY);
125 ddata->power_state = val;
126 mutex_unlock(&ddata->lock);
127
128 return count;
129}
130
131static DEVICE_ATTR(lux, S_IRUGO, bh1780_show_lux, NULL);
132
133static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
134 bh1780_show_power_state, bh1780_store_power_state);
135
136static struct attribute *bh1780_attributes[] = {
137 &dev_attr_power_state.attr,
138 &dev_attr_lux.attr,
139 NULL
140};
141
142static const struct attribute_group bh1780_attr_group = {
143 .attrs = bh1780_attributes,
144};
145
146static int __devinit bh1780_probe(struct i2c_client *client,
147 const struct i2c_device_id *id)
148{
149 int ret;
150 struct bh1780_data *ddata = NULL;
151 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
152
153 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
154 ret = -EIO;
155 goto err_op_failed;
156 }
157
158 ddata = kzalloc(sizeof(struct bh1780_data), GFP_KERNEL);
159 if (ddata == NULL) {
160 ret = -ENOMEM;
161 goto err_op_failed;
162 }
163
164 ddata->client = client;
165 i2c_set_clientdata(client, ddata);
166
167 ret = bh1780_read(ddata, BH1780_REG_PARTID, "PART ID");
168 if (ret < 0)
169 goto err_op_failed;
170
171 dev_info(&client->dev, "Ambient Light Sensor, Rev : %d\n",
172 (ret & BH1780_REVMASK));
173
174 mutex_init(&ddata->lock);
175
176 ret = sysfs_create_group(&client->dev.kobj, &bh1780_attr_group);
177 if (ret)
178 goto err_op_failed;
179
180 return 0;
181
182err_op_failed:
183 kfree(ddata);
184 return ret;
185}
186
187static int __devexit bh1780_remove(struct i2c_client *client)
188{
189 struct bh1780_data *ddata;
190
191 ddata = i2c_get_clientdata(client);
192 sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group);
193 i2c_set_clientdata(client, NULL);
194 kfree(ddata);
195
196 return 0;
197}
198
199#ifdef CONFIG_PM
200static int bh1780_suspend(struct i2c_client *client, pm_message_t mesg)
201{
202 struct bh1780_data *ddata;
203 int state, ret;
204
205 ddata = i2c_get_clientdata(client);
206 state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL");
207 if (state < 0)
208 return state;
209
210 ddata->power_state = state & BH1780_POWMASK;
211
212 ret = bh1780_write(ddata, BH1780_REG_CONTROL, BH1780_POFF,
213 "CONTROL");
214
215 if (ret < 0)
216 return ret;
217
218 return 0;
219}
220
221static int bh1780_resume(struct i2c_client *client)
222{
223 struct bh1780_data *ddata;
224 int state, ret;
225
226 ddata = i2c_get_clientdata(client);
227 state = ddata->power_state;
228
229 ret = bh1780_write(ddata, BH1780_REG_CONTROL, state,
230 "CONTROL");
231
232 if (ret < 0)
233 return ret;
234
235 return 0;
236}
237#else
238#define bh1780_suspend NULL
239#define bh1780_resume NULL
240#endif /* CONFIG_PM */
241
242static const struct i2c_device_id bh1780_id[] = {
243 { "bh1780", 0 },
244 { },
245};
246
247static struct i2c_driver bh1780_driver = {
248 .probe = bh1780_probe,
249 .remove = bh1780_remove,
250 .id_table = bh1780_id,
251 .suspend = bh1780_suspend,
252 .resume = bh1780_resume,
253 .driver = {
254 .name = "bh1780"
255 },
256};
257
258static int __init bh1780_init(void)
259{
260 return i2c_add_driver(&bh1780_driver);
261}
262
263static void __exit bh1780_exit(void)
264{
265 i2c_del_driver(&bh1780_driver);
266}
267
268module_init(bh1780_init)
269module_exit(bh1780_exit)
270
271MODULE_DESCRIPTION("BH1780GLI Ambient Light Sensor Driver");
272MODULE_LICENSE("GPL");
273MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c
new file mode 100644
index 000000000000..63ee4c1a5315
--- /dev/null
+++ b/drivers/misc/bmp085.c
@@ -0,0 +1,482 @@
1/* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
2
3 This driver supports the bmp085 digital barometric pressure
4 and temperature sensor from Bosch Sensortec. The datasheet
5 is avaliable from their website:
6 http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
7
8 A pressure measurement is issued by reading from pressure0_input.
9 The return value ranges from 30000 to 110000 pascal with a resulution
10 of 1 pascal (0.01 millibar) which enables measurements from 9000m above
11 to 500m below sea level.
12
13 The temperature can be read from temp0_input. Values range from
14 -400 to 850 representing the ambient temperature in degree celsius
15 multiplied by 10.The resolution is 0.1 celsius.
16
17 Because ambient pressure is temperature dependent, a temperature
18 measurement will be executed automatically even if the user is reading
19 from pressure0_input. This happens if the last temperature measurement
20 has been executed more then one second ago.
21
22 To decrease RMS noise from pressure measurements, the bmp085 can
23 autonomously calculate the average of up to eight samples. This is
24 set up by writing to the oversampling sysfs file. Accepted values
25 are 0, 1, 2 and 3. 2^x when x is the value written to this file
26 specifies the number of samples used to calculate the ambient pressure.
27 RMS noise is specified with six pascal (without averaging) and decreases
28 down to 3 pascal when using an oversampling setting of 3.
29
30 This program is free software; you can redistribute it and/or modify
31 it under the terms of the GNU General Public License as published by
32 the Free Software Foundation; either version 2 of the License, or
33 (at your option) any later version.
34
35 This program is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 GNU General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with this program; if not, write to the Free Software
42 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
43*/
44
45
46#include <linux/module.h>
47#include <linux/init.h>
48#include <linux/i2c.h>
49#include <linux/slab.h>
50#include <linux/delay.h>
51
52
53#define BMP085_I2C_ADDRESS 0x77
54#define BMP085_CHIP_ID 0x55
55
56#define BMP085_CALIBRATION_DATA_START 0xAA
57#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
58#define BMP085_CHIP_ID_REG 0xD0
59#define BMP085_VERSION_REG 0xD1
60#define BMP085_CTRL_REG 0xF4
61#define BMP085_TEMP_MEASUREMENT 0x2E
62#define BMP085_PRESSURE_MEASUREMENT 0x34
63#define BMP085_CONVERSION_REGISTER_MSB 0xF6
64#define BMP085_CONVERSION_REGISTER_LSB 0xF7
65#define BMP085_CONVERSION_REGISTER_XLSB 0xF8
66#define BMP085_TEMP_CONVERSION_TIME 5
67
68#define BMP085_CLIENT_NAME "bmp085"
69
70
71static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
72 I2C_CLIENT_END };
73
74struct bmp085_calibration_data {
75 s16 AC1, AC2, AC3;
76 u16 AC4, AC5, AC6;
77 s16 B1, B2;
78 s16 MB, MC, MD;
79};
80
81
82/* Each client has this additional data */
83struct bmp085_data {
84 struct i2c_client *client;
85 struct mutex lock;
86 struct bmp085_calibration_data calibration;
87 u32 raw_temperature;
88 u32 raw_pressure;
89 unsigned char oversampling_setting;
90 u32 last_temp_measurement;
91 s32 b6; /* calculated temperature correction coefficient */
92};
93
94
95static s32 bmp085_read_calibration_data(struct i2c_client *client)
96{
97 u16 tmp[BMP085_CALIBRATION_DATA_LENGTH];
98 struct bmp085_data *data = i2c_get_clientdata(client);
99 struct bmp085_calibration_data *cali = &(data->calibration);
100 s32 status = i2c_smbus_read_i2c_block_data(client,
101 BMP085_CALIBRATION_DATA_START,
102 BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16),
103 (u8 *)tmp);
104 if (status < 0)
105 return status;
106
107 if (status != BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16))
108 return -EIO;
109
110 cali->AC1 = be16_to_cpu(tmp[0]);
111 cali->AC2 = be16_to_cpu(tmp[1]);
112 cali->AC3 = be16_to_cpu(tmp[2]);
113 cali->AC4 = be16_to_cpu(tmp[3]);
114 cali->AC5 = be16_to_cpu(tmp[4]);
115 cali->AC6 = be16_to_cpu(tmp[5]);
116 cali->B1 = be16_to_cpu(tmp[6]);
117 cali->B2 = be16_to_cpu(tmp[7]);
118 cali->MB = be16_to_cpu(tmp[8]);
119 cali->MC = be16_to_cpu(tmp[9]);
120 cali->MD = be16_to_cpu(tmp[10]);
121 return 0;
122}
123
124
125static s32 bmp085_update_raw_temperature(struct bmp085_data *data)
126{
127 u16 tmp;
128 s32 status;
129
130 mutex_lock(&data->lock);
131 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
132 BMP085_TEMP_MEASUREMENT);
133 if (status != 0) {
134 dev_err(&data->client->dev,
135 "Error while requesting temperature measurement.\n");
136 goto exit;
137 }
138 msleep(BMP085_TEMP_CONVERSION_TIME);
139
140 status = i2c_smbus_read_i2c_block_data(data->client,
141 BMP085_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
142 if (status < 0)
143 goto exit;
144 if (status != sizeof(tmp)) {
145 dev_err(&data->client->dev,
146 "Error while reading temperature measurement result\n");
147 status = -EIO;
148 goto exit;
149 }
150 data->raw_temperature = be16_to_cpu(tmp);
151 data->last_temp_measurement = jiffies;
152 status = 0; /* everything ok, return 0 */
153
154exit:
155 mutex_unlock(&data->lock);
156 return status;
157}
158
159static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
160{
161 u32 tmp = 0;
162 s32 status;
163
164 mutex_lock(&data->lock);
165 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
166 BMP085_PRESSURE_MEASUREMENT + (data->oversampling_setting<<6));
167 if (status != 0) {
168 dev_err(&data->client->dev,
169 "Error while requesting pressure measurement.\n");
170 goto exit;
171 }
172
173 /* wait for the end of conversion */
174 msleep(2+(3 << data->oversampling_setting));
175
176 /* copy data into a u32 (4 bytes), but skip the first byte. */
177 status = i2c_smbus_read_i2c_block_data(data->client,
178 BMP085_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
179 if (status < 0)
180 goto exit;
181 if (status != 3) {
182 dev_err(&data->client->dev,
183 "Error while reading pressure measurement results\n");
184 status = -EIO;
185 goto exit;
186 }
187 data->raw_pressure = be32_to_cpu((tmp));
188 data->raw_pressure >>= (8-data->oversampling_setting);
189 status = 0; /* everything ok, return 0 */
190
191exit:
192 mutex_unlock(&data->lock);
193 return status;
194}
195
196
197/*
198 * This function starts the temperature measurement and returns the value
199 * in tenth of a degree celsius.
200 */
201static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature)
202{
203 struct bmp085_calibration_data *cali = &data->calibration;
204 long x1, x2;
205 int status;
206
207 status = bmp085_update_raw_temperature(data);
208 if (status != 0)
209 goto exit;
210
211 x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
212 x2 = (cali->MC << 11) / (x1 + cali->MD);
213 data->b6 = x1 + x2 - 4000;
214 /* if NULL just update b6. Used for pressure only measurements */
215 if (temperature != NULL)
216 *temperature = (x1+x2+8) >> 4;
217
218exit:
219 return status;;
220}
221
222/*
223 * This function starts the pressure measurement and returns the value
224 * in millibar. Since the pressure depends on the ambient temperature,
225 * a temperature measurement is executed if the last known value is older
226 * than one second.
227 */
228static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
229{
230 struct bmp085_calibration_data *cali = &data->calibration;
231 s32 x1, x2, x3, b3;
232 u32 b4, b7;
233 s32 p;
234 int status;
235
236 /* alt least every second force an update of the ambient temperature */
237 if (data->last_temp_measurement + 1*HZ < jiffies) {
238 status = bmp085_get_temperature(data, NULL);
239 if (status != 0)
240 goto exit;
241 }
242
243 status = bmp085_update_raw_pressure(data);
244 if (status != 0)
245 goto exit;
246
247 x1 = (data->b6 * data->b6) >> 12;
248 x1 *= cali->B2;
249 x1 >>= 11;
250
251 x2 = cali->AC2 * data->b6;
252 x2 >>= 11;
253
254 x3 = x1 + x2;
255
256 b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
257 b3 >>= 2;
258
259 x1 = (cali->AC3 * data->b6) >> 13;
260 x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
261 x3 = (x1 + x2 + 2) >> 2;
262 b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
263
264 b7 = ((u32)data->raw_pressure - b3) *
265 (50000 >> data->oversampling_setting);
266 p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
267
268 x1 = p >> 8;
269 x1 *= x1;
270 x1 = (x1 * 3038) >> 16;
271 x2 = (-7357 * p) >> 16;
272 p += (x1 + x2 + 3791) >> 4;
273
274 *pressure = p;
275
276exit:
277 return status;
278}
279
280/*
281 * This function sets the chip-internal oversampling. Valid values are 0..3.
282 * The chip will use 2^oversampling samples for internal averaging.
283 * This influences the measurement time and the accuracy; larger values
284 * increase both. The datasheet gives on overview on how measurement time,
285 * accuracy and noise correlate.
286 */
287static void bmp085_set_oversampling(struct bmp085_data *data,
288 unsigned char oversampling)
289{
290 if (oversampling > 3)
291 oversampling = 3;
292 data->oversampling_setting = oversampling;
293}
294
295/*
296 * Returns the currently selected oversampling. Range: 0..3
297 */
298static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
299{
300 return data->oversampling_setting;
301}
302
303/* sysfs callbacks */
304static ssize_t set_oversampling(struct device *dev,
305 struct device_attribute *attr,
306 const char *buf, size_t count)
307{
308 struct i2c_client *client = to_i2c_client(dev);
309 struct bmp085_data *data = i2c_get_clientdata(client);
310 unsigned long oversampling;
311 int success = strict_strtoul(buf, 10, &oversampling);
312 if (success == 0) {
313 bmp085_set_oversampling(data, oversampling);
314 return count;
315 }
316 return success;
317}
318
319static ssize_t show_oversampling(struct device *dev,
320 struct device_attribute *attr, char *buf)
321{
322 struct i2c_client *client = to_i2c_client(dev);
323 struct bmp085_data *data = i2c_get_clientdata(client);
324 return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
325}
326static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
327 show_oversampling, set_oversampling);
328
329
330static ssize_t show_temperature(struct device *dev,
331 struct device_attribute *attr, char *buf)
332{
333 int temperature;
334 int status;
335 struct i2c_client *client = to_i2c_client(dev);
336 struct bmp085_data *data = i2c_get_clientdata(client);
337
338 status = bmp085_get_temperature(data, &temperature);
339 if (status != 0)
340 return status;
341 else
342 return sprintf(buf, "%d\n", temperature);
343}
344static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
345
346
347static ssize_t show_pressure(struct device *dev,
348 struct device_attribute *attr, char *buf)
349{
350 int pressure;
351 int status;
352 struct i2c_client *client = to_i2c_client(dev);
353 struct bmp085_data *data = i2c_get_clientdata(client);
354
355 status = bmp085_get_pressure(data, &pressure);
356 if (status != 0)
357 return status;
358 else
359 return sprintf(buf, "%d\n", pressure);
360}
361static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
362
363
364static struct attribute *bmp085_attributes[] = {
365 &dev_attr_temp0_input.attr,
366 &dev_attr_pressure0_input.attr,
367 &dev_attr_oversampling.attr,
368 NULL
369};
370
371static const struct attribute_group bmp085_attr_group = {
372 .attrs = bmp085_attributes,
373};
374
375static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info)
376{
377 if (client->addr != BMP085_I2C_ADDRESS)
378 return -ENODEV;
379
380 if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID)
381 return -ENODEV;
382
383 return 0;
384}
385
386static int bmp085_init_client(struct i2c_client *client)
387{
388 unsigned char version;
389 int status;
390 struct bmp085_data *data = i2c_get_clientdata(client);
391 data->client = client;
392 status = bmp085_read_calibration_data(client);
393 if (status != 0)
394 goto exit;
395 version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG);
396 data->last_temp_measurement = 0;
397 data->oversampling_setting = 3;
398 mutex_init(&data->lock);
399 dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n",
400 (version & 0x0F), (version & 0xF0) >> 4);
401exit:
402 return status;
403}
404
405static int bmp085_probe(struct i2c_client *client,
406 const struct i2c_device_id *id)
407{
408 struct bmp085_data *data;
409 int err = 0;
410
411 data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL);
412 if (!data) {
413 err = -ENOMEM;
414 goto exit;
415 }
416
417 /* default settings after POR */
418 data->oversampling_setting = 0x00;
419
420 i2c_set_clientdata(client, data);
421
422 /* Initialize the BMP085 chip */
423 err = bmp085_init_client(client);
424 if (err != 0)
425 goto exit_free;
426
427 /* Register sysfs hooks */
428 err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group);
429 if (err)
430 goto exit_free;
431
432 dev_info(&data->client->dev, "Succesfully initialized bmp085!\n");
433 goto exit;
434
435exit_free:
436 kfree(data);
437exit:
438 return err;
439}
440
441static int bmp085_remove(struct i2c_client *client)
442{
443 sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group);
444 kfree(i2c_get_clientdata(client));
445 return 0;
446}
447
448static const struct i2c_device_id bmp085_id[] = {
449 { "bmp085", 0 },
450 { }
451};
452
453static struct i2c_driver bmp085_driver = {
454 .driver = {
455 .owner = THIS_MODULE,
456 .name = "bmp085"
457 },
458 .id_table = bmp085_id,
459 .probe = bmp085_probe,
460 .remove = bmp085_remove,
461
462 .detect = bmp085_detect,
463 .address_list = normal_i2c
464};
465
466static int __init bmp085_init(void)
467{
468 return i2c_add_driver(&bmp085_driver);
469}
470
471static void __exit bmp085_exit(void)
472{
473 i2c_del_driver(&bmp085_driver);
474}
475
476
477MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
478MODULE_DESCRIPTION("BMP085 driver");
479MODULE_LICENSE("GPL");
480
481module_init(bmp085_init);
482module_exit(bmp085_exit);
diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c
new file mode 100644
index 000000000000..234bfcaf2099
--- /dev/null
+++ b/drivers/misc/hmc6352.c
@@ -0,0 +1,166 @@
1/*
2 * hmc6352.c - Honeywell Compass Driver
3 *
4 * Copyright (C) 2009 Intel Corp
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include <linux/err.h>
29#include <linux/delay.h>
30#include <linux/sysfs.h>
31
32static DEFINE_MUTEX(compass_mutex);
33
34static int compass_command(struct i2c_client *c, u8 cmd)
35{
36 int ret = i2c_master_send(c, &cmd, 1);
37 if (ret < 0)
38 dev_warn(&c->dev, "command '%c' failed.\n", cmd);
39 return ret;
40}
41
42static int compass_store(struct device *dev, const char *buf, size_t count,
43 const char *map)
44{
45 struct i2c_client *c = to_i2c_client(dev);
46 int ret;
47 unsigned long val;
48
49 if (strict_strtoul(buf, 10, &val))
50 return -EINVAL;
51 if (val >= strlen(map))
52 return -EINVAL;
53 mutex_lock(&compass_mutex);
54 ret = compass_command(c, map[val]);
55 mutex_unlock(&compass_mutex);
56 if (ret < 0)
57 return ret;
58 return count;
59}
60
61static ssize_t compass_calibration_store(struct device *dev,
62 struct device_attribute *attr, const char *buf, size_t count)
63{
64 return compass_store(dev, buf, count, "EC");
65}
66
67static ssize_t compass_power_mode_store(struct device *dev,
68 struct device_attribute *attr, const char *buf, size_t count)
69{
70 return compass_store(dev, buf, count, "SW");
71}
72
73static ssize_t compass_heading_data_show(struct device *dev,
74 struct device_attribute *attr, char *buf)
75{
76 struct i2c_client *client = to_i2c_client(dev);
77 unsigned char i2c_data[2];
78 unsigned int ret;
79
80 mutex_lock(&compass_mutex);
81 ret = compass_command(client, 'A');
82 if (ret != 1) {
83 mutex_unlock(&compass_mutex);
84 return ret;
85 }
86 msleep(10); /* sending 'A' cmd we need to wait for 7-10 millisecs */
87 ret = i2c_master_recv(client, i2c_data, 2);
88 mutex_unlock(&compass_mutex);
89 if (ret != 1) {
90 dev_warn(dev, "i2c read data cmd failed\n");
91 return ret;
92 }
93 ret = (i2c_data[0] << 8) | i2c_data[1];
94 return sprintf(buf, "%d.%d\n", ret/10, ret%10);
95}
96
97
98static DEVICE_ATTR(heading0_input, S_IRUGO, compass_heading_data_show, NULL);
99static DEVICE_ATTR(calibration, S_IWUSR, NULL, compass_calibration_store);
100static DEVICE_ATTR(power_state, S_IWUSR, NULL, compass_power_mode_store);
101
102static struct attribute *mid_att_compass[] = {
103 &dev_attr_heading0_input.attr,
104 &dev_attr_calibration.attr,
105 &dev_attr_power_state.attr,
106 NULL
107};
108
109static const struct attribute_group m_compass_gr = {
110 .name = "hmc6352",
111 .attrs = mid_att_compass
112};
113
114static int hmc6352_probe(struct i2c_client *client,
115 const struct i2c_device_id *id)
116{
117 int res;
118
119 res = sysfs_create_group(&client->dev.kobj, &m_compass_gr);
120 if (res) {
121 dev_err(&client->dev, "device_create_file failed\n");
122 return res;
123 }
124 dev_info(&client->dev, "%s HMC6352 compass chip found\n",
125 client->name);
126 return 0;
127}
128
129static int hmc6352_remove(struct i2c_client *client)
130{
131 sysfs_remove_group(&client->dev.kobj, &m_compass_gr);
132 return 0;
133}
134
135static struct i2c_device_id hmc6352_id[] = {
136 { "hmc6352", 0 },
137 { }
138};
139
140MODULE_DEVICE_TABLE(i2c, hmc6352_id);
141
142static struct i2c_driver hmc6352_driver = {
143 .driver = {
144 .name = "hmc6352",
145 },
146 .probe = hmc6352_probe,
147 .remove = hmc6352_remove,
148 .id_table = hmc6352_id,
149};
150
151static int __init sensor_hmc6352_init(void)
152{
153 return i2c_add_driver(&hmc6352_driver);
154}
155
156static void __exit sensor_hmc6352_exit(void)
157{
158 i2c_del_driver(&hmc6352_driver);
159}
160
161module_init(sensor_hmc6352_init);
162module_exit(sensor_hmc6352_exit);
163
164MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
165MODULE_DESCRIPTION("hmc6352 Compass Driver");
166MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 98ad0120aa9b..557a8c2a7336 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -256,7 +256,8 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
256 256
257static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) 257static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
258{ 258{
259 char *dma_va, *dma_pa; 259 char *dma_va;
260 dma_addr_t dma_pa;
260 struct ccb *driver_ccb, *ilo_ccb; 261 struct ccb *driver_ccb, *ilo_ccb;
261 262
262 driver_ccb = &data->driver_ccb; 263 driver_ccb = &data->driver_ccb;
@@ -272,12 +273,12 @@ static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
272 return -ENOMEM; 273 return -ENOMEM;
273 274
274 dma_va = (char *)data->dma_va; 275 dma_va = (char *)data->dma_va;
275 dma_pa = (char *)data->dma_pa; 276 dma_pa = data->dma_pa;
276 277
277 memset(dma_va, 0, data->dma_size); 278 memset(dma_va, 0, data->dma_size);
278 279
279 dma_va = (char *)roundup((unsigned long)dma_va, ILO_START_ALIGN); 280 dma_va = (char *)roundup((unsigned long)dma_va, ILO_START_ALIGN);
280 dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_START_ALIGN); 281 dma_pa = roundup(dma_pa, ILO_START_ALIGN);
281 282
282 /* 283 /*
283 * Create two ccb's, one with virt addrs, one with phys addrs. 284 * Create two ccb's, one with virt addrs, one with phys addrs.
@@ -288,26 +289,26 @@ static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
288 289
289 fifo_setup(dma_va, NR_QENTRY); 290 fifo_setup(dma_va, NR_QENTRY);
290 driver_ccb->ccb_u1.send_fifobar = dma_va + FIFOHANDLESIZE; 291 driver_ccb->ccb_u1.send_fifobar = dma_va + FIFOHANDLESIZE;
291 ilo_ccb->ccb_u1.send_fifobar = dma_pa + FIFOHANDLESIZE; 292 ilo_ccb->ccb_u1.send_fifobar_pa = dma_pa + FIFOHANDLESIZE;
292 dma_va += fifo_sz(NR_QENTRY); 293 dma_va += fifo_sz(NR_QENTRY);
293 dma_pa += fifo_sz(NR_QENTRY); 294 dma_pa += fifo_sz(NR_QENTRY);
294 295
295 dma_va = (char *)roundup((unsigned long)dma_va, ILO_CACHE_SZ); 296 dma_va = (char *)roundup((unsigned long)dma_va, ILO_CACHE_SZ);
296 dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_CACHE_SZ); 297 dma_pa = roundup(dma_pa, ILO_CACHE_SZ);
297 298
298 fifo_setup(dma_va, NR_QENTRY); 299 fifo_setup(dma_va, NR_QENTRY);
299 driver_ccb->ccb_u3.recv_fifobar = dma_va + FIFOHANDLESIZE; 300 driver_ccb->ccb_u3.recv_fifobar = dma_va + FIFOHANDLESIZE;
300 ilo_ccb->ccb_u3.recv_fifobar = dma_pa + FIFOHANDLESIZE; 301 ilo_ccb->ccb_u3.recv_fifobar_pa = dma_pa + FIFOHANDLESIZE;
301 dma_va += fifo_sz(NR_QENTRY); 302 dma_va += fifo_sz(NR_QENTRY);
302 dma_pa += fifo_sz(NR_QENTRY); 303 dma_pa += fifo_sz(NR_QENTRY);
303 304
304 driver_ccb->ccb_u2.send_desc = dma_va; 305 driver_ccb->ccb_u2.send_desc = dma_va;
305 ilo_ccb->ccb_u2.send_desc = dma_pa; 306 ilo_ccb->ccb_u2.send_desc_pa = dma_pa;
306 dma_pa += desc_mem_sz(NR_QENTRY); 307 dma_pa += desc_mem_sz(NR_QENTRY);
307 dma_va += desc_mem_sz(NR_QENTRY); 308 dma_va += desc_mem_sz(NR_QENTRY);
308 309
309 driver_ccb->ccb_u4.recv_desc = dma_va; 310 driver_ccb->ccb_u4.recv_desc = dma_va;
310 ilo_ccb->ccb_u4.recv_desc = dma_pa; 311 ilo_ccb->ccb_u4.recv_desc_pa = dma_pa;
311 312
312 driver_ccb->channel = slot; 313 driver_ccb->channel = slot;
313 ilo_ccb->channel = slot; 314 ilo_ccb->channel = slot;
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index 247eb386a973..54e43adbdea1 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -79,21 +79,21 @@ struct ilo_hwinfo {
79struct ccb { 79struct ccb {
80 union { 80 union {
81 char *send_fifobar; 81 char *send_fifobar;
82 u64 padding1; 82 u64 send_fifobar_pa;
83 } ccb_u1; 83 } ccb_u1;
84 union { 84 union {
85 char *send_desc; 85 char *send_desc;
86 u64 padding2; 86 u64 send_desc_pa;
87 } ccb_u2; 87 } ccb_u2;
88 u64 send_ctrl; 88 u64 send_ctrl;
89 89
90 union { 90 union {
91 char *recv_fifobar; 91 char *recv_fifobar;
92 u64 padding3; 92 u64 recv_fifobar_pa;
93 } ccb_u3; 93 } ccb_u3;
94 union { 94 union {
95 char *recv_desc; 95 char *recv_desc;
96 u64 padding4; 96 u64 recv_desc_pa;
97 } ccb_u4; 97 } ccb_u4;
98 u64 recv_ctrl; 98 u64 recv_ctrl;
99 99