brintos

brintos / linux-shallow public Read only

0
0
Text · 17.1 KiB · eca3322 Raw
727 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * emc1403.c - SMSC Thermal Driver4 *5 * Copyright (C) 2008 Intel Corp6 *7 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~8 *9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~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/sysfs.h>20#include <linux/mutex.h>21#include <linux/regmap.h>22#include <linux/util_macros.h>23 24#define THERMAL_PID_REG		0xfd25#define THERMAL_SMSC_ID_REG	0xfe26#define THERMAL_REVISION_REG	0xff27 28enum emc1403_chip { emc1402, emc1403, emc1404, emc1428 };29 30struct thermal_data {31	enum emc1403_chip chip;32	struct regmap *regmap;33	struct mutex mutex;34};35 36static ssize_t power_state_show(struct device *dev, struct device_attribute *attr, char *buf)37{38	struct thermal_data *data = dev_get_drvdata(dev);39	unsigned int val;40	int retval;41 42	retval = regmap_read(data->regmap, 0x03, &val);43	if (retval < 0)44		return retval;45	return sprintf(buf, "%d\n", !!(val & BIT(6)));46}47 48static ssize_t power_state_store(struct device *dev, struct device_attribute *attr,49				 const char *buf, size_t count)50{51	struct thermal_data *data = dev_get_drvdata(dev);52	unsigned long val;53	int retval;54 55	if (kstrtoul(buf, 10, &val))56		return -EINVAL;57 58	retval = regmap_update_bits(data->regmap, 0x03, BIT(6),59				    val ? BIT(6) : 0);60	if (retval < 0)61		return retval;62	return count;63}64 65static DEVICE_ATTR_RW(power_state);66 67static struct attribute *emc1403_attrs[] = {68	&dev_attr_power_state.attr,69	NULL70};71ATTRIBUTE_GROUPS(emc1403);72 73static int emc1403_detect(struct i2c_client *client,74			struct i2c_board_info *info)75{76	int id;77	/* Check if thermal chip is SMSC and EMC1403 or EMC1423 */78 79	id = i2c_smbus_read_byte_data(client, THERMAL_SMSC_ID_REG);80	if (id != 0x5d)81		return -ENODEV;82 83	id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG);84	switch (id) {85	case 0x20:86		strscpy(info->type, "emc1402", I2C_NAME_SIZE);87		break;88	case 0x21:89		strscpy(info->type, "emc1403", I2C_NAME_SIZE);90		break;91	case 0x22:92		strscpy(info->type, "emc1422", I2C_NAME_SIZE);93		break;94	case 0x23:95		strscpy(info->type, "emc1423", I2C_NAME_SIZE);96		break;97	case 0x25:98		strscpy(info->type, "emc1404", I2C_NAME_SIZE);99		break;100	case 0x27:101		strscpy(info->type, "emc1424", I2C_NAME_SIZE);102		break;103	case 0x29:104		strscpy(info->type, "emc1428", I2C_NAME_SIZE);105		break;106	case 0x59:107		strscpy(info->type, "emc1438", I2C_NAME_SIZE);108		break;109	case 0x60:110		strscpy(info->type, "emc1442", I2C_NAME_SIZE);111		break;112	default:113		return -ENODEV;114	}115 116	id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG);117	if (id < 0x01 || id > 0x04)118		return -ENODEV;119 120	return 0;121}122 123static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg)124{125	switch (reg) {126	case 0x00:	/* internal diode high byte */127	case 0x01:	/* external diode 1 high byte */128	case 0x02:	/* status */129	case 0x10:	/* external diode 1 low byte */130	case 0x1b:	/* external diode fault */131	case 0x23:	/* external diode 2 high byte */132	case 0x24:	/* external diode 2 low byte */133	case 0x29:	/* internal diode low byte */134	case 0x2a:	/* externl diode 3 high byte */135	case 0x2b:	/* external diode 3 low byte */136	case 0x35:	/* high limit status */137	case 0x36:	/* low limit status */138	case 0x37:	/* therm limit status */139	case 0x41:	/* external diode 4 high byte */140	case 0x42:	/* external diode 4 low byte */141	case 0x43:	/* external diode 5 high byte */142	case 0x44:	/* external diode 5 low byte */143	case 0x45:	/* external diode 6 high byte */144	case 0x46:	/* external diode 6 low byte */145	case 0x47:	/* external diode 7 high byte */146	case 0x48:	/* external diode 7 low byte */147		return true;148	default:149		return false;150	}151}152 153static const struct regmap_config emc1403_regmap_config = {154	.reg_bits = 8,155	.val_bits = 8,156	.cache_type = REGCACHE_MAPLE,157	.volatile_reg = emc1403_regmap_is_volatile,158};159 160enum emc1403_reg_map {temp_min, temp_max, temp_crit, temp_input};161 162static u8 ema1403_temp_map[] = {163	[hwmon_temp_min] = temp_min,164	[hwmon_temp_max] = temp_max,165	[hwmon_temp_crit] = temp_crit,166	[hwmon_temp_input] = temp_input,167};168 169static u8 emc1403_temp_regs[][4] = {170	[0] = {171		[temp_min] = 0x06,172		[temp_max] = 0x05,173		[temp_crit] = 0x20,174		[temp_input] = 0x00,175	},176	[1] = {177		[temp_min] = 0x08,178		[temp_max] = 0x07,179		[temp_crit] = 0x19,180		[temp_input] = 0x01,181	},182	[2] = {183		[temp_min] = 0x16,184		[temp_max] = 0x15,185		[temp_crit] = 0x1a,186		[temp_input] = 0x23,187	},188	[3] = {189		[temp_min] = 0x2d,190		[temp_max] = 0x2c,191		[temp_crit] = 0x30,192		[temp_input] = 0x2a,193	},194	[4] = {195		[temp_min] = 0x51,196		[temp_max] = 0x50,197		[temp_crit] = 0x64,198		[temp_input] = 0x41,199	},200	[5] = {201		[temp_min] = 0x55,202		[temp_max] = 0x54,203		[temp_crit] = 0x65,204		[temp_input] = 0x43205	},206	[6] = {207		[temp_min] = 0x59,208		[temp_max] = 0x58,209		[temp_crit] = 0x66,210		[temp_input] = 0x45,211	},212	[7] = {213		[temp_min] = 0x5d,214		[temp_max] = 0x5c,215		[temp_crit] = 0x67,216		[temp_input] = 0x47,217	},218};219 220static s8 emc1403_temp_regs_low[][4] = {221	[0] = {222		[temp_min] = -1,223		[temp_max] = -1,224		[temp_crit] = -1,225		[temp_input] = 0x29,226	},227	[1] = {228		[temp_min] = 0x14,229		[temp_max] = 0x13,230		[temp_crit] = -1,231		[temp_input] = 0x10,232	},233	[2] = {234		[temp_min] = 0x18,235		[temp_max] = 0x17,236		[temp_crit] = -1,237		[temp_input] = 0x24,238	},239	[3] = {240		[temp_min] = 0x2f,241		[temp_max] = 0x2e,242		[temp_crit] = -1,243		[temp_input] = 0x2b,244	},245	[4] = {246		[temp_min] = 0x53,247		[temp_max] = 0x52,248		[temp_crit] = -1,249		[temp_input] = 0x42,250	},251	[5] = {252		[temp_min] = 0x57,253		[temp_max] = 0x56,254		[temp_crit] = -1,255		[temp_input] = 0x44,256	},257	[6] = {258		[temp_min] = 0x5b,259		[temp_max] = 0x5a,260		[temp_crit] = -1,261		[temp_input] = 0x46,262	},263	[7] = {264		[temp_min] = 0x5f,265		[temp_max] = 0x5e,266		[temp_crit] = -1,267		[temp_input] = 0x48,268	},269};270 271static int __emc1403_get_temp(struct thermal_data *data, int channel,272			      enum emc1403_reg_map map, long *val)273{274	unsigned int regvalh;275	unsigned int regvall = 0;276	int ret;277	s8 reg;278 279	ret = regmap_read(data->regmap, emc1403_temp_regs[channel][map], &regvalh);280	if (ret < 0)281		return ret;282 283	reg = emc1403_temp_regs_low[channel][map];284	if (reg >= 0) {285		ret = regmap_read(data->regmap, reg, &regvall);286		if (ret < 0)287			return ret;288	}289 290	if (data->chip == emc1428)291		*val = sign_extend32((regvalh << 3) | (regvall >> 5), 10) * 125;292	else293		*val = ((regvalh << 3) | (regvall >> 5)) * 125;294 295	return 0;296}297 298static int emc1403_get_temp(struct thermal_data *data, int channel,299			    enum emc1403_reg_map map, long *val)300{301	int ret;302 303	mutex_lock(&data->mutex);304	ret = __emc1403_get_temp(data, channel, map, val);305	mutex_unlock(&data->mutex);306 307	return ret;308}309 310static int emc1403_get_hyst(struct thermal_data *data, int channel,311			    enum emc1403_reg_map map, long *val)312{313	int hyst, ret;314	long limit;315 316	mutex_lock(&data->mutex);317	ret = __emc1403_get_temp(data, channel, map, &limit);318	if (ret < 0)319		goto unlock;320	ret = regmap_read(data->regmap, 0x21, &hyst);321	if (ret < 0)322		goto unlock;323	if (map == temp_min)324		*val = limit + hyst * 1000;325	else326		*val = limit - hyst * 1000;327unlock:328	mutex_unlock(&data->mutex);329	return ret;330}331 332static int emc1403_temp_read(struct thermal_data *data, u32 attr, int channel, long *val)333{334	unsigned int regval;335	int ret;336 337	switch (attr) {338	case hwmon_temp_min:339	case hwmon_temp_max:340	case hwmon_temp_crit:341	case hwmon_temp_input:342		ret = emc1403_get_temp(data, channel, ema1403_temp_map[attr], val);343		break;344	case hwmon_temp_min_hyst:345		ret = emc1403_get_hyst(data, channel, temp_min, val);346		break;347	case hwmon_temp_max_hyst:348		ret = emc1403_get_hyst(data, channel, temp_max, val);349		break;350	case hwmon_temp_crit_hyst:351		ret = emc1403_get_hyst(data, channel, temp_crit, val);352		break;353	case hwmon_temp_min_alarm:354		if (data->chip == emc1402) {355			ret = regmap_read(data->regmap, 0x02, &regval);356			if (ret < 0)357				break;358			*val = !!(regval & BIT(5 - 2 * channel));359		} else {360			ret = regmap_read(data->regmap, 0x36, &regval);361			if (ret < 0)362				break;363			*val = !!(regval & BIT(channel));364		}365		break;366	case hwmon_temp_max_alarm:367		if (data->chip == emc1402) {368			ret = regmap_read(data->regmap, 0x02, &regval);369			if (ret < 0)370				break;371			*val = !!(regval & BIT(6 - 2 * channel));372		} else {373			ret = regmap_read(data->regmap, 0x35, &regval);374			if (ret < 0)375				break;376			*val = !!(regval & BIT(channel));377		}378		break;379	case hwmon_temp_crit_alarm:380		if (data->chip == emc1402) {381			ret = regmap_read(data->regmap, 0x02, &regval);382			if (ret < 0)383				break;384			*val = !!(regval & BIT(channel));385		} else {386			ret = regmap_read(data->regmap, 0x37, &regval);387			if (ret < 0)388				break;389			*val = !!(regval & BIT(channel));390		}391		break;392	case hwmon_temp_fault:393		ret = regmap_read(data->regmap, 0x1b, &regval);394		if (ret < 0)395			break;396		*val = !!(regval & BIT(channel));397		break;398	default:399		return -EOPNOTSUPP;400	}401	return ret;402}403 404static int emc1403_get_convrate(struct thermal_data *data, long *val)405{406	unsigned int convrate;407	int ret;408 409	ret = regmap_read(data->regmap, 0x04, &convrate);410	if (ret < 0)411		return ret;412	if (convrate > 10)413		convrate = 4;414 415	*val = 16000 >> convrate;416	return 0;417}418 419static int emc1403_chip_read(struct thermal_data *data, u32 attr, long *val)420{421	switch (attr) {422	case hwmon_chip_update_interval:423		return emc1403_get_convrate(data, val);424	default:425		return -EOPNOTSUPP;426	}427}428 429static int emc1403_read(struct device *dev, enum hwmon_sensor_types type,430			u32 attr, int channel, long *val)431{432	struct thermal_data *data = dev_get_drvdata(dev);433 434	switch (type) {435	case hwmon_temp:436		return emc1403_temp_read(data, attr, channel, val);437	case hwmon_chip:438		return emc1403_chip_read(data, attr, val);439	default:440		return -EOPNOTSUPP;441	}442}443 444static int emc1403_set_hyst(struct thermal_data *data, long val)445{446	int hyst, ret;447	long limit;448 449	if (data->chip == emc1428)450		val = clamp_val(val, -128000, 127000);451	else452		val = clamp_val(val, 0, 255000);453 454	mutex_lock(&data->mutex);455	ret = __emc1403_get_temp(data, 0, temp_crit, &limit);456	if (ret < 0)457		goto unlock;458 459	hyst = limit - val;460	if (data->chip == emc1428)461		hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 127);462	else463		hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 255);464	ret = regmap_write(data->regmap, 0x21, hyst);465unlock:466	mutex_unlock(&data->mutex);467	return ret;468}469 470static int emc1403_set_temp(struct thermal_data *data, int channel,471			    enum emc1403_reg_map map, long val)472{473	unsigned int regval;474	int ret;475	u8 regh;476	s8 regl;477 478	regh = emc1403_temp_regs[channel][map];479	regl = emc1403_temp_regs_low[channel][map];480 481	mutex_lock(&data->mutex);482	if (regl >= 0) {483		if (data->chip == emc1428)484			val = clamp_val(val, -128000, 127875);485		else486			val = clamp_val(val, 0, 255875);487		regval = DIV_ROUND_CLOSEST(val, 125);488		ret = regmap_write(data->regmap, regh, (regval >> 3) & 0xff);489		if (ret < 0)490			goto unlock;491		ret = regmap_write(data->regmap, regl, (regval & 0x07) << 5);492	} else {493		if (data->chip == emc1428)494			val = clamp_val(val, -128000, 127000);495		else496			val = clamp_val(val, 0, 255000);497		regval = DIV_ROUND_CLOSEST(val, 1000);498		ret = regmap_write(data->regmap, regh, regval);499	}500unlock:501	mutex_unlock(&data->mutex);502	return ret;503}504 505static int emc1403_temp_write(struct thermal_data *data, u32 attr, int channel, long val)506{507	switch (attr) {508	case hwmon_temp_min:509	case hwmon_temp_max:510	case hwmon_temp_crit:511		return emc1403_set_temp(data, channel, ema1403_temp_map[attr], val);512	case hwmon_temp_crit_hyst:513		return emc1403_set_hyst(data, val);514	default:515		return -EOPNOTSUPP;516	}517}518 519/* Lookup table for temperature conversion times in msec */520static const u16 ina3221_conv_time[] = {521	16000, 8000, 4000, 2000, 1000, 500, 250, 125, 62, 31, 16522};523 524static int emc1403_set_convrate(struct thermal_data *data, unsigned int interval)525{526	int convrate;527 528	convrate = find_closest_descending(interval, ina3221_conv_time,529					   ARRAY_SIZE(ina3221_conv_time));530	return regmap_write(data->regmap, 0x04, convrate);531}532 533static int emc1403_chip_write(struct thermal_data *data, u32 attr, long val)534{535	switch (attr) {536	case hwmon_chip_update_interval:537		return emc1403_set_convrate(data, clamp_val(val, 0, 100000));538	default:539		return -EOPNOTSUPP;540	}541}542 543static int emc1403_write(struct device *dev, enum hwmon_sensor_types type,544			 u32 attr, int channel, long val)545{546	struct thermal_data *data = dev_get_drvdata(dev);547 548	switch (type) {549	case hwmon_temp:550		return emc1403_temp_write(data, attr, channel, val);551	case hwmon_chip:552		return emc1403_chip_write(data, attr, val);553	default:554		return -EOPNOTSUPP;555	}556}557 558static umode_t emc1403_temp_is_visible(const void *_data, u32 attr, int channel)559{560	const struct thermal_data *data = _data;561 562	if (data->chip == emc1402 && channel > 1)563		return 0;564	if (data->chip == emc1403 && channel > 2)565		return 0;566	if (data->chip != emc1428 && channel > 3)567		return 0;568 569	switch (attr) {570	case hwmon_temp_input:571	case hwmon_temp_min_alarm:572	case hwmon_temp_max_alarm:573	case hwmon_temp_crit_alarm:574	case hwmon_temp_fault:575	case hwmon_temp_min_hyst:576	case hwmon_temp_max_hyst:577		return 0444;578	case hwmon_temp_min:579	case hwmon_temp_max:580	case hwmon_temp_crit:581		return 0644;582	case hwmon_temp_crit_hyst:583		if (channel == 0)584			return 0644;585		return 0444;586	default:587		return 0;588	}589}590 591static umode_t emc1403_chip_is_visible(const void *_data, u32 attr)592{593	switch (attr) {594	case hwmon_chip_update_interval:595		return 0644;596	default:597		return 0;598	}599}600 601static umode_t emc1403_is_visible(const void *data, enum hwmon_sensor_types type,602				  u32 attr, int channel)603{604	switch (type) {605	case hwmon_temp:606		return emc1403_temp_is_visible(data, attr, channel);607	case hwmon_chip:608		return emc1403_chip_is_visible(data, attr);609	default:610		return 0;611	}612}613 614static const struct hwmon_channel_info * const emc1403_info[] = {615	HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),616	HWMON_CHANNEL_INFO(temp,617			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |618			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |619			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |620			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,621			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |622			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |623			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |624			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,625			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |626			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |627			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |628			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,629			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |630			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |631			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |632			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,633			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |634			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |635			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |636			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,637			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |638			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |639			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |640			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,641			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |642			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |643			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |644			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,645			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |646			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |647			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |648			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT649			   ),650	NULL651};652 653static const struct hwmon_ops emc1403_hwmon_ops = {654	.is_visible = emc1403_is_visible,655	.read = emc1403_read,656	.write = emc1403_write,657};658 659static const struct hwmon_chip_info emc1403_chip_info = {660	.ops = &emc1403_hwmon_ops,661	.info = emc1403_info,662};663 664/* Last digit of chip name indicates number of channels */665static const struct i2c_device_id emc1403_idtable[] = {666	{ "emc1402", emc1402 },667	{ "emc1403", emc1403 },668	{ "emc1404", emc1404 },669	{ "emc1412", emc1402 },670	{ "emc1413", emc1403 },671	{ "emc1414", emc1404 },672	{ "emc1422", emc1402 },673	{ "emc1423", emc1403 },674	{ "emc1424", emc1404 },675	{ "emc1428", emc1428 },676	{ "emc1438", emc1428 },677	{ "emc1442", emc1402 },678	{ }679};680MODULE_DEVICE_TABLE(i2c, emc1403_idtable);681 682static int emc1403_probe(struct i2c_client *client)683{684	struct thermal_data *data;685	struct device *hwmon_dev;686	const struct i2c_device_id *id = i2c_match_id(emc1403_idtable, client);687 688	data = devm_kzalloc(&client->dev, sizeof(struct thermal_data),689			    GFP_KERNEL);690	if (!data)691		return -ENOMEM;692 693	data->chip = id->driver_data;694	data->regmap = devm_regmap_init_i2c(client, &emc1403_regmap_config);695	if (IS_ERR(data->regmap))696		return PTR_ERR(data->regmap);697 698	mutex_init(&data->mutex);699 700	hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,701							 client->name, data,702							 &emc1403_chip_info,703							 emc1403_groups);704	return PTR_ERR_OR_ZERO(hwmon_dev);705}706 707static const unsigned short emc1403_address_list[] = {708	0x18, 0x1c, 0x29, 0x3c, 0x4c, 0x4d, 0x5c, I2C_CLIENT_END709};710 711static struct i2c_driver sensor_emc1403 = {712	.class = I2C_CLASS_HWMON,713	.driver = {714		.name = "emc1403",715	},716	.detect = emc1403_detect,717	.probe = emc1403_probe,718	.id_table = emc1403_idtable,719	.address_list = emc1403_address_list,720};721 722module_i2c_driver(sensor_emc1403);723 724MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");725MODULE_DESCRIPTION("emc1403 Thermal Driver");726MODULE_LICENSE("GPL v2");727