diff options
author | Greg Meiste <w30289@motorola.com> | 2010-11-16 13:33:06 -0600 |
---|---|---|
committer | Todd Poynor <toddpoynor@google.com> | 2011-01-07 20:37:34 -0800 |
commit | 63b6d550a648b6eb2828221a58c00a1c8267ec13 (patch) | |
tree | d9cc481c6abf2e3ec8b0328bb77f6665dcf5db6c | |
parent | d38b03a9f6afe63986d61d0bc97d360fc7206444 (diff) |
misc: Initial NCT1008 driver
Initial version of the NCT1008 driver to turn off the sensor when the
device is suspended. This improves standby current drain.
Change-Id: Ia64613c33c0052434d5e304c434605611e5ef789
Signed-off-by: Greg Meiste <w30289@motorola.com>
-rw-r--r-- | drivers/misc/Kconfig | 8 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rwxr-xr-x | drivers/misc/nct1008.c | 139 | ||||
-rw-r--r-- | include/linux/nct1008.h | 54 |
4 files changed, 202 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b74331260744..aad1247743f7 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -321,6 +321,14 @@ config HMC6352 This driver provides support for the Honeywell HMC6352 compass, providing configuration and heading data via sysfs. +config SENSORS_NCT1008 + tristate "ON Semiconductor Temperature Sensor" + default n + depends on I2C + help + Say yes here if you wish to include the ON Semiconductor + NCT1008 Temperature sensor. + config EP93XX_PWM tristate "EP93xx PWM support" depends on ARCH_EP93XX diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95cde2a..51f2787d8d15 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -35,3 +35,4 @@ obj-y += eeprom/ obj-y += cb710/ obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o +obj-$(CONFIG_SENSORS_NCT1008) += nct1008.o diff --git a/drivers/misc/nct1008.c b/drivers/misc/nct1008.c new file mode 100755 index 000000000000..a29e984bc4c6 --- /dev/null +++ b/drivers/misc/nct1008.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2010 Motorola, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/nct1008.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/uaccess.h> + +#define NCT_BIT_CONFIG_RUN_STOP 6 + +struct nct1008_data { + struct i2c_client *client; +}; + +static uint32_t nct1008_debug; +module_param_named(temp_debug, nct1008_debug, uint, 0664); + +static int nct1008_run(struct nct1008_data *nct, u8 run) +{ + int err; + u8 rd_val; + u8 wr_val; + + rd_val = i2c_smbus_read_byte_data(nct->client, NCT_CONFIG_RD); + if (rd_val < 0) { + pr_err("%s: config register read fail: %d\n", __func__, rd_val); + return rd_val; + } + + if (nct1008_debug) + pr_info("%s: Previous config is 0x%02x\n", __func__, rd_val); + + if (run) + wr_val = rd_val & ~(1 << NCT_BIT_CONFIG_RUN_STOP); + else + wr_val = rd_val | (1 << NCT_BIT_CONFIG_RUN_STOP); + err = i2c_smbus_write_byte_data(nct->client, NCT_CONFIG_WR, wr_val); + if (err) + pr_err("%s: setting RUN/STOP failed: %d\n", __func__, err); + + return err; +} + +static int nct1008_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct nct1008_data *nct; + + nct = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL); + if (nct == NULL) + return -ENOMEM; + + nct->client = client; + i2c_set_clientdata(client, nct); + + return 0; +} + +static int nct1008_remove(struct i2c_client *client) +{ + struct nct1008_data *nct = i2c_get_clientdata(client); + + kfree(nct); + return 0; +} + +static int nct1008_suspend(struct i2c_client *client, pm_message_t mesg) +{ + struct nct1008_data *nct = i2c_get_clientdata(client); + + if (nct1008_debug) + pr_info("%s: Suspending\n", __func__); + + return nct1008_run(nct, 0); +} + +static int nct1008_resume(struct i2c_client *client) +{ + struct nct1008_data *nct = i2c_get_clientdata(client); + + if (nct1008_debug) + pr_info("%s: Resuming\n", __func__); + + return nct1008_run(nct, 1); +} + +static const struct i2c_device_id nct1008_id[] = { + {"nct1008", 0}, + {} +}; + +static struct i2c_driver nct1008_i2c_driver = { + .probe = nct1008_probe, + .remove = nct1008_remove, + .suspend = nct1008_suspend, + .resume = nct1008_resume, + .id_table = nct1008_id, + .driver = { + .name = "nct1008", + .owner = THIS_MODULE, + }, +}; + +static int __init nct1008_init(void) +{ + return i2c_add_driver(&nct1008_i2c_driver); +} + +static void __exit nct1008_exit(void) +{ + i2c_del_driver(&nct1008_i2c_driver); +} + +module_init(nct1008_init); +module_exit(nct1008_exit); + +MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008"); +MODULE_AUTHOR("Motorola"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/nct1008.h b/include/linux/nct1008.h new file mode 100644 index 000000000000..c6b396246659 --- /dev/null +++ b/include/linux/nct1008.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Motorola, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#ifndef _LINUX_NCT1008_H__ +#define _LINUX_NCT1008_H__ + +/* NCT1008 Read Only Registers */ +#define NCT_LOCAL_TEMP_RD 0x00 +#define NCT_EXT_TEMP_HIGH_RD 0x01 +#define NCT_EXT_TEMP_LOW_RD 0x10 +#define NCT_STATUS_RD 0x02 + +/* NCT1008 Control Registers */ +#define NCT_CONFIG_RD 0x03 +#define NCT_CONFIG_WR 0x09 +#define NCT_CONV_RATE_RD 0x04 +#define NCT_CONV_RATE_WR 0x0A + +/* NCT1008 Limit Registers */ +#define NCT_LOCAL_TEMP_HIGH_LIMIT_RD 0x05 +#define NCT_LOCAL_TEMP_LOW_LIMIT_RD 0x06 +#define NCT_LOCAL_TEMP_HIGH_LIMIT_WR 0x0B +#define NCT_LOCAL_TEMP_LOW_LIMIT_WR 0x0C + +#define NCT_EXT_TEMP_HIGH_LIMIT_HBYTE_RD 0x07 +#define NCT_EXT_TEMP_LOW_LIMIT_HBYTE_RD 0x08 +#define NCT_EXT_TEMP_HIGH_LIMIT_HBYTE_WR 0x0D +#define NCT_EXT_TEMP_LOW_LIMIT_HBYTE_WR 0x0E +#define NCT_EXT_TEMP_HIGH_LIMIT_LBYTE_RDWR 0x13 +#define NCT_EXT_TEMP_LOW_LIMIT_LBYTE_RDWR 0x14 +#define NCT_EXT_THERM_LIMIT 0x19 +#define NCT_LOCAL_THERM_LIMIT 0x20 + +#define NCT_EXT_TEMP_OFFSET_HIGH_RDWR 0x11 +#define NCT_EXT_TEMP_OFFSET_LOW_RDWR 0x12 +#define NCT_THERM_HYST 0x21 +#define NCT_CONSEC_ALERT 0x22 + +#endif /* _LINUX_NCT1008_H__ */ |