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