blob: 080af75c517bfcb26a4203db1e6e82e98e339c0b [file] [log] [blame]
Jonathan Cameron251eb402009-04-13 14:39:45 -07001/*
2 * sht15.c - support for the SHT15 Temperature and Humidity Sensor
3 *
4 * Copyright (c) 2009 Jonathan Cameron
5 *
6 * Copyright (c) 2007 Wouter Horre
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 version 2 as
10 * published by the Free Software Foundation.
11 *
Vivien Didelot99a03782011-04-12 15:34:36 -040012 * For further information, see the Documentation/hwmon/sht15 file.
Jonathan Cameron251eb402009-04-13 14:39:45 -070013 */
14
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/gpio.h>
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/hwmon.h>
21#include <linux/hwmon-sysfs.h>
22#include <linux/mutex.h>
23#include <linux/platform_device.h>
Alexey Dobriyand43c36d2009-10-07 17:09:06 +040024#include <linux/sched.h>
Jonathan Cameron251eb402009-04-13 14:39:45 -070025#include <linux/delay.h>
26#include <linux/jiffies.h>
27#include <linux/err.h>
28#include <linux/sht15.h>
29#include <linux/regulator/consumer.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/slab.h>
Jonathan Cameron251eb402009-04-13 14:39:45 -070031#include <asm/atomic.h>
32
Vivien Didelot99a03782011-04-12 15:34:36 -040033/* Commands */
34#define SHT15_MEASURE_TEMP 0x03
35#define SHT15_MEASURE_RH 0x05
Jonathan Cameron251eb402009-04-13 14:39:45 -070036
Vivien Didelot99a03782011-04-12 15:34:36 -040037/* Min timings */
38#define SHT15_TSCKL 100 /* (nsecs) clock low */
39#define SHT15_TSCKH 100 /* (nsecs) clock high */
40#define SHT15_TSU 150 /* (nsecs) data setup time */
Jonathan Cameron251eb402009-04-13 14:39:45 -070041
Vivien Didelot99a03782011-04-12 15:34:36 -040042/* Actions the driver may be doing */
43enum sht15_state {
44 SHT15_READING_NOTHING,
45 SHT15_READING_TEMP,
46 SHT15_READING_HUMID
47};
Jonathan Cameron251eb402009-04-13 14:39:45 -070048
49/**
Lucas De Marchi25985ed2011-03-30 22:57:33 -030050 * struct sht15_temppair - elements of voltage dependent temp calc
Jonathan Cameron251eb402009-04-13 14:39:45 -070051 * @vdd: supply voltage in microvolts
52 * @d1: see data sheet
53 */
54struct sht15_temppair {
55 int vdd; /* microvolts */
56 int d1;
57};
58
Vivien Didelot99a03782011-04-12 15:34:36 -040059/* Table 9 from datasheet - relates temperature calculation to supply voltage */
Jonathan Cameron251eb402009-04-13 14:39:45 -070060static const struct sht15_temppair temppoints[] = {
61 { 2500000, -39400 },
62 { 3000000, -39600 },
63 { 3500000, -39700 },
64 { 4000000, -39800 },
65 { 5000000, -40100 },
66};
67
68/**
69 * struct sht15_data - device instance specific data
Vivien Didelot99a03782011-04-12 15:34:36 -040070 * @pdata: platform data (gpio's etc).
71 * @read_work: bh of interrupt handler.
72 * @wait_queue: wait queue for getting values from device.
73 * @val_temp: last temperature value read from device.
74 * @val_humid: last humidity value read from device.
75 * @state: state identifying the action the driver is doing.
76 * @measurements_valid: are the current stored measures valid (start condition).
77 * @last_measurement: time of last measure.
78 * @read_lock: mutex to ensure only one read in progress at a time.
79 * @dev: associate device structure.
80 * @hwmon_dev: device associated with hwmon subsystem.
81 * @reg: associated regulator (if specified).
82 * @nb: notifier block to handle notifications of voltage
83 * changes.
84 * @supply_uV: local copy of supply voltage used to allow use of
85 * regulator consumer if available.
86 * @supply_uV_valid: indicates that an updated value has not yet been
87 * obtained from the regulator and so any calculations
88 * based upon it will be invalid.
89 * @update_supply_work: work struct that is used to update the supply_uV.
90 * @interrupt_handled: flag used to indicate a handler has been scheduled.
Jonathan Cameron251eb402009-04-13 14:39:45 -070091 */
92struct sht15_data {
93 struct sht15_platform_data *pdata;
94 struct work_struct read_work;
95 wait_queue_head_t wait_queue;
96 uint16_t val_temp;
97 uint16_t val_humid;
Vivien Didelot99a03782011-04-12 15:34:36 -040098 enum sht15_state state;
99 bool measurements_valid;
100 unsigned long last_measurement;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700101 struct mutex read_lock;
102 struct device *dev;
103 struct device *hwmon_dev;
104 struct regulator *reg;
105 struct notifier_block nb;
106 int supply_uV;
Vivien Didelot99a03782011-04-12 15:34:36 -0400107 bool supply_uV_valid;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700108 struct work_struct update_supply_work;
109 atomic_t interrupt_handled;
110};
111
112/**
113 * sht15_connection_reset() - reset the comms interface
114 * @data: sht15 specific data
115 *
116 * This implements section 3.4 of the data sheet
117 */
118static void sht15_connection_reset(struct sht15_data *data)
119{
120 int i;
Vivien Didelot99a03782011-04-12 15:34:36 -0400121
Jonathan Cameron251eb402009-04-13 14:39:45 -0700122 gpio_direction_output(data->pdata->gpio_data, 1);
123 ndelay(SHT15_TSCKL);
124 gpio_set_value(data->pdata->gpio_sck, 0);
125 ndelay(SHT15_TSCKL);
126 for (i = 0; i < 9; ++i) {
127 gpio_set_value(data->pdata->gpio_sck, 1);
128 ndelay(SHT15_TSCKH);
129 gpio_set_value(data->pdata->gpio_sck, 0);
130 ndelay(SHT15_TSCKL);
131 }
132}
Vivien Didelot99a03782011-04-12 15:34:36 -0400133
Jonathan Cameron251eb402009-04-13 14:39:45 -0700134/**
135 * sht15_send_bit() - send an individual bit to the device
136 * @data: device state data
137 * @val: value of bit to be sent
Vivien Didelot99a03782011-04-12 15:34:36 -0400138 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700139static inline void sht15_send_bit(struct sht15_data *data, int val)
140{
Jonathan Cameron251eb402009-04-13 14:39:45 -0700141 gpio_set_value(data->pdata->gpio_data, val);
142 ndelay(SHT15_TSU);
143 gpio_set_value(data->pdata->gpio_sck, 1);
144 ndelay(SHT15_TSCKH);
145 gpio_set_value(data->pdata->gpio_sck, 0);
146 ndelay(SHT15_TSCKL); /* clock low time */
147}
148
149/**
150 * sht15_transmission_start() - specific sequence for new transmission
Jonathan Cameron251eb402009-04-13 14:39:45 -0700151 * @data: device state data
Vivien Didelot99a03782011-04-12 15:34:36 -0400152 *
Jonathan Cameron251eb402009-04-13 14:39:45 -0700153 * Timings for this are not documented on the data sheet, so very
154 * conservative ones used in implementation. This implements
155 * figure 12 on the data sheet.
Vivien Didelot99a03782011-04-12 15:34:36 -0400156 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700157static void sht15_transmission_start(struct sht15_data *data)
158{
159 /* ensure data is high and output */
160 gpio_direction_output(data->pdata->gpio_data, 1);
161 ndelay(SHT15_TSU);
162 gpio_set_value(data->pdata->gpio_sck, 0);
163 ndelay(SHT15_TSCKL);
164 gpio_set_value(data->pdata->gpio_sck, 1);
165 ndelay(SHT15_TSCKH);
166 gpio_set_value(data->pdata->gpio_data, 0);
167 ndelay(SHT15_TSU);
168 gpio_set_value(data->pdata->gpio_sck, 0);
169 ndelay(SHT15_TSCKL);
170 gpio_set_value(data->pdata->gpio_sck, 1);
171 ndelay(SHT15_TSCKH);
172 gpio_set_value(data->pdata->gpio_data, 1);
173 ndelay(SHT15_TSU);
174 gpio_set_value(data->pdata->gpio_sck, 0);
175 ndelay(SHT15_TSCKL);
176}
Vivien Didelot99a03782011-04-12 15:34:36 -0400177
Jonathan Cameron251eb402009-04-13 14:39:45 -0700178/**
179 * sht15_send_byte() - send a single byte to the device
180 * @data: device state
181 * @byte: value to be sent
Vivien Didelot99a03782011-04-12 15:34:36 -0400182 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700183static void sht15_send_byte(struct sht15_data *data, u8 byte)
184{
185 int i;
Vivien Didelot99a03782011-04-12 15:34:36 -0400186
Jonathan Cameron251eb402009-04-13 14:39:45 -0700187 for (i = 0; i < 8; i++) {
188 sht15_send_bit(data, !!(byte & 0x80));
189 byte <<= 1;
190 }
191}
Vivien Didelot99a03782011-04-12 15:34:36 -0400192
Jonathan Cameron251eb402009-04-13 14:39:45 -0700193/**
194 * sht15_wait_for_response() - checks for ack from device
195 * @data: device state
Vivien Didelot99a03782011-04-12 15:34:36 -0400196 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700197static int sht15_wait_for_response(struct sht15_data *data)
198{
199 gpio_direction_input(data->pdata->gpio_data);
200 gpio_set_value(data->pdata->gpio_sck, 1);
201 ndelay(SHT15_TSCKH);
202 if (gpio_get_value(data->pdata->gpio_data)) {
203 gpio_set_value(data->pdata->gpio_sck, 0);
204 dev_err(data->dev, "Command not acknowledged\n");
205 sht15_connection_reset(data);
206 return -EIO;
207 }
208 gpio_set_value(data->pdata->gpio_sck, 0);
209 ndelay(SHT15_TSCKL);
210 return 0;
211}
212
213/**
214 * sht15_send_cmd() - Sends a command to the device.
215 * @data: device state
216 * @cmd: command byte to be sent
217 *
218 * On entry, sck is output low, data is output pull high
219 * and the interrupt disabled.
Vivien Didelot99a03782011-04-12 15:34:36 -0400220 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700221static int sht15_send_cmd(struct sht15_data *data, u8 cmd)
222{
223 int ret = 0;
Vivien Didelot99a03782011-04-12 15:34:36 -0400224
Jonathan Cameron251eb402009-04-13 14:39:45 -0700225 sht15_transmission_start(data);
226 sht15_send_byte(data, cmd);
227 ret = sht15_wait_for_response(data);
228 return ret;
229}
Vivien Didelot99a03782011-04-12 15:34:36 -0400230
Jonathan Cameron251eb402009-04-13 14:39:45 -0700231/**
Vivien Didelot99a03782011-04-12 15:34:36 -0400232 * sht15_measurement() - get a new value from device
Jonathan Cameron251eb402009-04-13 14:39:45 -0700233 * @data: device instance specific data
234 * @command: command sent to request value
235 * @timeout_msecs: timeout after which comms are assumed
236 * to have failed are reset.
Vivien Didelot99a03782011-04-12 15:34:36 -0400237 */
238static int sht15_measurement(struct sht15_data *data,
239 int command,
240 int timeout_msecs)
Jonathan Cameron251eb402009-04-13 14:39:45 -0700241{
242 int ret;
Vivien Didelot99a03782011-04-12 15:34:36 -0400243
Jonathan Cameron251eb402009-04-13 14:39:45 -0700244 ret = sht15_send_cmd(data, command);
245 if (ret)
246 return ret;
247
248 gpio_direction_input(data->pdata->gpio_data);
249 atomic_set(&data->interrupt_handled, 0);
250
251 enable_irq(gpio_to_irq(data->pdata->gpio_data));
252 if (gpio_get_value(data->pdata->gpio_data) == 0) {
253 disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300254 /* Only relevant if the interrupt hasn't occurred. */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700255 if (!atomic_read(&data->interrupt_handled))
256 schedule_work(&data->read_work);
257 }
258 ret = wait_event_timeout(data->wait_queue,
Vivien Didelot99a03782011-04-12 15:34:36 -0400259 (data->state == SHT15_READING_NOTHING),
Jonathan Cameron251eb402009-04-13 14:39:45 -0700260 msecs_to_jiffies(timeout_msecs));
261 if (ret == 0) {/* timeout occurred */
Joe Perches24205e02009-07-11 13:42:37 +0200262 disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
Jonathan Cameron251eb402009-04-13 14:39:45 -0700263 sht15_connection_reset(data);
264 return -ETIME;
265 }
266 return 0;
267}
268
269/**
Vivien Didelot99a03782011-04-12 15:34:36 -0400270 * sht15_update_measurements() - get updated measures from device if too old
Jonathan Cameron251eb402009-04-13 14:39:45 -0700271 * @data: device state
Vivien Didelot99a03782011-04-12 15:34:36 -0400272 */
273static int sht15_update_measurements(struct sht15_data *data)
Jonathan Cameron251eb402009-04-13 14:39:45 -0700274{
275 int ret = 0;
276 int timeout = HZ;
277
278 mutex_lock(&data->read_lock);
Vivien Didelot99a03782011-04-12 15:34:36 -0400279 if (time_after(jiffies, data->last_measurement + timeout)
280 || !data->measurements_valid) {
281 data->state = SHT15_READING_HUMID;
282 ret = sht15_measurement(data, SHT15_MEASURE_RH, 160);
Jonathan Cameron251eb402009-04-13 14:39:45 -0700283 if (ret)
284 goto error_ret;
Vivien Didelot99a03782011-04-12 15:34:36 -0400285 data->state = SHT15_READING_TEMP;
286 ret = sht15_measurement(data, SHT15_MEASURE_TEMP, 400);
Jonathan Cameron251eb402009-04-13 14:39:45 -0700287 if (ret)
288 goto error_ret;
Vivien Didelot99a03782011-04-12 15:34:36 -0400289 data->measurements_valid = true;
290 data->last_measurement = jiffies;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700291 }
292error_ret:
293 mutex_unlock(&data->read_lock);
294
295 return ret;
296}
297
298/**
299 * sht15_calc_temp() - convert the raw reading to a temperature
300 * @data: device state
301 *
302 * As per section 4.3 of the data sheet.
Vivien Didelot99a03782011-04-12 15:34:36 -0400303 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700304static inline int sht15_calc_temp(struct sht15_data *data)
305{
Jerome Oufella328a2c22010-04-14 16:14:07 +0200306 int d1 = temppoints[0].d1;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700307 int i;
308
Jerome Oufella328a2c22010-04-14 16:14:07 +0200309 for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--)
Jonathan Cameron251eb402009-04-13 14:39:45 -0700310 /* Find pointer to interpolate */
311 if (data->supply_uV > temppoints[i - 1].vdd) {
Jerome Oufella328a2c22010-04-14 16:14:07 +0200312 d1 = (data->supply_uV - temppoints[i - 1].vdd)
Jonathan Cameron251eb402009-04-13 14:39:45 -0700313 * (temppoints[i].d1 - temppoints[i - 1].d1)
314 / (temppoints[i].vdd - temppoints[i - 1].vdd)
315 + temppoints[i - 1].d1;
316 break;
317 }
318
Vivien Didelot99a03782011-04-12 15:34:36 -0400319 return data->val_temp * 10 + d1;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700320}
321
322/**
323 * sht15_calc_humid() - using last temperature convert raw to humid
324 * @data: device state
325 *
326 * This is the temperature compensated version as per section 4.2 of
327 * the data sheet.
Vivien Didelot99a03782011-04-12 15:34:36 -0400328 *
329 * The sensor is assumed to be V3, which is compatible with V4.
330 * Humidity conversion coefficients are shown in table 7 of the datasheet.
331 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700332static inline int sht15_calc_humid(struct sht15_data *data)
333{
Vivien Didelot99a03782011-04-12 15:34:36 -0400334 int rh_linear; /* milli percent */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700335 int temp = sht15_calc_temp(data);
336
337 const int c1 = -4;
338 const int c2 = 40500; /* x 10 ^ -6 */
Vivien Didelot99a03782011-04-12 15:34:36 -0400339 const int c3 = -28; /* x 10 ^ -7 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700340
Vivien Didelot99a03782011-04-12 15:34:36 -0400341 rh_linear = c1 * 1000
342 + c2 * data->val_humid / 1000
Vivien Didelotccd32e72011-03-21 17:59:35 +0100343 + (data->val_humid * data->val_humid * c3) / 10000;
Jonathan Cameron4235f682009-12-16 21:38:28 +0100344 return (temp - 25000) * (10000 + 80 * data->val_humid)
Vivien Didelot99a03782011-04-12 15:34:36 -0400345 / 1000000 + rh_linear;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700346}
347
Vivien Didelot99a03782011-04-12 15:34:36 -0400348/**
349 * sht15_show_temp() - show temperature measurement value in sysfs
350 * @dev: device.
351 * @attr: device attribute.
352 * @buf: sysfs buffer where measurement values are written to.
353 *
354 * Will be called on read access to temp1_input sysfs attribute.
355 * Returns number of bytes written into buffer, negative errno on error.
356 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700357static ssize_t sht15_show_temp(struct device *dev,
358 struct device_attribute *attr,
359 char *buf)
360{
361 int ret;
362 struct sht15_data *data = dev_get_drvdata(dev);
363
364 /* Technically no need to read humidity as well */
Vivien Didelot99a03782011-04-12 15:34:36 -0400365 ret = sht15_update_measurements(data);
Jonathan Cameron251eb402009-04-13 14:39:45 -0700366
367 return ret ? ret : sprintf(buf, "%d\n",
368 sht15_calc_temp(data));
369}
370
Vivien Didelot99a03782011-04-12 15:34:36 -0400371/**
372 * sht15_show_humidity() - show humidity measurement value in sysfs
373 * @dev: device.
374 * @attr: device attribute.
375 * @buf: sysfs buffer where measurement values are written to.
376 *
377 * Will be called on read access to humidity1_input sysfs attribute.
378 * Returns number of bytes written into buffer, negative errno on error.
379 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700380static ssize_t sht15_show_humidity(struct device *dev,
381 struct device_attribute *attr,
382 char *buf)
383{
384 int ret;
385 struct sht15_data *data = dev_get_drvdata(dev);
386
Vivien Didelot99a03782011-04-12 15:34:36 -0400387 ret = sht15_update_measurements(data);
Jonathan Cameron251eb402009-04-13 14:39:45 -0700388
389 return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data));
390
Vivien Didelot99a03782011-04-12 15:34:36 -0400391}
392
Jonathan Cameron251eb402009-04-13 14:39:45 -0700393static ssize_t show_name(struct device *dev,
394 struct device_attribute *attr,
395 char *buf)
396{
397 struct platform_device *pdev = to_platform_device(dev);
398 return sprintf(buf, "%s\n", pdev->name);
399}
400
Vivien Didelot99a03782011-04-12 15:34:36 -0400401static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
402 sht15_show_temp, NULL, 0);
403static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO,
404 sht15_show_humidity, NULL, 0);
Jonathan Cameron251eb402009-04-13 14:39:45 -0700405static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
406static struct attribute *sht15_attrs[] = {
407 &sensor_dev_attr_temp1_input.dev_attr.attr,
408 &sensor_dev_attr_humidity1_input.dev_attr.attr,
409 &dev_attr_name.attr,
410 NULL,
411};
412
413static const struct attribute_group sht15_attr_group = {
414 .attrs = sht15_attrs,
415};
416
417static irqreturn_t sht15_interrupt_fired(int irq, void *d)
418{
419 struct sht15_data *data = d;
Vivien Didelot99a03782011-04-12 15:34:36 -0400420
Jonathan Cameron251eb402009-04-13 14:39:45 -0700421 /* First disable the interrupt */
422 disable_irq_nosync(irq);
423 atomic_inc(&data->interrupt_handled);
424 /* Then schedule a reading work struct */
Vivien Didelot99a03782011-04-12 15:34:36 -0400425 if (data->state != SHT15_READING_NOTHING)
Jonathan Cameron251eb402009-04-13 14:39:45 -0700426 schedule_work(&data->read_work);
427 return IRQ_HANDLED;
428}
429
Vivien Didelot99a03782011-04-12 15:34:36 -0400430/**
431 * sht15_ack() - Send an ack to the device
432 *
433 * Each byte of data is acknowledged by pulling the data line
Jonathan Cameron251eb402009-04-13 14:39:45 -0700434 * low for one clock pulse.
435 */
436static void sht15_ack(struct sht15_data *data)
437{
438 gpio_direction_output(data->pdata->gpio_data, 0);
439 ndelay(SHT15_TSU);
440 gpio_set_value(data->pdata->gpio_sck, 1);
441 ndelay(SHT15_TSU);
442 gpio_set_value(data->pdata->gpio_sck, 0);
443 ndelay(SHT15_TSU);
444 gpio_set_value(data->pdata->gpio_data, 1);
445
446 gpio_direction_input(data->pdata->gpio_data);
447}
Vivien Didelot99a03782011-04-12 15:34:36 -0400448
Jonathan Cameron251eb402009-04-13 14:39:45 -0700449/**
450 * sht15_end_transmission() - notify device of end of transmission
451 * @data: device state
452 *
453 * This is basically a NAK. (single clock pulse, data high)
Vivien Didelot99a03782011-04-12 15:34:36 -0400454 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700455static void sht15_end_transmission(struct sht15_data *data)
456{
457 gpio_direction_output(data->pdata->gpio_data, 1);
458 ndelay(SHT15_TSU);
459 gpio_set_value(data->pdata->gpio_sck, 1);
460 ndelay(SHT15_TSCKH);
461 gpio_set_value(data->pdata->gpio_sck, 0);
462 ndelay(SHT15_TSCKL);
463}
464
465static void sht15_bh_read_data(struct work_struct *work_s)
466{
467 int i;
468 uint16_t val = 0;
469 struct sht15_data *data
470 = container_of(work_s, struct sht15_data,
471 read_work);
Vivien Didelot99a03782011-04-12 15:34:36 -0400472
Jonathan Cameron251eb402009-04-13 14:39:45 -0700473 /* Firstly, verify the line is low */
474 if (gpio_get_value(data->pdata->gpio_data)) {
Vivien Didelot99a03782011-04-12 15:34:36 -0400475 /*
476 * If not, then start the interrupt again - care here as could
477 * have gone low in meantime so verify it hasn't!
478 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700479 atomic_set(&data->interrupt_handled, 0);
480 enable_irq(gpio_to_irq(data->pdata->gpio_data));
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300481 /* If still not occurred or another handler has been scheduled */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700482 if (gpio_get_value(data->pdata->gpio_data)
483 || atomic_read(&data->interrupt_handled))
484 return;
485 }
Vivien Didelot99a03782011-04-12 15:34:36 -0400486
Jonathan Cameron251eb402009-04-13 14:39:45 -0700487 /* Read the data back from the device */
488 for (i = 0; i < 16; ++i) {
489 val <<= 1;
490 gpio_set_value(data->pdata->gpio_sck, 1);
491 ndelay(SHT15_TSCKH);
492 val |= !!gpio_get_value(data->pdata->gpio_data);
493 gpio_set_value(data->pdata->gpio_sck, 0);
494 ndelay(SHT15_TSCKL);
495 if (i == 7)
496 sht15_ack(data);
497 }
Vivien Didelot99a03782011-04-12 15:34:36 -0400498
Jonathan Cameron251eb402009-04-13 14:39:45 -0700499 /* Tell the device we are done */
500 sht15_end_transmission(data);
501
Vivien Didelot99a03782011-04-12 15:34:36 -0400502 switch (data->state) {
Jonathan Cameron251eb402009-04-13 14:39:45 -0700503 case SHT15_READING_TEMP:
504 data->val_temp = val;
505 break;
506 case SHT15_READING_HUMID:
507 data->val_humid = val;
508 break;
Vivien Didelot99a03782011-04-12 15:34:36 -0400509 default:
510 break;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700511 }
512
Vivien Didelot99a03782011-04-12 15:34:36 -0400513 data->state = SHT15_READING_NOTHING;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700514 wake_up(&data->wait_queue);
515}
516
517static void sht15_update_voltage(struct work_struct *work_s)
518{
519 struct sht15_data *data
520 = container_of(work_s, struct sht15_data,
521 update_supply_work);
522 data->supply_uV = regulator_get_voltage(data->reg);
523}
524
525/**
526 * sht15_invalidate_voltage() - mark supply voltage invalid when notified by reg
527 * @nb: associated notification structure
528 * @event: voltage regulator state change event code
529 * @ignored: function parameter - ignored here
530 *
531 * Note that as the notification code holds the regulator lock, we have
532 * to schedule an update of the supply voltage rather than getting it directly.
Vivien Didelot99a03782011-04-12 15:34:36 -0400533 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700534static int sht15_invalidate_voltage(struct notifier_block *nb,
Vivien Didelot99a03782011-04-12 15:34:36 -0400535 unsigned long event,
536 void *ignored)
Jonathan Cameron251eb402009-04-13 14:39:45 -0700537{
538 struct sht15_data *data = container_of(nb, struct sht15_data, nb);
539
540 if (event == REGULATOR_EVENT_VOLTAGE_CHANGE)
541 data->supply_uV_valid = false;
542 schedule_work(&data->update_supply_work);
543
544 return NOTIFY_OK;
545}
546
547static int __devinit sht15_probe(struct platform_device *pdev)
548{
549 int ret = 0;
550 struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
551
552 if (!data) {
553 ret = -ENOMEM;
Vivien Didelot99a03782011-04-12 15:34:36 -0400554 dev_err(&pdev->dev, "kzalloc failed\n");
Jonathan Cameron251eb402009-04-13 14:39:45 -0700555 goto error_ret;
556 }
557
558 INIT_WORK(&data->read_work, sht15_bh_read_data);
559 INIT_WORK(&data->update_supply_work, sht15_update_voltage);
560 platform_set_drvdata(pdev, data);
561 mutex_init(&data->read_lock);
562 data->dev = &pdev->dev;
563 init_waitqueue_head(&data->wait_queue);
564
565 if (pdev->dev.platform_data == NULL) {
Vivien Didelot99a03782011-04-12 15:34:36 -0400566 dev_err(&pdev->dev, "no platform data supplied\n");
Jonathan Cameron251eb402009-04-13 14:39:45 -0700567 goto err_free_data;
568 }
569 data->pdata = pdev->dev.platform_data;
Vivien Didelot99a03782011-04-12 15:34:36 -0400570 data->supply_uV = data->pdata->supply_mv * 1000;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700571
Vivien Didelot99a03782011-04-12 15:34:36 -0400572 /*
573 * If a regulator is available,
574 * query what the supply voltage actually is!
575 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700576 data->reg = regulator_get(data->dev, "vcc");
577 if (!IS_ERR(data->reg)) {
Jean Delvarec7a78d22010-04-14 16:14:08 +0200578 int voltage;
579
580 voltage = regulator_get_voltage(data->reg);
581 if (voltage)
582 data->supply_uV = voltage;
583
Jonathan Cameron251eb402009-04-13 14:39:45 -0700584 regulator_enable(data->reg);
Vivien Didelot99a03782011-04-12 15:34:36 -0400585 /*
586 * Setup a notifier block to update this if another device
587 * causes the voltage to change
588 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700589 data->nb.notifier_call = &sht15_invalidate_voltage;
590 ret = regulator_register_notifier(data->reg, &data->nb);
591 }
Vivien Didelot99a03782011-04-12 15:34:36 -0400592
593 /* Try requesting the GPIOs */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700594 ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck");
595 if (ret) {
Vivien Didelot99a03782011-04-12 15:34:36 -0400596 dev_err(&pdev->dev, "gpio request failed\n");
Jonathan Cameron251eb402009-04-13 14:39:45 -0700597 goto err_free_data;
598 }
599 gpio_direction_output(data->pdata->gpio_sck, 0);
Vivien Didelot99a03782011-04-12 15:34:36 -0400600
Jonathan Cameron251eb402009-04-13 14:39:45 -0700601 ret = gpio_request(data->pdata->gpio_data, "SHT15 data");
602 if (ret) {
Vivien Didelot99a03782011-04-12 15:34:36 -0400603 dev_err(&pdev->dev, "gpio request failed\n");
Jonathan Cameron251eb402009-04-13 14:39:45 -0700604 goto err_release_gpio_sck;
605 }
606 ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
607 if (ret) {
608 dev_err(&pdev->dev, "sysfs create failed");
Roel Kluin560a64a2009-09-21 17:04:48 -0700609 goto err_release_gpio_data;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700610 }
611
612 ret = request_irq(gpio_to_irq(data->pdata->gpio_data),
613 sht15_interrupt_fired,
614 IRQF_TRIGGER_FALLING,
615 "sht15 data",
616 data);
617 if (ret) {
Vivien Didelot99a03782011-04-12 15:34:36 -0400618 dev_err(&pdev->dev, "failed to get irq for data line\n");
Jonathan Cameron251eb402009-04-13 14:39:45 -0700619 goto err_release_gpio_data;
620 }
621 disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
622 sht15_connection_reset(data);
623 sht15_send_cmd(data, 0x1E);
624
625 data->hwmon_dev = hwmon_device_register(data->dev);
626 if (IS_ERR(data->hwmon_dev)) {
627 ret = PTR_ERR(data->hwmon_dev);
Roel Kluin560a64a2009-09-21 17:04:48 -0700628 goto err_release_irq;
Jonathan Cameron251eb402009-04-13 14:39:45 -0700629 }
Vivien Didelot99a03782011-04-12 15:34:36 -0400630
Jonathan Cameron251eb402009-04-13 14:39:45 -0700631 return 0;
632
Roel Kluin560a64a2009-09-21 17:04:48 -0700633err_release_irq:
634 free_irq(gpio_to_irq(data->pdata->gpio_data), data);
Jonathan Cameron251eb402009-04-13 14:39:45 -0700635err_release_gpio_data:
636 gpio_free(data->pdata->gpio_data);
637err_release_gpio_sck:
638 gpio_free(data->pdata->gpio_sck);
639err_free_data:
640 kfree(data);
641error_ret:
Jonathan Cameron251eb402009-04-13 14:39:45 -0700642 return ret;
643}
644
645static int __devexit sht15_remove(struct platform_device *pdev)
646{
647 struct sht15_data *data = platform_get_drvdata(pdev);
648
Vivien Didelot99a03782011-04-12 15:34:36 -0400649 /*
650 * Make sure any reads from the device are done and
651 * prevent new ones beginning
652 */
Jonathan Cameron251eb402009-04-13 14:39:45 -0700653 mutex_lock(&data->read_lock);
654 hwmon_device_unregister(data->hwmon_dev);
655 sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
656 if (!IS_ERR(data->reg)) {
657 regulator_unregister_notifier(data->reg, &data->nb);
658 regulator_disable(data->reg);
659 regulator_put(data->reg);
660 }
661
662 free_irq(gpio_to_irq(data->pdata->gpio_data), data);
663 gpio_free(data->pdata->gpio_data);
664 gpio_free(data->pdata->gpio_sck);
665 mutex_unlock(&data->read_lock);
666 kfree(data);
Vivien Didelot99a03782011-04-12 15:34:36 -0400667
Jonathan Cameron251eb402009-04-13 14:39:45 -0700668 return 0;
669}
670
Rakib Mullickcb0f1a12009-10-09 20:35:17 +0200671/*
672 * sht_drivers simultaneously refers to __devinit and __devexit function
673 * which causes spurious section mismatch warning. So use __refdata to
674 * get rid from this.
675 */
676static struct platform_driver __refdata sht_drivers[] = {
Jonathan Cameron251eb402009-04-13 14:39:45 -0700677 {
678 .driver = {
679 .name = "sht10",
680 .owner = THIS_MODULE,
681 },
682 .probe = sht15_probe,
Jean Delvarecd659fd2009-06-15 18:39:45 +0200683 .remove = __devexit_p(sht15_remove),
Jonathan Cameron251eb402009-04-13 14:39:45 -0700684 }, {
685 .driver = {
686 .name = "sht11",
687 .owner = THIS_MODULE,
688 },
689 .probe = sht15_probe,
Jean Delvarecd659fd2009-06-15 18:39:45 +0200690 .remove = __devexit_p(sht15_remove),
Jonathan Cameron251eb402009-04-13 14:39:45 -0700691 }, {
692 .driver = {
693 .name = "sht15",
694 .owner = THIS_MODULE,
695 },
696 .probe = sht15_probe,
Jean Delvarecd659fd2009-06-15 18:39:45 +0200697 .remove = __devexit_p(sht15_remove),
Jonathan Cameron251eb402009-04-13 14:39:45 -0700698 }, {
699 .driver = {
700 .name = "sht71",
701 .owner = THIS_MODULE,
702 },
703 .probe = sht15_probe,
Jean Delvarecd659fd2009-06-15 18:39:45 +0200704 .remove = __devexit_p(sht15_remove),
Jonathan Cameron251eb402009-04-13 14:39:45 -0700705 }, {
706 .driver = {
707 .name = "sht75",
708 .owner = THIS_MODULE,
709 },
710 .probe = sht15_probe,
Jean Delvarecd659fd2009-06-15 18:39:45 +0200711 .remove = __devexit_p(sht15_remove),
Jonathan Cameron251eb402009-04-13 14:39:45 -0700712 },
713};
714
Jonathan Cameron251eb402009-04-13 14:39:45 -0700715static int __init sht15_init(void)
716{
717 int ret;
718 int i;
719
720 for (i = 0; i < ARRAY_SIZE(sht_drivers); i++) {
721 ret = platform_driver_register(&sht_drivers[i]);
722 if (ret)
723 goto error_unreg;
724 }
725
726 return 0;
727
728error_unreg:
729 while (--i >= 0)
730 platform_driver_unregister(&sht_drivers[i]);
731
732 return ret;
733}
734module_init(sht15_init);
735
736static void __exit sht15_exit(void)
737{
738 int i;
739 for (i = ARRAY_SIZE(sht_drivers) - 1; i >= 0; i--)
740 platform_driver_unregister(&sht_drivers[i]);
741}
742module_exit(sht15_exit);
743
744MODULE_LICENSE("GPL");