aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/lm708
-rw-r--r--drivers/hwmon/Kconfig5
-rw-r--r--drivers/hwmon/lm70.c84
3 files changed, 84 insertions, 13 deletions
diff --git a/Documentation/hwmon/lm70 b/Documentation/hwmon/lm70
index b8d1a521e689..0d240291e3cc 100644
--- a/Documentation/hwmon/lm70
+++ b/Documentation/hwmon/lm70
@@ -1,9 +1,11 @@
1Kernel driver lm70 1Kernel driver lm70
2================== 2==================
3 3
4Supported chip: 4Supported chips:
5 * National Semiconductor LM70 5 * National Semiconductor LM70
6 Datasheet: http://www.national.com/pf/LM/LM70.html 6 Datasheet: http://www.national.com/pf/LM/LM70.html
7 * Texas Instruments TMP121/TMP123
8 Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html
7 9
8Author: 10Author:
9 Kaiwan N Billimoria <kaiwan@designergraphix.com> 11 Kaiwan N Billimoria <kaiwan@designergraphix.com>
@@ -29,6 +31,10 @@ As a real (in-tree) example of this "SPI protocol driver" interfacing
29with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c 31with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
30and its associated documentation. 32and its associated documentation.
31 33
34The TMP121/TMP123 are very similar; main differences are 4 wire SPI inter-
35face (read only) and 13-bit temperature data (0.0625 degrees celsius reso-
36lution).
37
32Thanks to 38Thanks to
33--------- 39---------
34Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver 40Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 3c34fb5e4194..4b33bc82cc24 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -428,11 +428,12 @@ config SENSORS_LM63
428 will be called lm63. 428 will be called lm63.
429 429
430config SENSORS_LM70 430config SENSORS_LM70
431 tristate "National Semiconductor LM70" 431 tristate "National Semiconductor LM70 / Texas Instruments TMP121"
432 depends on SPI_MASTER && EXPERIMENTAL 432 depends on SPI_MASTER && EXPERIMENTAL
433 help 433 help
434 If you say yes here you get support for the National Semiconductor 434 If you say yes here you get support for the National Semiconductor
435 LM70 digital temperature sensor chip. 435 LM70 and Texas Instruments TMP121/TMP123 digital temperature
436 sensor chips.
436 437
437 This driver can also be built as a module. If so, the module 438 This driver can also be built as a module. If so, the module
438 will be called lm70. 439 will be called lm70.
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index 9f9741b1d2b5..ae6204f33214 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -37,9 +37,13 @@
37 37
38#define DRVNAME "lm70" 38#define DRVNAME "lm70"
39 39
40#define LM70_CHIP_LM70 0 /* original NS LM70 */
41#define LM70_CHIP_TMP121 1 /* TI TMP121/TMP123 */
42
40struct lm70 { 43struct lm70 {
41 struct device *hwmon_dev; 44 struct device *hwmon_dev;
42 struct mutex lock; 45 struct mutex lock;
46 unsigned int chip;
43}; 47};
44 48
45/* sysfs hook function */ 49/* sysfs hook function */
@@ -47,7 +51,7 @@ static ssize_t lm70_sense_temp(struct device *dev,
47 struct device_attribute *attr, char *buf) 51 struct device_attribute *attr, char *buf)
48{ 52{
49 struct spi_device *spi = to_spi_device(dev); 53 struct spi_device *spi = to_spi_device(dev);
50 int status, val; 54 int status, val = 0;
51 u8 rxbuf[2]; 55 u8 rxbuf[2];
52 s16 raw=0; 56 s16 raw=0;
53 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); 57 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
@@ -70,6 +74,7 @@ static ssize_t lm70_sense_temp(struct device *dev,
70 rxbuf[0], rxbuf[1], raw); 74 rxbuf[0], rxbuf[1], raw);
71 75
72 /* 76 /*
77 * LM70:
73 * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's 78 * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's
74 * complement value. Only the MSB 11 bits (1 sign + 10 temperature 79 * complement value. Only the MSB 11 bits (1 sign + 10 temperature
75 * bits) are meaningful; the LSB 5 bits are to be discarded. 80 * bits) are meaningful; the LSB 5 bits are to be discarded.
@@ -79,8 +84,21 @@ static ssize_t lm70_sense_temp(struct device *dev,
79 * by 0.25. Also multiply by 1000 to represent in millidegrees 84 * by 0.25. Also multiply by 1000 to represent in millidegrees
80 * Celsius. 85 * Celsius.
81 * So it's equivalent to multiplying by 0.25 * 1000 = 250. 86 * So it's equivalent to multiplying by 0.25 * 1000 = 250.
87 *
88 * TMP121/TMP123:
89 * 13 bits of 2's complement data, discard LSB 3 bits,
90 * resolution 0.0625 degrees celsius.
82 */ 91 */
83 val = ((int)raw/32) * 250; 92 switch (p_lm70->chip) {
93 case LM70_CHIP_LM70:
94 val = ((int)raw / 32) * 250;
95 break;
96
97 case LM70_CHIP_TMP121:
98 val = ((int)raw / 8) * 625 / 10;
99 break;
100 }
101
84 status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ 102 status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
85out: 103out:
86 mutex_unlock(&p_lm70->lock); 104 mutex_unlock(&p_lm70->lock);
@@ -92,22 +110,31 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL);
92static ssize_t lm70_show_name(struct device *dev, struct device_attribute 110static ssize_t lm70_show_name(struct device *dev, struct device_attribute
93 *devattr, char *buf) 111 *devattr, char *buf)
94{ 112{
95 return sprintf(buf, "lm70\n"); 113 struct lm70 *p_lm70 = dev_get_drvdata(dev);
114 int ret;
115
116 switch (p_lm70->chip) {
117 case LM70_CHIP_LM70:
118 ret = sprintf(buf, "lm70\n");
119 break;
120 case LM70_CHIP_TMP121:
121 ret = sprintf(buf, "tmp121\n");
122 break;
123 default:
124 ret = -EINVAL;
125 }
126 return ret;
96} 127}
97 128
98static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL); 129static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL);
99 130
100/*----------------------------------------------------------------------*/ 131/*----------------------------------------------------------------------*/
101 132
102static int __devinit lm70_probe(struct spi_device *spi) 133static int __devinit common_probe(struct spi_device *spi, int chip)
103{ 134{
104 struct lm70 *p_lm70; 135 struct lm70 *p_lm70;
105 int status; 136 int status;
106 137
107 /* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */
108 if ((spi->mode & (SPI_CPOL|SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
109 return -EINVAL;
110
111 /* NOTE: we assume 8-bit words, and convert to 16 bits manually */ 138 /* NOTE: we assume 8-bit words, and convert to 16 bits manually */
112 139
113 p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL); 140 p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
@@ -115,6 +142,7 @@ static int __devinit lm70_probe(struct spi_device *spi)
115 return -ENOMEM; 142 return -ENOMEM;
116 143
117 mutex_init(&p_lm70->lock); 144 mutex_init(&p_lm70->lock);
145 p_lm70->chip = chip;
118 146
119 /* sysfs hook */ 147 /* sysfs hook */
120 p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); 148 p_lm70->hwmon_dev = hwmon_device_register(&spi->dev);
@@ -142,6 +170,24 @@ out_dev_reg_failed:
142 return status; 170 return status;
143} 171}
144 172
173static int __devinit lm70_probe(struct spi_device *spi)
174{
175 /* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */
176 if ((spi->mode & (SPI_CPOL | SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
177 return -EINVAL;
178
179 return common_probe(spi, LM70_CHIP_LM70);
180}
181
182static int __devinit tmp121_probe(struct spi_device *spi)
183{
184 /* signaling is SPI_MODE_0 with only MISO connected */
185 if (spi->mode & (SPI_CPOL | SPI_CPHA))
186 return -EINVAL;
187
188 return common_probe(spi, LM70_CHIP_TMP121);
189}
190
145static int __devexit lm70_remove(struct spi_device *spi) 191static int __devexit lm70_remove(struct spi_device *spi)
146{ 192{
147 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); 193 struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
@@ -155,6 +201,15 @@ static int __devexit lm70_remove(struct spi_device *spi)
155 return 0; 201 return 0;
156} 202}
157 203
204static struct spi_driver tmp121_driver = {
205 .driver = {
206 .name = "tmp121",
207 .owner = THIS_MODULE,
208 },
209 .probe = tmp121_probe,
210 .remove = __devexit_p(lm70_remove),
211};
212
158static struct spi_driver lm70_driver = { 213static struct spi_driver lm70_driver = {
159 .driver = { 214 .driver = {
160 .name = "lm70", 215 .name = "lm70",
@@ -166,17 +221,26 @@ static struct spi_driver lm70_driver = {
166 221
167static int __init init_lm70(void) 222static int __init init_lm70(void)
168{ 223{
169 return spi_register_driver(&lm70_driver); 224 int ret = spi_register_driver(&lm70_driver);
225 if (ret)
226 return ret;
227
228 ret = spi_register_driver(&tmp121_driver);
229 if (ret)
230 spi_unregister_driver(&lm70_driver);
231
232 return ret;
170} 233}
171 234
172static void __exit cleanup_lm70(void) 235static void __exit cleanup_lm70(void)
173{ 236{
174 spi_unregister_driver(&lm70_driver); 237 spi_unregister_driver(&lm70_driver);
238 spi_unregister_driver(&tmp121_driver);
175} 239}
176 240
177module_init(init_lm70); 241module_init(init_lm70);
178module_exit(cleanup_lm70); 242module_exit(cleanup_lm70);
179 243
180MODULE_AUTHOR("Kaiwan N Billimoria"); 244MODULE_AUTHOR("Kaiwan N Billimoria");
181MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver"); 245MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
182MODULE_LICENSE("GPL"); 246MODULE_LICENSE("GPL");