tmp103.c (5216B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Texas Instruments TMP103 SMBus temperature sensor driver 4 * Copyright (C) 2014 Heiko Schocher <hs@denx.de> 5 * 6 * Based on: 7 * Texas Instruments TMP102 SMBus temperature sensor driver 8 * 9 * Copyright (C) 2010 Steven King <sfking@fdwdc.com> 10 */ 11 12#include <linux/module.h> 13#include <linux/init.h> 14#include <linux/slab.h> 15#include <linux/i2c.h> 16#include <linux/hwmon.h> 17#include <linux/hwmon-sysfs.h> 18#include <linux/err.h> 19#include <linux/mutex.h> 20#include <linux/device.h> 21#include <linux/jiffies.h> 22#include <linux/regmap.h> 23 24#define TMP103_TEMP_REG 0x00 25#define TMP103_CONF_REG 0x01 26#define TMP103_TLOW_REG 0x02 27#define TMP103_THIGH_REG 0x03 28 29#define TMP103_CONF_M0 0x01 30#define TMP103_CONF_M1 0x02 31#define TMP103_CONF_LC 0x04 32#define TMP103_CONF_FL 0x08 33#define TMP103_CONF_FH 0x10 34#define TMP103_CONF_CR0 0x20 35#define TMP103_CONF_CR1 0x40 36#define TMP103_CONF_ID 0x80 37#define TMP103_CONF_SD (TMP103_CONF_M1) 38#define TMP103_CONF_SD_MASK (TMP103_CONF_M0 | TMP103_CONF_M1) 39 40#define TMP103_CONFIG (TMP103_CONF_CR1 | TMP103_CONF_M1) 41#define TMP103_CONFIG_MASK (TMP103_CONF_CR0 | TMP103_CONF_CR1 | \ 42 TMP103_CONF_M0 | TMP103_CONF_M1) 43 44static inline int tmp103_reg_to_mc(s8 val) 45{ 46 return val * 1000; 47} 48 49static inline u8 tmp103_mc_to_reg(int val) 50{ 51 return DIV_ROUND_CLOSEST(val, 1000); 52} 53 54static int tmp103_read(struct device *dev, enum hwmon_sensor_types type, 55 u32 attr, int channel, long *temp) 56{ 57 struct regmap *regmap = dev_get_drvdata(dev); 58 unsigned int regval; 59 int err, reg; 60 61 switch (attr) { 62 case hwmon_temp_input: 63 reg = TMP103_TEMP_REG; 64 break; 65 case hwmon_temp_min: 66 reg = TMP103_TLOW_REG; 67 break; 68 case hwmon_temp_max: 69 reg = TMP103_THIGH_REG; 70 break; 71 default: 72 return -EOPNOTSUPP; 73 } 74 75 err = regmap_read(regmap, reg, ®val); 76 if (err < 0) 77 return err; 78 79 *temp = tmp103_reg_to_mc(regval); 80 81 return 0; 82} 83 84static int tmp103_write(struct device *dev, enum hwmon_sensor_types type, 85 u32 attr, int channel, long temp) 86{ 87 struct regmap *regmap = dev_get_drvdata(dev); 88 int reg; 89 90 switch (attr) { 91 case hwmon_temp_min: 92 reg = TMP103_TLOW_REG; 93 break; 94 case hwmon_temp_max: 95 reg = TMP103_THIGH_REG; 96 break; 97 default: 98 return -EOPNOTSUPP; 99 } 100 101 temp = clamp_val(temp, -55000, 127000); 102 return regmap_write(regmap, reg, tmp103_mc_to_reg(temp)); 103} 104 105static umode_t tmp103_is_visible(const void *data, enum hwmon_sensor_types type, 106 u32 attr, int channel) 107{ 108 if (type != hwmon_temp) 109 return 0; 110 111 switch (attr) { 112 case hwmon_temp_input: 113 return 0444; 114 case hwmon_temp_min: 115 case hwmon_temp_max: 116 return 0644; 117 default: 118 return 0; 119 } 120} 121 122static const struct hwmon_channel_info *tmp103_info[] = { 123 HWMON_CHANNEL_INFO(chip, 124 HWMON_C_REGISTER_TZ), 125 HWMON_CHANNEL_INFO(temp, 126 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN), 127 NULL 128}; 129 130static const struct hwmon_ops tmp103_hwmon_ops = { 131 .is_visible = tmp103_is_visible, 132 .read = tmp103_read, 133 .write = tmp103_write, 134}; 135 136static const struct hwmon_chip_info tmp103_chip_info = { 137 .ops = &tmp103_hwmon_ops, 138 .info = tmp103_info, 139}; 140 141static bool tmp103_regmap_is_volatile(struct device *dev, unsigned int reg) 142{ 143 return reg == TMP103_TEMP_REG; 144} 145 146static const struct regmap_config tmp103_regmap_config = { 147 .reg_bits = 8, 148 .val_bits = 8, 149 .max_register = TMP103_THIGH_REG, 150 .volatile_reg = tmp103_regmap_is_volatile, 151}; 152 153static int tmp103_probe(struct i2c_client *client) 154{ 155 struct device *dev = &client->dev; 156 struct device *hwmon_dev; 157 struct regmap *regmap; 158 int ret; 159 160 regmap = devm_regmap_init_i2c(client, &tmp103_regmap_config); 161 if (IS_ERR(regmap)) { 162 dev_err(dev, "failed to allocate register map\n"); 163 return PTR_ERR(regmap); 164 } 165 166 ret = regmap_update_bits(regmap, TMP103_CONF_REG, TMP103_CONFIG_MASK, 167 TMP103_CONFIG); 168 if (ret < 0) { 169 dev_err(&client->dev, "error writing config register\n"); 170 return ret; 171 } 172 173 i2c_set_clientdata(client, regmap); 174 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 175 regmap, 176 &tmp103_chip_info, 177 NULL); 178 return PTR_ERR_OR_ZERO(hwmon_dev); 179} 180 181static int __maybe_unused tmp103_suspend(struct device *dev) 182{ 183 struct regmap *regmap = dev_get_drvdata(dev); 184 185 return regmap_update_bits(regmap, TMP103_CONF_REG, 186 TMP103_CONF_SD_MASK, 0); 187} 188 189static int __maybe_unused tmp103_resume(struct device *dev) 190{ 191 struct regmap *regmap = dev_get_drvdata(dev); 192 193 return regmap_update_bits(regmap, TMP103_CONF_REG, 194 TMP103_CONF_SD_MASK, TMP103_CONF_SD); 195} 196 197static SIMPLE_DEV_PM_OPS(tmp103_dev_pm_ops, tmp103_suspend, tmp103_resume); 198 199static const struct i2c_device_id tmp103_id[] = { 200 { "tmp103", 0 }, 201 { } 202}; 203MODULE_DEVICE_TABLE(i2c, tmp103_id); 204 205static const struct of_device_id __maybe_unused tmp103_of_match[] = { 206 { .compatible = "ti,tmp103" }, 207 { }, 208}; 209MODULE_DEVICE_TABLE(of, tmp103_of_match); 210 211static struct i2c_driver tmp103_driver = { 212 .driver = { 213 .name = "tmp103", 214 .of_match_table = of_match_ptr(tmp103_of_match), 215 .pm = &tmp103_dev_pm_ops, 216 }, 217 .probe_new = tmp103_probe, 218 .id_table = tmp103_id, 219}; 220 221module_i2c_driver(tmp103_driver); 222 223MODULE_AUTHOR("Heiko Schocher <hs@denx.de>"); 224MODULE_DESCRIPTION("Texas Instruments TMP103 temperature sensor driver"); 225MODULE_LICENSE("GPL");