^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * lm70.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * The LM70 is a temperature sensor chip from National Semiconductor (NS).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * The LM70 communicates with a host processor via an SPI/Microwire Bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * interface. The complete datasheet is available at National's website
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * http://www.national.com/pf/LM/LM70.html
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DRVNAME "lm70"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define LM70_CHIP_LM70 0 /* original NS LM70 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define LM70_CHIP_TMP121 1 /* TI TMP121/TMP123 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define LM70_CHIP_LM71 2 /* NS LM71 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define LM70_CHIP_LM74 3 /* NS LM74 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define LM70_CHIP_TMP122 4 /* TI TMP122/TMP124 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct lm70 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct spi_device *spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* sysfs hook function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static ssize_t temp1_input_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct lm70 *p_lm70 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct spi_device *spi = p_lm70->spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int status, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 rxbuf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) s16 raw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (mutex_lock_interruptible(&p_lm70->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * spi_read() requires a DMA-safe buffer; so we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * spi_write_then_read(), transmitting 0 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_warn(dev, "spi_write_then_read failed with status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) raw = (rxbuf[0] << 8) + rxbuf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) dev_dbg(dev, "rxbuf[0] : 0x%02x rxbuf[1] : 0x%02x raw=0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) rxbuf[0], rxbuf[1], raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * LM70:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * complement value. Only the MSB 11 bits (1 sign + 10 temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * bits) are meaningful; the LSB 5 bits are to be discarded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * See the datasheet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Further, each bit represents 0.25 degrees Celsius; so, multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * by 0.25. Also multiply by 1000 to represent in millidegrees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Celsius.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * So it's equivalent to multiplying by 0.25 * 1000 = 250.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * LM74 and TMP121/TMP122/TMP123/TMP124:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * 13 bits of 2's complement data, discard LSB 3 bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * resolution 0.0625 degrees celsius.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * LM71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * 14 bits of 2's complement data, discard LSB 2 bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * resolution 0.0312 degrees celsius.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) switch (p_lm70->chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case LM70_CHIP_LM70:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) val = ((int)raw / 32) * 250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case LM70_CHIP_TMP121:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case LM70_CHIP_TMP122:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) case LM70_CHIP_LM74:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) val = ((int)raw / 8) * 625 / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) case LM70_CHIP_LM71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) val = ((int)raw / 4) * 3125 / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mutex_unlock(&p_lm70->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static DEVICE_ATTR_RO(temp1_input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static struct attribute *lm70_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) &dev_attr_temp1_input.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ATTRIBUTE_GROUPS(lm70);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*----------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static const struct of_device_id lm70_of_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .compatible = "ti,lm70",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .data = (void *) LM70_CHIP_LM70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .compatible = "ti,tmp121",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .data = (void *) LM70_CHIP_TMP121,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .compatible = "ti,tmp122",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .data = (void *) LM70_CHIP_TMP122,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .compatible = "ti,lm71",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .data = (void *) LM70_CHIP_LM71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .compatible = "ti,lm74",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .data = (void *) LM70_CHIP_LM74,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) MODULE_DEVICE_TABLE(of, lm70_of_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int lm70_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct lm70 *p_lm70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (dev_fwnode(&spi->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) chip = (int)(uintptr_t)device_get_match_data(&spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) chip = spi_get_device_id(spi)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* signaling is SPI_MODE_0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (spi->mode & (SPI_CPOL | SPI_CPHA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* NOTE: we assume 8-bit words, and convert to 16 bits manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) p_lm70 = devm_kzalloc(&spi->dev, sizeof(*p_lm70), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!p_lm70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mutex_init(&p_lm70->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) p_lm70->chip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) p_lm70->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) hwmon_dev = devm_hwmon_device_register_with_groups(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) spi->modalias,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) p_lm70, lm70_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static const struct spi_device_id lm70_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { "lm70", LM70_CHIP_LM70 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { "tmp121", LM70_CHIP_TMP121 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { "tmp122", LM70_CHIP_TMP122 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) { "lm71", LM70_CHIP_LM71 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { "lm74", LM70_CHIP_LM74 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) MODULE_DEVICE_TABLE(spi, lm70_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static struct spi_driver lm70_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .name = "lm70",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .of_match_table = of_match_ptr(lm70_of_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .id_table = lm70_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .probe = lm70_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) module_spi_driver(lm70_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) MODULE_AUTHOR("Kaiwan N Billimoria");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) MODULE_DESCRIPTION("NS LM70 and compatibles Linux driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) MODULE_LICENSE("GPL");