brintos

brintos / linux-shallow public Read only

0
0
Text · 14.5 KiB · 3bdc305 Raw
591 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2011 Alexander Stein <alexander.stein@systec-electronic.com>4 *5 * The LM95245 is a sensor chip made by TI / National Semiconductor.6 * It reports up to two temperatures (its own plus an external one).7 *8 * This driver is based on lm95241.c9 */10 11#include <linux/err.h>12#include <linux/init.h>13#include <linux/hwmon.h>14#include <linux/i2c.h>15#include <linux/module.h>16#include <linux/mutex.h>17#include <linux/regmap.h>18#include <linux/slab.h>19 20static const unsigned short normal_i2c[] = {21	0x18, 0x19, 0x29, 0x4c, 0x4d, I2C_CLIENT_END };22 23/* LM95245 registers */24/* general registers */25#define LM95245_REG_RW_CONFIG1		0x0326#define LM95245_REG_RW_CONVERS_RATE	0x0427#define LM95245_REG_W_ONE_SHOT		0x0F28 29/* diode configuration */30#define LM95245_REG_RW_CONFIG2		0xBF31#define LM95245_REG_RW_REMOTE_OFFH	0x1132#define LM95245_REG_RW_REMOTE_OFFL	0x1233 34/* status registers */35#define LM95245_REG_R_STATUS1		0x0236#define LM95245_REG_R_STATUS2		0x3337 38/* limit registers */39#define LM95245_REG_RW_REMOTE_OS_LIMIT		0x0740#define LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT	0x2041#define LM95245_REG_RW_REMOTE_TCRIT_LIMIT	0x1942#define LM95245_REG_RW_COMMON_HYSTERESIS	0x2143 44/* temperature signed */45#define LM95245_REG_R_LOCAL_TEMPH_S	0x0046#define LM95245_REG_R_LOCAL_TEMPL_S	0x3047#define LM95245_REG_R_REMOTE_TEMPH_S	0x0148#define LM95245_REG_R_REMOTE_TEMPL_S	0x1049/* temperature unsigned */50#define LM95245_REG_R_REMOTE_TEMPH_U	0x3151#define LM95245_REG_R_REMOTE_TEMPL_U	0x3252 53/* id registers */54#define LM95245_REG_R_MAN_ID		0xFE55#define LM95245_REG_R_CHIP_ID		0xFF56 57/* LM95245 specific bitfields */58#define CFG_STOP		0x4059#define CFG_REMOTE_TCRIT_MASK	0x1060#define CFG_REMOTE_OS_MASK	0x0861#define CFG_LOCAL_TCRIT_MASK	0x0462#define CFG_LOCAL_OS_MASK	0x0263 64#define CFG2_OS_A0		0x4065#define CFG2_DIODE_FAULT_OS	0x2066#define CFG2_DIODE_FAULT_TCRIT	0x1067#define CFG2_REMOTE_TT		0x0868#define CFG2_REMOTE_FILTER_DIS	0x0069#define CFG2_REMOTE_FILTER_EN	0x0670 71/* conversation rate in ms */72#define RATE_CR0063	0x0073#define RATE_CR0364	0x0174#define RATE_CR1000	0x0275#define RATE_CR2500	0x0376 77#define STATUS1_ROS		0x1078#define STATUS1_DIODE_FAULT	0x0479#define STATUS1_RTCRIT		0x0280#define STATUS1_LOC		0x0181 82#define MANUFACTURER_ID		0x0183#define LM95235_REVISION	0xB184#define LM95245_REVISION	0xB385 86/* Client data (each client gets its own) */87struct lm95245_data {88	struct regmap *regmap;89	struct mutex update_lock;90	int interval;	/* in msecs */91};92 93/* Conversions */94static int temp_from_reg_unsigned(u8 val_h, u8 val_l)95{96	return val_h * 1000 + val_l * 1000 / 256;97}98 99static int temp_from_reg_signed(u8 val_h, u8 val_l)100{101	if (val_h & 0x80)102		return (val_h - 0x100) * 1000;103	return temp_from_reg_unsigned(val_h, val_l);104}105 106static int lm95245_read_conversion_rate(struct lm95245_data *data)107{108	unsigned int rate;109	int ret;110 111	ret = regmap_read(data->regmap, LM95245_REG_RW_CONVERS_RATE, &rate);112	if (ret < 0)113		return ret;114 115	switch (rate) {116	case RATE_CR0063:117		data->interval = 63;118		break;119	case RATE_CR0364:120		data->interval = 364;121		break;122	case RATE_CR1000:123		data->interval = 1000;124		break;125	case RATE_CR2500:126	default:127		data->interval = 2500;128		break;129	}130	return 0;131}132 133static int lm95245_set_conversion_rate(struct lm95245_data *data, long interval)134{135	int ret, rate;136 137	if (interval <= 63) {138		interval = 63;139		rate = RATE_CR0063;140	} else if (interval <= 364) {141		interval = 364;142		rate = RATE_CR0364;143	} else if (interval <= 1000) {144		interval = 1000;145		rate = RATE_CR1000;146	} else {147		interval = 2500;148		rate = RATE_CR2500;149	}150 151	ret = regmap_write(data->regmap, LM95245_REG_RW_CONVERS_RATE, rate);152	if (ret < 0)153		return ret;154 155	data->interval = interval;156	return 0;157}158 159static int lm95245_read_temp(struct device *dev, u32 attr, int channel,160			     long *val)161{162	struct lm95245_data *data = dev_get_drvdata(dev);163	struct regmap *regmap = data->regmap;164	unsigned int regs[2];165	unsigned int regval;166	u8 regvals[2];167	int ret;168 169	switch (attr) {170	case hwmon_temp_input:171		regs[0] = channel ? LM95245_REG_R_REMOTE_TEMPL_S :172				    LM95245_REG_R_LOCAL_TEMPL_S;173		regs[1] = channel ? LM95245_REG_R_REMOTE_TEMPH_S :174				    LM95245_REG_R_LOCAL_TEMPH_S;175		ret = regmap_multi_reg_read(regmap, regs, regvals, 2);176		if (ret < 0)177			return ret;178		/*179		 * Local temp is always signed.180		 * Remote temp has both signed and unsigned data.181		 * Use signed calculation for remote if signed bit is set182		 * or if reported temperature is below signed limit.183		 */184		if (!channel || (regvals[1] & 0x80) || regvals[1] < 0x7f) {185			*val = temp_from_reg_signed(regvals[1], regvals[0]);186			return 0;187		}188		ret = regmap_bulk_read(regmap, LM95245_REG_R_REMOTE_TEMPH_U, regvals, 2);189		if (ret)190			return ret;191		*val = temp_from_reg_unsigned(regvals[0], regvals[1]);192		return 0;193	case hwmon_temp_max:194		ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OS_LIMIT,195				  &regval);196		if (ret < 0)197			return ret;198		*val = regval * 1000;199		return 0;200	case hwmon_temp_crit:201		regs[0] = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT :202				    LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT;203		ret = regmap_read(regmap, regs[0], &regval);204		if (ret < 0)205			return ret;206		*val = regval * 1000;207		return 0;208	case hwmon_temp_max_hyst:209		regs[0] = LM95245_REG_RW_REMOTE_OS_LIMIT;210		regs[1] = LM95245_REG_RW_COMMON_HYSTERESIS;211		ret = regmap_multi_reg_read(regmap, regs, regvals, 2);212		if (ret < 0)213			return ret;214		*val = (regvals[0] - regvals[1]) * 1000;215		return 0;216	case hwmon_temp_crit_hyst:217		regs[0] = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT :218				    LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT;219		regs[1] = LM95245_REG_RW_COMMON_HYSTERESIS;220 221		ret = regmap_multi_reg_read(regmap, regs, regvals, 2);222		if (ret < 0)223			return ret;224		*val = (regvals[0] - regvals[1]) * 1000;225		return 0;226	case hwmon_temp_type:227		ret = regmap_read(regmap, LM95245_REG_RW_CONFIG2, &regval);228		if (ret < 0)229			return ret;230		*val = (regval & CFG2_REMOTE_TT) ? 1 : 2;231		return 0;232	case hwmon_temp_offset:233		ret = regmap_bulk_read(regmap, LM95245_REG_RW_REMOTE_OFFH, regvals, 2);234		if (ret < 0)235			return ret;236		*val = temp_from_reg_signed(regvals[0], regvals[1]);237		return 0;238	case hwmon_temp_max_alarm:239		ret = regmap_read(regmap, LM95245_REG_R_STATUS1, &regval);240		if (ret < 0)241			return ret;242		*val = !!(regval & STATUS1_ROS);243		return 0;244	case hwmon_temp_crit_alarm:245		ret = regmap_read(regmap, LM95245_REG_R_STATUS1, &regval);246		if (ret < 0)247			return ret;248		*val = !!(regval & (channel ? STATUS1_RTCRIT : STATUS1_LOC));249		return 0;250	case hwmon_temp_fault:251		ret = regmap_read(regmap, LM95245_REG_R_STATUS1, &regval);252		if (ret < 0)253			return ret;254		*val = !!(regval & STATUS1_DIODE_FAULT);255		return 0;256	default:257		return -EOPNOTSUPP;258	}259}260 261static int lm95245_write_temp(struct device *dev, u32 attr, int channel,262			      long val)263{264	struct lm95245_data *data = dev_get_drvdata(dev);265	struct regmap *regmap = data->regmap;266	unsigned int regval;267	u8 regvals[2];268	int ret, reg;269 270	switch (attr) {271	case hwmon_temp_max:272		val = clamp_val(val / 1000, 0, 255);273		ret = regmap_write(regmap, LM95245_REG_RW_REMOTE_OS_LIMIT, val);274		return ret;275	case hwmon_temp_crit:276		reg = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT :277				LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT;278		val = clamp_val(val / 1000, 0, channel ? 255 : 127);279		ret = regmap_write(regmap, reg, val);280		return ret;281	case hwmon_temp_crit_hyst:282		mutex_lock(&data->update_lock);283		ret = regmap_read(regmap, LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT,284				  &regval);285		if (ret < 0) {286			mutex_unlock(&data->update_lock);287			return ret;288		}289		/* Clamp to reasonable range to prevent overflow */290		val = clamp_val(val, -1000000, 1000000);291		val = regval - val / 1000;292		val = clamp_val(val, 0, 31);293		ret = regmap_write(regmap, LM95245_REG_RW_COMMON_HYSTERESIS,294				   val);295		mutex_unlock(&data->update_lock);296		return ret;297	case hwmon_temp_offset:298		val = clamp_val(val, -128000, 127875);299		val = val * 256 / 1000;300		regvals[0] = val >> 8;301		regvals[1] = val & 0xe0;302 303		ret = regmap_bulk_write(regmap, LM95245_REG_RW_REMOTE_OFFH, regvals, 2);304		return ret;305	case hwmon_temp_type:306		if (val != 1 && val != 2)307			return -EINVAL;308		ret = regmap_update_bits(regmap, LM95245_REG_RW_CONFIG2,309					 CFG2_REMOTE_TT,310					 val == 1 ? CFG2_REMOTE_TT : 0);311		return ret;312	default:313		return -EOPNOTSUPP;314	}315}316 317static int lm95245_read_chip(struct device *dev, u32 attr, int channel,318			     long *val)319{320	struct lm95245_data *data = dev_get_drvdata(dev);321 322	switch (attr) {323	case hwmon_chip_update_interval:324		*val = data->interval;325		return 0;326	default:327		return -EOPNOTSUPP;328	}329}330 331static int lm95245_write_chip(struct device *dev, u32 attr, int channel,332			      long val)333{334	struct lm95245_data *data = dev_get_drvdata(dev);335	int ret;336 337	switch (attr) {338	case hwmon_chip_update_interval:339		mutex_lock(&data->update_lock);340		ret = lm95245_set_conversion_rate(data, val);341		mutex_unlock(&data->update_lock);342		return ret;343	default:344		return -EOPNOTSUPP;345	}346}347 348static int lm95245_read(struct device *dev, enum hwmon_sensor_types type,349			u32 attr, int channel, long *val)350{351	switch (type) {352	case hwmon_chip:353		return lm95245_read_chip(dev, attr, channel, val);354	case hwmon_temp:355		return lm95245_read_temp(dev, attr, channel, val);356	default:357		return -EOPNOTSUPP;358	}359}360 361static int lm95245_write(struct device *dev, enum hwmon_sensor_types type,362			 u32 attr, int channel, long val)363{364	switch (type) {365	case hwmon_chip:366		return lm95245_write_chip(dev, attr, channel, val);367	case hwmon_temp:368		return lm95245_write_temp(dev, attr, channel, val);369	default:370		return -EOPNOTSUPP;371	}372}373 374static umode_t lm95245_temp_is_visible(const void *data, u32 attr, int channel)375{376	switch (attr) {377	case hwmon_temp_input:378	case hwmon_temp_max_alarm:379	case hwmon_temp_max_hyst:380	case hwmon_temp_crit_alarm:381	case hwmon_temp_fault:382		return 0444;383	case hwmon_temp_type:384	case hwmon_temp_max:385	case hwmon_temp_crit:386	case hwmon_temp_offset:387		return 0644;388	case hwmon_temp_crit_hyst:389		return (channel == 0) ? 0644 : 0444;390	default:391		return 0;392	}393}394 395static umode_t lm95245_is_visible(const void *data,396				  enum hwmon_sensor_types type,397				  u32 attr, int channel)398{399	switch (type) {400	case hwmon_chip:401		switch (attr) {402		case hwmon_chip_update_interval:403			return 0644;404		default:405			return 0;406		}407	case hwmon_temp:408		return lm95245_temp_is_visible(data, attr, channel);409	default:410		return 0;411	}412}413 414/* Return 0 if detection is successful, -ENODEV otherwise */415static int lm95245_detect(struct i2c_client *new_client,416			  struct i2c_board_info *info)417{418	struct i2c_adapter *adapter = new_client->adapter;419	int address = new_client->addr;420	const char *name;421	int rev, id;422 423	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))424		return -ENODEV;425 426	id = i2c_smbus_read_byte_data(new_client, LM95245_REG_R_MAN_ID);427	if (id != MANUFACTURER_ID)428		return -ENODEV;429 430	rev = i2c_smbus_read_byte_data(new_client, LM95245_REG_R_CHIP_ID);431	switch (rev) {432	case LM95235_REVISION:433		if (address != 0x18 && address != 0x29 && address != 0x4c)434			return -ENODEV;435		name = "lm95235";436		break;437	case LM95245_REVISION:438		name = "lm95245";439		break;440	default:441		return -ENODEV;442	}443 444	strscpy(info->type, name, I2C_NAME_SIZE);445	return 0;446}447 448static int lm95245_init_client(struct lm95245_data *data)449{450	int ret;451 452	ret = lm95245_read_conversion_rate(data);453	if (ret < 0)454		return ret;455 456	return regmap_update_bits(data->regmap, LM95245_REG_RW_CONFIG1,457				  CFG_STOP, 0);458}459 460static bool lm95245_is_writeable_reg(struct device *dev, unsigned int reg)461{462	switch (reg) {463	case LM95245_REG_RW_CONFIG1:464	case LM95245_REG_RW_CONVERS_RATE:465	case LM95245_REG_W_ONE_SHOT:466	case LM95245_REG_RW_CONFIG2:467	case LM95245_REG_RW_REMOTE_OFFH:468	case LM95245_REG_RW_REMOTE_OFFL:469	case LM95245_REG_RW_REMOTE_OS_LIMIT:470	case LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT:471	case LM95245_REG_RW_REMOTE_TCRIT_LIMIT:472	case LM95245_REG_RW_COMMON_HYSTERESIS:473		return true;474	default:475		return false;476	}477}478 479static bool lm95245_is_volatile_reg(struct device *dev, unsigned int reg)480{481	switch (reg) {482	case LM95245_REG_R_STATUS1:483	case LM95245_REG_R_STATUS2:484	case LM95245_REG_R_LOCAL_TEMPH_S:485	case LM95245_REG_R_LOCAL_TEMPL_S:486	case LM95245_REG_R_REMOTE_TEMPH_S:487	case LM95245_REG_R_REMOTE_TEMPL_S:488	case LM95245_REG_R_REMOTE_TEMPH_U:489	case LM95245_REG_R_REMOTE_TEMPL_U:490		return true;491	default:492		return false;493	}494}495 496static const struct regmap_config lm95245_regmap_config = {497	.reg_bits = 8,498	.val_bits = 8,499	.writeable_reg = lm95245_is_writeable_reg,500	.volatile_reg = lm95245_is_volatile_reg,501	.cache_type = REGCACHE_MAPLE,502	.use_single_read = true,503	.use_single_write = true,504};505 506static const struct hwmon_channel_info * const lm95245_info[] = {507	HWMON_CHANNEL_INFO(chip,508			   HWMON_C_UPDATE_INTERVAL),509	HWMON_CHANNEL_INFO(temp,510			   HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_HYST |511			   HWMON_T_CRIT_ALARM,512			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |513			   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_FAULT |514			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |515			   HWMON_T_TYPE | HWMON_T_OFFSET),516	NULL517};518 519static const struct hwmon_ops lm95245_hwmon_ops = {520	.is_visible = lm95245_is_visible,521	.read = lm95245_read,522	.write = lm95245_write,523};524 525static const struct hwmon_chip_info lm95245_chip_info = {526	.ops = &lm95245_hwmon_ops,527	.info = lm95245_info,528};529 530static int lm95245_probe(struct i2c_client *client)531{532	struct device *dev = &client->dev;533	struct lm95245_data *data;534	struct device *hwmon_dev;535	int ret;536 537	data = devm_kzalloc(dev, sizeof(struct lm95245_data), GFP_KERNEL);538	if (!data)539		return -ENOMEM;540 541	data->regmap = devm_regmap_init_i2c(client, &lm95245_regmap_config);542	if (IS_ERR(data->regmap))543		return PTR_ERR(data->regmap);544 545	mutex_init(&data->update_lock);546 547	/* Initialize the LM95245 chip */548	ret = lm95245_init_client(data);549	if (ret < 0)550		return ret;551 552	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,553							 data,554							 &lm95245_chip_info,555							 NULL);556	return PTR_ERR_OR_ZERO(hwmon_dev);557}558 559/* Driver data (common to all clients) */560static const struct i2c_device_id lm95245_id[] = {561	{ "lm95235" },562	{ "lm95245" },563	{ }564};565MODULE_DEVICE_TABLE(i2c, lm95245_id);566 567static const struct of_device_id __maybe_unused lm95245_of_match[] = {568	{ .compatible = "national,lm95235" },569	{ .compatible = "national,lm95245" },570	{ },571};572MODULE_DEVICE_TABLE(of, lm95245_of_match);573 574static struct i2c_driver lm95245_driver = {575	.class		= I2C_CLASS_HWMON,576	.driver = {577		.name	= "lm95245",578		.of_match_table = of_match_ptr(lm95245_of_match),579	},580	.probe		= lm95245_probe,581	.id_table	= lm95245_id,582	.detect		= lm95245_detect,583	.address_list	= normal_i2c,584};585 586module_i2c_driver(lm95245_driver);587 588MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>");589MODULE_DESCRIPTION("LM95235/LM95245 sensor driver");590MODULE_LICENSE("GPL");591