misc: Initial NCT1008 driver
authorGreg Meiste <w30289@motorola.com>
Tue, 16 Nov 2010 19:33:06 +0000 (13:33 -0600)
committerTodd Poynor <toddpoynor@google.com>
Sat, 20 Nov 2010 04:21:28 +0000 (20:21 -0800)
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>
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/nct1008.c [new file with mode: 0755]
include/linux/nct1008.h [new file with mode: 0644]

index bf519e85f045b78a44fd77b25eb0a04842ca0e5a..89fa7e153a6e8de75ea89c7a289fb455da5da8b9 100644 (file)
@@ -375,6 +375,14 @@ config SENSORS_MAX9635
         Say yes here if you wish to include the Maxim
         MAX9635 ambient light sensor driver.
 
+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 SENSORS_MOTO_BMP085
        tristate "BMP085 Barometer (moto driver)"
        default n
index 1cac581e592d954dae9450337f6ce638a94828b4..de167814b48afd560c8b68e20c0d4f6816ccab7d 100644 (file)
@@ -43,6 +43,7 @@ obj-$(CONFIG_APANIC)          += apanic.o
 obj-$(CONFIG_SENSORS_AK8975)   += akm8975.o
 obj-$(CONFIG_SENSORS_KXTF9)    += kxtf9.o
 obj-$(CONFIG_SENSORS_MAX9635)  += max9635.o
+obj-$(CONFIG_SENSORS_NCT1008)  += nct1008.o
 obj-$(CONFIG_SENSORS_L3G4200D) += l3g4200d.o
 obj-$(CONFIG_GPS_GPIO_BRCM4750)        += gps-gpio-brcm4750.o
 obj-$(CONFIG_MDM6600_CTRL)     += mdm6600_ctrl.o
diff --git a/drivers/misc/nct1008.c b/drivers/misc/nct1008.c
new file mode 100755 (executable)
index 0000000..a29e984
--- /dev/null
@@ -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 (file)
index 0000000..c6b3962
--- /dev/null
@@ -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__ */