brintos

brintos / linux-shallow public Read only

0
0
Text · 11.3 KiB · f800fe2 Raw
468 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * lm83.c - Part of lm_sensors, Linux kernel modules for hardware4 *          monitoring5 * Copyright (C) 2003-2009  Jean Delvare <jdelvare@suse.de>6 *7 * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is8 * a sensor chip made by National Semiconductor. It reports up to four9 * temperatures (its own plus up to three external ones) with a 1 deg10 * resolution and a 3-4 deg accuracy. Complete datasheet can be obtained11 * from National's website at:12 *   http://www.national.com/pf/LM/LM83.html13 * Since the datasheet omits to give the chip stepping code, I give it14 * here: 0x03 (at register 0xff).15 *16 * Also supports the LM82 temp sensor, which is basically a stripped down17 * model of the LM83.  Datasheet is here:18 * http://www.national.com/pf/LM/LM82.html19 */20 21#include <linux/bits.h>22#include <linux/err.h>23#include <linux/i2c.h>24#include <linux/init.h>25#include <linux/hwmon.h>26#include <linux/module.h>27#include <linux/regmap.h>28#include <linux/slab.h>29 30/*31 * Addresses to scan32 * Address is selected using 2 three-level pins, resulting in 9 possible33 * addresses.34 */35 36static const unsigned short normal_i2c[] = {37	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };38 39enum chips { lm83, lm82 };40 41/*42 * The LM83 registers43 * Manufacturer ID is 0x01 for National Semiconductor.44 */45 46#define LM83_REG_R_MAN_ID		0xFE47#define LM83_REG_R_CHIP_ID		0xFF48#define LM83_REG_R_CONFIG		0x0349#define LM83_REG_W_CONFIG		0x0950#define LM83_REG_R_STATUS1		0x0251#define LM83_REG_R_STATUS2		0x3552#define LM83_REG_R_LOCAL_TEMP		0x0053#define LM83_REG_R_LOCAL_HIGH		0x0554#define LM83_REG_W_LOCAL_HIGH		0x0B55#define LM83_REG_R_REMOTE1_TEMP		0x3056#define LM83_REG_R_REMOTE1_HIGH		0x3857#define LM83_REG_W_REMOTE1_HIGH		0x5058#define LM83_REG_R_REMOTE2_TEMP		0x0159#define LM83_REG_R_REMOTE2_HIGH		0x0760#define LM83_REG_W_REMOTE2_HIGH		0x0D61#define LM83_REG_R_REMOTE3_TEMP		0x3162#define LM83_REG_R_REMOTE3_HIGH		0x3A63#define LM83_REG_W_REMOTE3_HIGH		0x5264#define LM83_REG_R_TCRIT		0x4265#define LM83_REG_W_TCRIT		0x5A66 67static const u8 LM83_REG_TEMP[] = {68	LM83_REG_R_LOCAL_TEMP,69	LM83_REG_R_REMOTE1_TEMP,70	LM83_REG_R_REMOTE2_TEMP,71	LM83_REG_R_REMOTE3_TEMP,72};73 74static const u8 LM83_REG_MAX[] = {75	LM83_REG_R_LOCAL_HIGH,76	LM83_REG_R_REMOTE1_HIGH,77	LM83_REG_R_REMOTE2_HIGH,78	LM83_REG_R_REMOTE3_HIGH,79};80 81/* alarm and fault registers and bits, indexed by channel */82static const u8 LM83_ALARM_REG[] = {83	LM83_REG_R_STATUS1, LM83_REG_R_STATUS2, LM83_REG_R_STATUS1, LM83_REG_R_STATUS284};85 86static const u8 LM83_MAX_ALARM_BIT[] = {87	BIT(6), BIT(7), BIT(4), BIT(4)88};89 90static const u8 LM83_CRIT_ALARM_BIT[] = {91	BIT(0), BIT(0), BIT(1), BIT(1)92};93 94static const u8 LM83_FAULT_BIT[] = {95	0, BIT(5), BIT(2), BIT(2)96};97 98/*99 * Client data (each client gets its own)100 */101 102struct lm83_data {103	struct regmap *regmap;104	enum chips type;105};106 107/* regmap code */108 109static int lm83_regmap_reg_read(void *context, unsigned int reg, unsigned int *val)110{111	struct i2c_client *client = context;112	int ret;113 114	ret = i2c_smbus_read_byte_data(client, reg);115	if (ret < 0)116		return ret;117 118	*val = ret;119	return 0;120}121 122/*123 * The regmap write function maps read register addresses to write register124 * addresses. This is necessary for regmap register caching to work.125 * An alternative would be to clear the regmap cache whenever a register is126 * written, but that would be much more expensive.127 */128static int lm83_regmap_reg_write(void *context, unsigned int reg, unsigned int val)129{130	struct i2c_client *client = context;131 132	switch (reg) {133	case LM83_REG_R_CONFIG:134	case LM83_REG_R_LOCAL_HIGH:135	case LM83_REG_R_REMOTE2_HIGH:136		reg += 0x06;137		break;138	case LM83_REG_R_REMOTE1_HIGH:139	case LM83_REG_R_REMOTE3_HIGH:140	case LM83_REG_R_TCRIT:141		reg += 0x18;142		break;143	default:144		break;145	}146 147	return i2c_smbus_write_byte_data(client, reg, val);148}149 150static bool lm83_regmap_is_volatile(struct device *dev, unsigned int reg)151{152	switch (reg) {153	case LM83_REG_R_LOCAL_TEMP:154	case LM83_REG_R_REMOTE1_TEMP:155	case LM83_REG_R_REMOTE2_TEMP:156	case LM83_REG_R_REMOTE3_TEMP:157	case LM83_REG_R_STATUS1:158	case LM83_REG_R_STATUS2:159		return true;160	default:161		return false;162	}163}164 165static const struct regmap_config lm83_regmap_config = {166	.reg_bits = 8,167	.val_bits = 8,168	.cache_type = REGCACHE_MAPLE,169	.volatile_reg = lm83_regmap_is_volatile,170	.reg_read = lm83_regmap_reg_read,171	.reg_write = lm83_regmap_reg_write,172};173 174/* hwmon API */175 176static int lm83_temp_read(struct device *dev, u32 attr, int channel, long *val)177{178	struct lm83_data *data = dev_get_drvdata(dev);179	unsigned int regval;180	int err;181 182	switch (attr) {183	case hwmon_temp_input:184		err = regmap_read(data->regmap, LM83_REG_TEMP[channel], &regval);185		if (err < 0)186			return err;187		*val = (s8)regval * 1000;188		break;189	case hwmon_temp_max:190		err = regmap_read(data->regmap, LM83_REG_MAX[channel], &regval);191		if (err < 0)192			return err;193		*val = (s8)regval * 1000;194		break;195	case hwmon_temp_crit:196		err = regmap_read(data->regmap, LM83_REG_R_TCRIT, &regval);197		if (err < 0)198			return err;199		*val = (s8)regval * 1000;200		break;201	case hwmon_temp_max_alarm:202		err = regmap_read(data->regmap, LM83_ALARM_REG[channel], &regval);203		if (err < 0)204			return err;205		*val = !!(regval & LM83_MAX_ALARM_BIT[channel]);206		break;207	case hwmon_temp_crit_alarm:208		err = regmap_read(data->regmap, LM83_ALARM_REG[channel], &regval);209		if (err < 0)210			return err;211		*val = !!(regval & LM83_CRIT_ALARM_BIT[channel]);212		break;213	case hwmon_temp_fault:214		err = regmap_read(data->regmap, LM83_ALARM_REG[channel], &regval);215		if (err < 0)216			return err;217		*val = !!(regval & LM83_FAULT_BIT[channel]);218		break;219	default:220		return -EOPNOTSUPP;221	}222	return 0;223}224 225static int lm83_temp_write(struct device *dev, u32 attr, int channel, long val)226{227	struct lm83_data *data = dev_get_drvdata(dev);228	unsigned int regval;229	int err;230 231	regval = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000);232 233	switch (attr) {234	case hwmon_temp_max:235		err = regmap_write(data->regmap, LM83_REG_MAX[channel], regval);236		if (err < 0)237			return err;238		break;239	case hwmon_temp_crit:240		err = regmap_write(data->regmap, LM83_REG_R_TCRIT, regval);241		if (err < 0)242			return err;243		break;244	default:245		return -EOPNOTSUPP;246	}247	return 0;248}249 250static int lm83_chip_read(struct device *dev, u32 attr, int channel, long *val)251{252	struct lm83_data *data = dev_get_drvdata(dev);253	unsigned int regval;254	int err;255 256	switch (attr) {257	case hwmon_chip_alarms:258		err = regmap_read(data->regmap, LM83_REG_R_STATUS1, &regval);259		if (err < 0)260			return err;261		*val = regval;262		err = regmap_read(data->regmap, LM83_REG_R_STATUS2, &regval);263		if (err < 0)264			return err;265		*val |= regval << 8;266		return 0;267	default:268		return -EOPNOTSUPP;269	}270 271	return 0;272}273 274static int lm83_read(struct device *dev, enum hwmon_sensor_types type,275		     u32 attr, int channel, long *val)276{277	switch (type) {278	case hwmon_chip:279		return lm83_chip_read(dev, attr, channel, val);280	case hwmon_temp:281		return lm83_temp_read(dev, attr, channel, val);282	default:283		return -EOPNOTSUPP;284	}285}286 287static int lm83_write(struct device *dev, enum hwmon_sensor_types type,288		      u32 attr, int channel, long val)289{290	switch (type) {291	case hwmon_temp:292		return lm83_temp_write(dev, attr, channel, val);293	default:294		return -EOPNOTSUPP;295	}296}297 298static umode_t lm83_is_visible(const void *_data, enum hwmon_sensor_types type,299			       u32 attr, int channel)300{301	const struct lm83_data *data = _data;302 303	/*304	 * LM82 only supports a single external channel, modeled as channel 2.305	 */306	if (data->type == lm82 && (channel == 1 || channel == 3))307		return 0;308 309	switch (type) {310	case hwmon_chip:311		if (attr == hwmon_chip_alarms)312			return 0444;313		break;314	case hwmon_temp:315		switch (attr) {316		case hwmon_temp_input:317		case hwmon_temp_max_alarm:318		case hwmon_temp_crit_alarm:319			return 0444;320		case hwmon_temp_fault:321			if (channel)322				return 0444;323			break;324		case hwmon_temp_max:325			return 0644;326		case hwmon_temp_crit:327			if (channel == 2)328				return 0644;329			return 0444;330		default:331			break;332		}333		break;334	default:335		break;336	}337	return 0;338}339 340static const struct hwmon_channel_info * const lm83_info[] = {341	HWMON_CHANNEL_INFO(chip, HWMON_C_ALARMS),342	HWMON_CHANNEL_INFO(temp,343			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |344			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,345			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |346			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,347			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |348			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,349			   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |350			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT351			   ),352	NULL353};354 355static const struct hwmon_ops lm83_hwmon_ops = {356	.is_visible = lm83_is_visible,357	.read = lm83_read,358	.write = lm83_write,359};360 361static const struct hwmon_chip_info lm83_chip_info = {362	.ops = &lm83_hwmon_ops,363	.info = lm83_info,364};365 366/* Return 0 if detection is successful, -ENODEV otherwise */367static int lm83_detect(struct i2c_client *client,368		       struct i2c_board_info *info)369{370	struct i2c_adapter *adapter = client->adapter;371	const char *name;372	u8 man_id, chip_id;373 374	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))375		return -ENODEV;376 377	/* Detection */378	if ((i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) & 0xA8) ||379	    (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) & 0x48) ||380	    (i2c_smbus_read_byte_data(client, LM83_REG_R_CONFIG) & 0x41)) {381		dev_dbg(&adapter->dev, "LM83 detection failed at 0x%02x\n",382			client->addr);383		return -ENODEV;384	}385 386	/* Identification */387	man_id = i2c_smbus_read_byte_data(client, LM83_REG_R_MAN_ID);388	if (man_id != 0x01)	/* National Semiconductor */389		return -ENODEV;390 391	chip_id = i2c_smbus_read_byte_data(client, LM83_REG_R_CHIP_ID);392	switch (chip_id) {393	case 0x03:394		/*395		 * According to the LM82 datasheet dated March 2013, recent396		 * revisions of LM82 have a die revision of 0x03. This was397		 * confirmed with a real chip. Further details in this revision398		 * of the LM82 datasheet strongly suggest that LM82 is just a399		 * repackaged LM83. It is therefore impossible to distinguish400		 * those chips from LM83, and they will be misdetected as LM83.401		 */402		name = "lm83";403		break;404	case 0x01:405		name = "lm82";406		break;407	default:408		/* identification failed */409		dev_dbg(&adapter->dev,410			"Unsupported chip (man_id=0x%02X, chip_id=0x%02X)\n",411			man_id, chip_id);412		return -ENODEV;413	}414 415	strscpy(info->type, name, I2C_NAME_SIZE);416 417	return 0;418}419 420static int lm83_probe(struct i2c_client *client)421{422	struct device *dev = &client->dev;423	struct device *hwmon_dev;424	struct lm83_data *data;425 426	data = devm_kzalloc(dev, sizeof(struct lm83_data), GFP_KERNEL);427	if (!data)428		return -ENOMEM;429 430	data->regmap = devm_regmap_init(dev, NULL, client, &lm83_regmap_config);431	if (IS_ERR(data->regmap))432		return PTR_ERR(data->regmap);433 434	data->type = (uintptr_t)i2c_get_match_data(client);435 436	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,437							 data, &lm83_chip_info, NULL);438	return PTR_ERR_OR_ZERO(hwmon_dev);439}440 441/*442 * Driver data (common to all clients)443 */444 445static const struct i2c_device_id lm83_id[] = {446	{ "lm83", lm83 },447	{ "lm82", lm82 },448	{ }449};450MODULE_DEVICE_TABLE(i2c, lm83_id);451 452static struct i2c_driver lm83_driver = {453	.class		= I2C_CLASS_HWMON,454	.driver = {455		.name	= "lm83",456	},457	.probe		= lm83_probe,458	.id_table	= lm83_id,459	.detect		= lm83_detect,460	.address_list	= normal_i2c,461};462 463module_i2c_driver(lm83_driver);464 465MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");466MODULE_DESCRIPTION("LM83 driver");467MODULE_LICENSE("GPL");468