brintos

brintos / linux-shallow public Read only

0
0
Text · 29.5 KiB · 2448391 Raw
1172 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Analog Devices LTC2947 high precision power and energy monitor4 *5 * Copyright 2019 Analog Devices Inc.6 */7#include <linux/bitfield.h>8#include <linux/bits.h>9#include <linux/clk.h>10#include <linux/device.h>11#include <linux/hwmon.h>12#include <linux/hwmon-sysfs.h>13#include <linux/module.h>14#include <linux/mod_devicetable.h>15#include <linux/property.h>16#include <linux/regmap.h>17 18#include "ltc2947.h"19 20/* register's */21#define LTC2947_REG_PAGE_CTRL		0xFF22#define LTC2947_REG_CTRL		0xF023#define LTC2947_REG_TBCTL		0xE924#define LTC2947_CONT_MODE_MASK		BIT(3)25#define LTC2947_CONT_MODE(x)		FIELD_PREP(LTC2947_CONT_MODE_MASK, x)26#define LTC2947_PRE_MASK		GENMASK(2, 0)27#define LTC2947_PRE(x)			FIELD_PREP(LTC2947_PRE_MASK, x)28#define LTC2947_DIV_MASK		GENMASK(7, 3)29#define LTC2947_DIV(x)			FIELD_PREP(LTC2947_DIV_MASK, x)30#define LTC2947_SHUTDOWN_MASK		BIT(0)31#define LTC2947_REG_ACCUM_POL		0xE132#define LTC2947_ACCUM_POL_1_MASK	GENMASK(1, 0)33#define LTC2947_ACCUM_POL_1(x)		FIELD_PREP(LTC2947_ACCUM_POL_1_MASK, x)34#define LTC2947_ACCUM_POL_2_MASK	GENMASK(3, 2)35#define LTC2947_ACCUM_POL_2(x)		FIELD_PREP(LTC2947_ACCUM_POL_2_MASK, x)36#define LTC2947_REG_ACCUM_DEADBAND	0xE437#define LTC2947_REG_GPIOSTATCTL		0x6738#define LTC2947_GPIO_EN_MASK		BIT(0)39#define LTC2947_GPIO_EN(x)		FIELD_PREP(LTC2947_GPIO_EN_MASK, x)40#define LTC2947_GPIO_FAN_EN_MASK	BIT(6)41#define LTC2947_GPIO_FAN_EN(x)		FIELD_PREP(LTC2947_GPIO_FAN_EN_MASK, x)42#define LTC2947_GPIO_FAN_POL_MASK	BIT(7)43#define LTC2947_GPIO_FAN_POL(x)		FIELD_PREP(LTC2947_GPIO_FAN_POL_MASK, x)44#define LTC2947_REG_GPIO_ACCUM		0xE345/* 200Khz */46#define LTC2947_CLK_MIN			20000047/* 25Mhz */48#define LTC2947_CLK_MAX			2500000049#define LTC2947_PAGE0			050#define LTC2947_PAGE1			151/* Voltage registers */52#define LTC2947_REG_VOLTAGE		0xA053#define LTC2947_REG_VOLTAGE_MAX		0x5054#define LTC2947_REG_VOLTAGE_MIN		0x5255#define LTC2947_REG_VOLTAGE_THRE_H	0x9056#define LTC2947_REG_VOLTAGE_THRE_L	0x9257#define LTC2947_REG_DVCC		0xA458#define LTC2947_REG_DVCC_MAX		0x5859#define LTC2947_REG_DVCC_MIN		0x5A60#define LTC2947_REG_DVCC_THRE_H		0x9861#define LTC2947_REG_DVCC_THRE_L		0x9A62#define LTC2947_VOLTAGE_GEN_CHAN	063#define LTC2947_VOLTAGE_DVCC_CHAN	164/* in mV */65#define VOLTAGE_MAX			1550066#define VOLTAGE_MIN			-30067#define VDVCC_MAX			1500068#define VDVCC_MIN			475069/* Current registers */70#define LTC2947_REG_CURRENT		0x9071#define LTC2947_REG_CURRENT_MAX		0x4072#define LTC2947_REG_CURRENT_MIN		0x4273#define LTC2947_REG_CURRENT_THRE_H	0x8074#define LTC2947_REG_CURRENT_THRE_L	0x8275/* in mA */76#define CURRENT_MAX			3000077#define CURRENT_MIN			-3000078/* Power registers */79#define LTC2947_REG_POWER		0x9380#define LTC2947_REG_POWER_MAX		0x4481#define LTC2947_REG_POWER_MIN		0x4682#define LTC2947_REG_POWER_THRE_H	0x8483#define LTC2947_REG_POWER_THRE_L	0x8684/* in uW */85#define POWER_MAX			45000000086#define POWER_MIN			-45000000087/* Temperature registers */88#define LTC2947_REG_TEMP		0xA289#define LTC2947_REG_TEMP_MAX		0x5490#define LTC2947_REG_TEMP_MIN		0x5691#define LTC2947_REG_TEMP_THRE_H		0x9492#define LTC2947_REG_TEMP_THRE_L		0x9693#define LTC2947_REG_TEMP_FAN_THRE_H	0x9C94#define LTC2947_REG_TEMP_FAN_THRE_L	0x9E95#define LTC2947_TEMP_FAN_CHAN		196/* in millidegress Celsius */97#define TEMP_MAX			8500098#define TEMP_MIN			-4000099/* Energy registers */100#define LTC2947_REG_ENERGY1		0x06101#define LTC2947_REG_ENERGY2		0x16102/* Status/Alarm/Overflow registers */103#define LTC2947_REG_STATUS		0x80104#define LTC2947_REG_STATVT		0x81105#define LTC2947_REG_STATIP		0x82106#define LTC2947_REG_STATVDVCC		0x87107 108#define LTC2947_ALERTS_SIZE	(LTC2947_REG_STATVDVCC - LTC2947_REG_STATUS)109#define LTC2947_MAX_VOLTAGE_MASK	BIT(0)110#define LTC2947_MIN_VOLTAGE_MASK	BIT(1)111#define LTC2947_MAX_CURRENT_MASK	BIT(0)112#define LTC2947_MIN_CURRENT_MASK	BIT(1)113#define LTC2947_MAX_POWER_MASK		BIT(2)114#define LTC2947_MIN_POWER_MASK		BIT(3)115#define LTC2947_MAX_TEMP_MASK		BIT(2)116#define LTC2947_MIN_TEMP_MASK		BIT(3)117#define LTC2947_MAX_TEMP_FAN_MASK	BIT(4)118#define LTC2947_MIN_TEMP_FAN_MASK	BIT(5)119 120struct ltc2947_data {121	struct regmap *map;122	struct device *dev;123	/*124	 * The mutex is needed because the device has 2 memory pages. When125	 * reading/writing the correct page needs to be set so that, the126	 * complete sequence select_page->read/write needs to be protected.127	 */128	struct mutex lock;129	u32 lsb_energy;130	bool gpio_out;131};132 133static int __ltc2947_val_read16(const struct ltc2947_data *st, const u8 reg,134				u64 *val)135{136	__be16 __val = 0;137	int ret;138 139	ret = regmap_bulk_read(st->map, reg, &__val, 2);140	if (ret)141		return ret;142 143	*val = be16_to_cpu(__val);144 145	return 0;146}147 148static int __ltc2947_val_read24(const struct ltc2947_data *st, const u8 reg,149				u64 *val)150{151	__be32 __val = 0;152	int ret;153 154	ret = regmap_bulk_read(st->map, reg, &__val, 3);155	if (ret)156		return ret;157 158	*val = be32_to_cpu(__val) >> 8;159 160	return 0;161}162 163static int __ltc2947_val_read64(const struct ltc2947_data *st, const u8 reg,164				u64 *val)165{166	__be64 __val = 0;167	int ret;168 169	ret = regmap_bulk_read(st->map, reg, &__val, 6);170	if (ret)171		return ret;172 173	*val = be64_to_cpu(__val) >> 16;174 175	return 0;176}177 178static int ltc2947_val_read(struct ltc2947_data *st, const u8 reg,179			    const u8 page, const size_t size, s64 *val)180{181	int ret;182	u64 __val = 0;183 184	mutex_lock(&st->lock);185 186	ret = regmap_write(st->map, LTC2947_REG_PAGE_CTRL, page);187	if (ret) {188		mutex_unlock(&st->lock);189		return ret;190	}191 192	dev_dbg(st->dev, "Read val, reg:%02X, p:%d sz:%zu\n", reg, page,193		size);194 195	switch (size) {196	case 2:197		ret = __ltc2947_val_read16(st, reg, &__val);198		break;199	case 3:200		ret = __ltc2947_val_read24(st, reg, &__val);201		break;202	case 6:203		ret = __ltc2947_val_read64(st, reg, &__val);204		break;205	default:206		ret = -EINVAL;207		break;208	}209 210	mutex_unlock(&st->lock);211 212	if (ret)213		return ret;214 215	*val = sign_extend64(__val, (8 * size) - 1);216 217	dev_dbg(st->dev, "Got s:%lld, u:%016llX\n", *val, __val);218 219	return 0;220}221 222static int __ltc2947_val_write64(const struct ltc2947_data *st, const u8 reg,223				 const u64 val)224{225	__be64 __val;226 227	__val = cpu_to_be64(val << 16);228	return regmap_bulk_write(st->map, reg, &__val, 6);229}230 231static int __ltc2947_val_write16(const struct ltc2947_data *st, const u8 reg,232				 const u16 val)233{234	__be16 __val;235 236	__val = cpu_to_be16(val);237	return regmap_bulk_write(st->map, reg, &__val, 2);238}239 240static int ltc2947_val_write(struct ltc2947_data *st, const u8 reg,241			     const u8 page, const size_t size, const u64 val)242{243	int ret;244 245	mutex_lock(&st->lock);246	/* set device on correct page */247	ret = regmap_write(st->map, LTC2947_REG_PAGE_CTRL, page);248	if (ret) {249		mutex_unlock(&st->lock);250		return ret;251	}252 253	dev_dbg(st->dev, "Write val, r:%02X, p:%d, sz:%zu, val:%016llX\n",254		reg, page, size, val);255 256	switch (size) {257	case 2:258		ret = __ltc2947_val_write16(st, reg, val);259		break;260	case 6:261		ret = __ltc2947_val_write64(st, reg, val);262		break;263	default:264		ret = -EINVAL;265		break;266	}267 268	mutex_unlock(&st->lock);269 270	return ret;271}272 273static int ltc2947_reset_history(struct ltc2947_data *st, const u8 reg_h,274				 const u8 reg_l)275{276	int ret;277	/*278	 * let's reset the tracking register's. Tracking register's have all279	 * 2 bytes size280	 */281	ret = ltc2947_val_write(st, reg_h, LTC2947_PAGE0, 2, 0x8000U);282	if (ret)283		return ret;284 285	return ltc2947_val_write(st, reg_l, LTC2947_PAGE0, 2, 0x7FFFU);286}287 288static int ltc2947_alarm_read(struct ltc2947_data *st, const u8 reg,289			      const u32 mask, long *val)290{291	u8 offset = reg - LTC2947_REG_STATUS;292	/* +1 to include status reg */293	char alarms[LTC2947_ALERTS_SIZE + 1];294	int ret = 0;295 296	memset(alarms, 0, sizeof(alarms));297 298	mutex_lock(&st->lock);299 300	ret = regmap_write(st->map, LTC2947_REG_PAGE_CTRL, LTC2947_PAGE0);301	if (ret)302		goto unlock;303 304	dev_dbg(st->dev, "Read alarm, reg:%02X, mask:%02X\n", reg, mask);305	/*306	 * As stated in the datasheet, when Threshold and Overflow registers307	 * are used, the status and all alert registers must be read in one308	 * multi-byte transaction.309	 */310	ret = regmap_bulk_read(st->map, LTC2947_REG_STATUS, alarms,311			       sizeof(alarms));312	if (ret)313		goto unlock;314 315	/* get the alarm */316	*val = !!(alarms[offset] & mask);317unlock:318	mutex_unlock(&st->lock);319	return ret;320}321 322static ssize_t ltc2947_show_value(struct device *dev,323				  struct device_attribute *da, char *buf)324{325	struct ltc2947_data *st = dev_get_drvdata(dev);326	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);327	int ret;328	s64 val = 0;329 330	ret = ltc2947_val_read(st, attr->index, LTC2947_PAGE0, 6, &val);331	if (ret)332		return ret;333 334	/* value in microJoule. st->lsb_energy was multiplied by 10E9 */335	val = div_s64(val * st->lsb_energy, 1000);336 337	return sprintf(buf, "%lld\n", val);338}339 340static int ltc2947_read_temp(struct device *dev, const u32 attr, long *val,341			     const int channel)342{343	int ret;344	struct ltc2947_data *st = dev_get_drvdata(dev);345	s64 __val = 0;346 347	switch (attr) {348	case hwmon_temp_input:349		ret = ltc2947_val_read(st, LTC2947_REG_TEMP, LTC2947_PAGE0,350				       2, &__val);351		break;352	case hwmon_temp_highest:353		ret = ltc2947_val_read(st, LTC2947_REG_TEMP_MAX, LTC2947_PAGE0,354				       2, &__val);355		break;356	case hwmon_temp_lowest:357		ret = ltc2947_val_read(st, LTC2947_REG_TEMP_MIN, LTC2947_PAGE0,358				       2, &__val);359		break;360	case hwmon_temp_max_alarm:361		if (channel == LTC2947_TEMP_FAN_CHAN)362			return ltc2947_alarm_read(st, LTC2947_REG_STATVT,363						  LTC2947_MAX_TEMP_FAN_MASK,364						  val);365 366		return ltc2947_alarm_read(st, LTC2947_REG_STATVT,367					  LTC2947_MAX_TEMP_MASK, val);368	case hwmon_temp_min_alarm:369		if (channel == LTC2947_TEMP_FAN_CHAN)370			return	ltc2947_alarm_read(st, LTC2947_REG_STATVT,371						   LTC2947_MIN_TEMP_FAN_MASK,372						   val);373 374		return	ltc2947_alarm_read(st, LTC2947_REG_STATVT,375					   LTC2947_MIN_TEMP_MASK, val);376	case hwmon_temp_max:377		if (channel == LTC2947_TEMP_FAN_CHAN)378			ret = ltc2947_val_read(st, LTC2947_REG_TEMP_FAN_THRE_H,379					       LTC2947_PAGE1, 2, &__val);380		else381			ret = ltc2947_val_read(st, LTC2947_REG_TEMP_THRE_H,382					       LTC2947_PAGE1, 2, &__val);383		break;384	case hwmon_temp_min:385		if (channel == LTC2947_TEMP_FAN_CHAN)386			ret = ltc2947_val_read(st, LTC2947_REG_TEMP_FAN_THRE_L,387					       LTC2947_PAGE1, 2, &__val);388		else389			ret = ltc2947_val_read(st, LTC2947_REG_TEMP_THRE_L,390					       LTC2947_PAGE1, 2, &__val);391		break;392	default:393		return -ENOTSUPP;394	}395 396	if (ret)397		return ret;398 399	/* in milidegrees celcius, temp is given by: */400	*val = (__val * 204) + 5500;401 402	return 0;403}404 405static int ltc2947_read_power(struct device *dev, const u32 attr, long *val)406{407	struct ltc2947_data *st = dev_get_drvdata(dev);408	int ret;409	u32 lsb = 200000; /* in uW */410	s64 __val = 0;411 412	switch (attr) {413	case hwmon_power_input:414		ret = ltc2947_val_read(st, LTC2947_REG_POWER, LTC2947_PAGE0,415				       3, &__val);416		lsb = 50000;417		break;418	case hwmon_power_input_highest:419		ret = ltc2947_val_read(st, LTC2947_REG_POWER_MAX, LTC2947_PAGE0,420				       2, &__val);421		break;422	case hwmon_power_input_lowest:423		ret = ltc2947_val_read(st, LTC2947_REG_POWER_MIN, LTC2947_PAGE0,424				       2, &__val);425		break;426	case hwmon_power_max_alarm:427		return ltc2947_alarm_read(st, LTC2947_REG_STATIP,428					  LTC2947_MAX_POWER_MASK, val);429	case hwmon_power_min_alarm:430		return ltc2947_alarm_read(st, LTC2947_REG_STATIP,431					  LTC2947_MIN_POWER_MASK, val);432	case hwmon_power_max:433		ret = ltc2947_val_read(st, LTC2947_REG_POWER_THRE_H,434				       LTC2947_PAGE1, 2, &__val);435		break;436	case hwmon_power_min:437		ret = ltc2947_val_read(st, LTC2947_REG_POWER_THRE_L,438				       LTC2947_PAGE1, 2, &__val);439		break;440	default:441		return -ENOTSUPP;442	}443 444	if (ret)445		return ret;446 447	*val = __val * lsb;448 449	return 0;450}451 452static int ltc2947_read_curr(struct device *dev, const u32 attr, long *val)453{454	struct ltc2947_data *st = dev_get_drvdata(dev);455	int ret;456	u8 lsb = 12; /* in mA */457	s64 __val = 0;458 459	switch (attr) {460	case hwmon_curr_input:461		ret = ltc2947_val_read(st, LTC2947_REG_CURRENT,462				       LTC2947_PAGE0, 3, &__val);463		lsb = 3;464		break;465	case hwmon_curr_highest:466		ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_MAX,467				       LTC2947_PAGE0, 2, &__val);468		break;469	case hwmon_curr_lowest:470		ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_MIN,471				       LTC2947_PAGE0, 2, &__val);472		break;473	case hwmon_curr_max_alarm:474		return ltc2947_alarm_read(st, LTC2947_REG_STATIP,475					  LTC2947_MAX_CURRENT_MASK, val);476	case hwmon_curr_min_alarm:477		return ltc2947_alarm_read(st, LTC2947_REG_STATIP,478					  LTC2947_MIN_CURRENT_MASK, val);479	case hwmon_curr_max:480		ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_THRE_H,481				       LTC2947_PAGE1, 2, &__val);482		break;483	case hwmon_curr_min:484		ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_THRE_L,485				       LTC2947_PAGE1, 2, &__val);486		break;487	default:488		return -ENOTSUPP;489	}490 491	if (ret)492		return ret;493 494	*val = __val * lsb;495 496	return 0;497}498 499static int ltc2947_read_in(struct device *dev, const u32 attr, long *val,500			   const int channel)501{502	struct ltc2947_data *st = dev_get_drvdata(dev);503	int ret;504	u8 lsb = 2; /* in mV */505	s64 __val = 0;506 507	if (channel < 0 || channel > LTC2947_VOLTAGE_DVCC_CHAN) {508		dev_err(st->dev, "Invalid chan%d for voltage", channel);509		return -EINVAL;510	}511 512	switch (attr) {513	case hwmon_in_input:514		if (channel == LTC2947_VOLTAGE_DVCC_CHAN) {515			ret = ltc2947_val_read(st, LTC2947_REG_DVCC,516					       LTC2947_PAGE0, 2, &__val);517			lsb = 145;518		} else {519			ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE,520					       LTC2947_PAGE0, 2, &__val);521		}522		break;523	case hwmon_in_highest:524		if (channel == LTC2947_VOLTAGE_DVCC_CHAN) {525			ret = ltc2947_val_read(st, LTC2947_REG_DVCC_MAX,526					       LTC2947_PAGE0, 2, &__val);527			lsb = 145;528		} else {529			ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_MAX,530					       LTC2947_PAGE0, 2, &__val);531		}532		break;533	case hwmon_in_lowest:534		if (channel == LTC2947_VOLTAGE_DVCC_CHAN) {535			ret = ltc2947_val_read(st, LTC2947_REG_DVCC_MIN,536					       LTC2947_PAGE0, 2, &__val);537			lsb = 145;538		} else {539			ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_MIN,540					       LTC2947_PAGE0, 2, &__val);541		}542		break;543	case hwmon_in_max_alarm:544		if (channel == LTC2947_VOLTAGE_DVCC_CHAN)545			return ltc2947_alarm_read(st, LTC2947_REG_STATVDVCC,546						  LTC2947_MAX_VOLTAGE_MASK,547						  val);548 549		return ltc2947_alarm_read(st, LTC2947_REG_STATVT,550					  LTC2947_MAX_VOLTAGE_MASK, val);551	case hwmon_in_min_alarm:552		if (channel == LTC2947_VOLTAGE_DVCC_CHAN)553			return ltc2947_alarm_read(st, LTC2947_REG_STATVDVCC,554						  LTC2947_MIN_VOLTAGE_MASK,555						  val);556 557		return ltc2947_alarm_read(st, LTC2947_REG_STATVT,558					  LTC2947_MIN_VOLTAGE_MASK, val);559	case hwmon_in_max:560		if (channel == LTC2947_VOLTAGE_DVCC_CHAN) {561			ret = ltc2947_val_read(st, LTC2947_REG_DVCC_THRE_H,562					       LTC2947_PAGE1, 2, &__val);563			lsb = 145;564		} else {565			ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_THRE_H,566					       LTC2947_PAGE1, 2, &__val);567		}568		break;569	case hwmon_in_min:570		if (channel == LTC2947_VOLTAGE_DVCC_CHAN) {571			ret = ltc2947_val_read(st, LTC2947_REG_DVCC_THRE_L,572					       LTC2947_PAGE1, 2, &__val);573			lsb = 145;574		} else {575			ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_THRE_L,576					       LTC2947_PAGE1, 2, &__val);577		}578		break;579	default:580		return -ENOTSUPP;581	}582 583	if (ret)584		return ret;585 586	*val = __val * lsb;587 588	return 0;589}590 591static int ltc2947_read(struct device *dev, enum hwmon_sensor_types type,592			u32 attr, int channel, long *val)593{594	switch (type) {595	case hwmon_in:596		return ltc2947_read_in(dev, attr, val, channel);597	case hwmon_curr:598		return ltc2947_read_curr(dev, attr, val);599	case hwmon_power:600		return ltc2947_read_power(dev, attr, val);601	case hwmon_temp:602		return ltc2947_read_temp(dev, attr, val, channel);603	default:604		return -ENOTSUPP;605	}606}607 608static int ltc2947_write_temp(struct device *dev, const u32 attr,609			      long val, const int channel)610{611	struct ltc2947_data *st = dev_get_drvdata(dev);612 613	if (channel < 0 || channel > LTC2947_TEMP_FAN_CHAN) {614		dev_err(st->dev, "Invalid chan%d for temperature", channel);615		return -EINVAL;616	}617 618	switch (attr) {619	case hwmon_temp_reset_history:620		if (val != 1)621			return -EINVAL;622		return ltc2947_reset_history(st, LTC2947_REG_TEMP_MAX,623					     LTC2947_REG_TEMP_MIN);624	case hwmon_temp_max:625		val = clamp_val(val, TEMP_MIN, TEMP_MAX);626		if (channel == LTC2947_TEMP_FAN_CHAN) {627			if (!st->gpio_out)628				return -ENOTSUPP;629 630			return ltc2947_val_write(st,631					LTC2947_REG_TEMP_FAN_THRE_H,632					LTC2947_PAGE1, 2,633					DIV_ROUND_CLOSEST(val - 550, 204));634		}635 636		return ltc2947_val_write(st, LTC2947_REG_TEMP_THRE_H,637					 LTC2947_PAGE1, 2,638					 DIV_ROUND_CLOSEST(val - 550, 204));639	case hwmon_temp_min:640		val = clamp_val(val, TEMP_MIN, TEMP_MAX);641		if (channel == LTC2947_TEMP_FAN_CHAN) {642			if (!st->gpio_out)643				return -ENOTSUPP;644 645			return ltc2947_val_write(st,646					LTC2947_REG_TEMP_FAN_THRE_L,647					LTC2947_PAGE1, 2,648					DIV_ROUND_CLOSEST(val - 550, 204));649		}650 651		return ltc2947_val_write(st, LTC2947_REG_TEMP_THRE_L,652					 LTC2947_PAGE1, 2,653					 DIV_ROUND_CLOSEST(val - 550, 204));654	default:655		return -ENOTSUPP;656	}657}658 659static int ltc2947_write_power(struct device *dev, const u32 attr,660			       long val)661{662	struct ltc2947_data *st = dev_get_drvdata(dev);663 664	switch (attr) {665	case hwmon_power_reset_history:666		if (val != 1)667			return -EINVAL;668		return ltc2947_reset_history(st, LTC2947_REG_POWER_MAX,669					     LTC2947_REG_POWER_MIN);670	case hwmon_power_max:671		val = clamp_val(val, POWER_MIN, POWER_MAX);672		return ltc2947_val_write(st, LTC2947_REG_POWER_THRE_H,673					 LTC2947_PAGE1, 2,674					 DIV_ROUND_CLOSEST(val, 200000));675	case hwmon_power_min:676		val = clamp_val(val, POWER_MIN, POWER_MAX);677		return ltc2947_val_write(st, LTC2947_REG_POWER_THRE_L,678					 LTC2947_PAGE1, 2,679					 DIV_ROUND_CLOSEST(val, 200000));680	default:681		return -ENOTSUPP;682	}683}684 685static int ltc2947_write_curr(struct device *dev, const u32 attr,686			      long val)687{688	struct ltc2947_data *st = dev_get_drvdata(dev);689 690	switch (attr) {691	case hwmon_curr_reset_history:692		if (val != 1)693			return -EINVAL;694		return ltc2947_reset_history(st, LTC2947_REG_CURRENT_MAX,695					     LTC2947_REG_CURRENT_MIN);696	case hwmon_curr_max:697		val = clamp_val(val, CURRENT_MIN, CURRENT_MAX);698		return ltc2947_val_write(st, LTC2947_REG_CURRENT_THRE_H,699					 LTC2947_PAGE1, 2,700					 DIV_ROUND_CLOSEST(val, 12));701	case hwmon_curr_min:702		val = clamp_val(val, CURRENT_MIN, CURRENT_MAX);703		return ltc2947_val_write(st, LTC2947_REG_CURRENT_THRE_L,704					 LTC2947_PAGE1, 2,705					 DIV_ROUND_CLOSEST(val, 12));706	default:707		return -ENOTSUPP;708	}709}710 711static int ltc2947_write_in(struct device *dev, const u32 attr, long val,712			    const int channel)713{714	struct ltc2947_data *st = dev_get_drvdata(dev);715 716	if (channel > LTC2947_VOLTAGE_DVCC_CHAN) {717		dev_err(st->dev, "Invalid chan%d for voltage", channel);718		return -EINVAL;719	}720 721	switch (attr) {722	case hwmon_in_reset_history:723		if (val != 1)724			return -EINVAL;725 726		if (channel == LTC2947_VOLTAGE_DVCC_CHAN)727			return ltc2947_reset_history(st, LTC2947_REG_DVCC_MAX,728						     LTC2947_REG_DVCC_MIN);729 730		return ltc2947_reset_history(st, LTC2947_REG_VOLTAGE_MAX,731					     LTC2947_REG_VOLTAGE_MIN);732	case hwmon_in_max:733		if (channel == LTC2947_VOLTAGE_DVCC_CHAN) {734			val = clamp_val(val, VDVCC_MIN, VDVCC_MAX);735			return ltc2947_val_write(st, LTC2947_REG_DVCC_THRE_H,736						 LTC2947_PAGE1, 2,737						 DIV_ROUND_CLOSEST(val, 145));738		}739 740		val = clamp_val(val, VOLTAGE_MIN, VOLTAGE_MAX);741		return ltc2947_val_write(st, LTC2947_REG_VOLTAGE_THRE_H,742					 LTC2947_PAGE1, 2,743					 DIV_ROUND_CLOSEST(val, 2));744	case hwmon_in_min:745		if (channel == LTC2947_VOLTAGE_DVCC_CHAN) {746			val = clamp_val(val, VDVCC_MIN, VDVCC_MAX);747			return ltc2947_val_write(st, LTC2947_REG_DVCC_THRE_L,748						 LTC2947_PAGE1, 2,749						 DIV_ROUND_CLOSEST(val, 145));750		}751 752		val = clamp_val(val, VOLTAGE_MIN, VOLTAGE_MAX);753		return ltc2947_val_write(st, LTC2947_REG_VOLTAGE_THRE_L,754					 LTC2947_PAGE1, 2,755					 DIV_ROUND_CLOSEST(val, 2));756	default:757		return -ENOTSUPP;758	}759}760 761static int ltc2947_write(struct device *dev,762			 enum hwmon_sensor_types type,763			 u32 attr, int channel, long val)764{765	switch (type) {766	case hwmon_in:767		return ltc2947_write_in(dev, attr, val, channel);768	case hwmon_curr:769		return ltc2947_write_curr(dev, attr, val);770	case hwmon_power:771		return ltc2947_write_power(dev, attr, val);772	case hwmon_temp:773		return ltc2947_write_temp(dev, attr, val, channel);774	default:775		return -ENOTSUPP;776	}777}778 779static int ltc2947_read_labels(struct device *dev,780			       enum hwmon_sensor_types type,781			       u32 attr, int channel, const char **str)782{783	switch (type) {784	case hwmon_in:785		if (channel == LTC2947_VOLTAGE_DVCC_CHAN)786			*str = "DVCC";787		else788			*str = "VP-VM";789		return 0;790	case hwmon_curr:791		*str = "IP-IM";792		return 0;793	case hwmon_temp:794		if (channel == LTC2947_TEMP_FAN_CHAN)795			*str = "TEMPFAN";796		else797			*str = "Ambient";798		return 0;799	case hwmon_power:800		*str = "Power";801		return 0;802	default:803		return -ENOTSUPP;804	}805}806 807static int ltc2947_in_is_visible(const u32 attr)808{809	switch (attr) {810	case hwmon_in_input:811	case hwmon_in_highest:812	case hwmon_in_lowest:813	case hwmon_in_max_alarm:814	case hwmon_in_min_alarm:815	case hwmon_in_label:816		return 0444;817	case hwmon_in_reset_history:818		return 0200;819	case hwmon_in_max:820	case hwmon_in_min:821		return 0644;822	default:823		return 0;824	}825}826 827static int ltc2947_curr_is_visible(const u32 attr)828{829	switch (attr) {830	case hwmon_curr_input:831	case hwmon_curr_highest:832	case hwmon_curr_lowest:833	case hwmon_curr_max_alarm:834	case hwmon_curr_min_alarm:835	case hwmon_curr_label:836		return 0444;837	case hwmon_curr_reset_history:838		return 0200;839	case hwmon_curr_max:840	case hwmon_curr_min:841		return 0644;842	default:843		return 0;844	}845}846 847static int ltc2947_power_is_visible(const u32 attr)848{849	switch (attr) {850	case hwmon_power_input:851	case hwmon_power_input_highest:852	case hwmon_power_input_lowest:853	case hwmon_power_label:854	case hwmon_power_max_alarm:855	case hwmon_power_min_alarm:856		return 0444;857	case hwmon_power_reset_history:858		return 0200;859	case hwmon_power_max:860	case hwmon_power_min:861		return 0644;862	default:863		return 0;864	}865}866 867static int ltc2947_temp_is_visible(const u32 attr)868{869	switch (attr) {870	case hwmon_temp_input:871	case hwmon_temp_highest:872	case hwmon_temp_lowest:873	case hwmon_temp_max_alarm:874	case hwmon_temp_min_alarm:875	case hwmon_temp_label:876		return 0444;877	case hwmon_temp_reset_history:878		return 0200;879	case hwmon_temp_max:880	case hwmon_temp_min:881		return 0644;882	default:883		return 0;884	}885}886 887static umode_t ltc2947_is_visible(const void *data,888				  enum hwmon_sensor_types type,889				  u32 attr, int channel)890{891	switch (type) {892	case hwmon_in:893		return ltc2947_in_is_visible(attr);894	case hwmon_curr:895		return ltc2947_curr_is_visible(attr);896	case hwmon_power:897		return ltc2947_power_is_visible(attr);898	case hwmon_temp:899		return ltc2947_temp_is_visible(attr);900	default:901		return 0;902	}903}904 905static const struct hwmon_channel_info * const ltc2947_info[] = {906	HWMON_CHANNEL_INFO(in,907			   HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST |908			   HWMON_I_MAX | HWMON_I_MIN | HWMON_I_RESET_HISTORY |909			   HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM |910			   HWMON_I_LABEL,911			   HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST |912			   HWMON_I_MAX | HWMON_I_MIN | HWMON_I_RESET_HISTORY |913			   HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM |914			   HWMON_I_LABEL),915	HWMON_CHANNEL_INFO(curr,916			   HWMON_C_INPUT | HWMON_C_LOWEST | HWMON_C_HIGHEST |917			   HWMON_C_MAX | HWMON_C_MIN | HWMON_C_RESET_HISTORY |918			   HWMON_C_MIN_ALARM | HWMON_C_MAX_ALARM |919			   HWMON_C_LABEL),920	HWMON_CHANNEL_INFO(power,921			   HWMON_P_INPUT | HWMON_P_INPUT_LOWEST |922			   HWMON_P_INPUT_HIGHEST | HWMON_P_MAX | HWMON_P_MIN |923			   HWMON_P_RESET_HISTORY | HWMON_P_MAX_ALARM |924			   HWMON_P_MIN_ALARM | HWMON_P_LABEL),925	HWMON_CHANNEL_INFO(temp,926			   HWMON_T_INPUT | HWMON_T_LOWEST | HWMON_T_HIGHEST |927			   HWMON_T_MAX | HWMON_T_MIN | HWMON_T_RESET_HISTORY |928			   HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM |929			   HWMON_T_LABEL,930			   HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | HWMON_T_MAX |931			   HWMON_T_MIN | HWMON_T_LABEL),932	NULL933};934 935static const struct hwmon_ops ltc2947_hwmon_ops = {936	.is_visible = ltc2947_is_visible,937	.read = ltc2947_read,938	.write = ltc2947_write,939	.read_string = ltc2947_read_labels,940};941 942static const struct hwmon_chip_info ltc2947_chip_info = {943	.ops = &ltc2947_hwmon_ops,944	.info = ltc2947_info,945};946 947/* energy attributes are 6bytes wide so we need u64 */948static SENSOR_DEVICE_ATTR(energy1_input, 0444, ltc2947_show_value, NULL,949			  LTC2947_REG_ENERGY1);950static SENSOR_DEVICE_ATTR(energy2_input, 0444, ltc2947_show_value, NULL,951			  LTC2947_REG_ENERGY2);952 953static struct attribute *ltc2947_attrs[] = {954	&sensor_dev_attr_energy1_input.dev_attr.attr,955	&sensor_dev_attr_energy2_input.dev_attr.attr,956	NULL,957};958ATTRIBUTE_GROUPS(ltc2947);959 960static int ltc2947_setup(struct ltc2947_data *st)961{962	int ret;963	struct clk *extclk;964	u32 dummy, deadband, pol;965	u32 accum[2];966 967	/* clear status register by reading it */968	ret = regmap_read(st->map, LTC2947_REG_STATUS, &dummy);969	if (ret)970		return ret;971	/*972	 * Set max/min for power here since the default values x scale973	 * would overflow on 32bit arch974	 */975	ret = ltc2947_val_write(st, LTC2947_REG_POWER_THRE_H, LTC2947_PAGE1, 2,976				POWER_MAX / 200000);977	if (ret)978		return ret;979 980	ret = ltc2947_val_write(st, LTC2947_REG_POWER_THRE_L, LTC2947_PAGE1, 2,981				POWER_MIN / 200000);982	if (ret)983		return ret;984 985	/* check external clock presence */986	extclk = devm_clk_get_optional_enabled(st->dev, NULL);987	if (IS_ERR(extclk))988		return dev_err_probe(st->dev, PTR_ERR(extclk),989				     "Failed to get external clock\n");990 991	if (extclk) {992		unsigned long rate_hz;993		u8 pre = 0, div, tbctl;994		u64 aux;995 996		/* let's calculate and set the right valus in TBCTL */997		rate_hz = clk_get_rate(extclk);998		if (rate_hz < LTC2947_CLK_MIN || rate_hz > LTC2947_CLK_MAX) {999			dev_err(st->dev, "Invalid rate:%lu for external clock",1000				rate_hz);1001			return -EINVAL;1002		}1003 1004		/* as in table 1 of the datasheet */1005		if (rate_hz >= LTC2947_CLK_MIN && rate_hz <= 1000000)1006			pre = 0;1007		else if (rate_hz > 1000000 && rate_hz <= 2000000)1008			pre = 1;1009		else if (rate_hz > 2000000 && rate_hz <= 4000000)1010			pre = 2;1011		else if (rate_hz > 4000000 && rate_hz <= 8000000)1012			pre = 3;1013		else if (rate_hz > 8000000 && rate_hz <= 16000000)1014			pre = 4;1015		else if (rate_hz > 16000000 && rate_hz <= LTC2947_CLK_MAX)1016			pre = 5;1017		/*1018		 * Div is given by:1019		 *	floor(fref / (2^PRE * 32768))1020		 */1021		div = rate_hz / ((1 << pre) * 32768);1022		tbctl = LTC2947_PRE(pre) | LTC2947_DIV(div);1023 1024		ret = regmap_write(st->map, LTC2947_REG_TBCTL, tbctl);1025		if (ret)1026			return ret;1027		/*1028		 * The energy lsb is given by (in W*s):1029		 *      06416 * (1/fref) * 2^PRE * (DIV + 1)1030		 * The value is multiplied by 10E91031		 */1032		aux = (div + 1) * ((1 << pre) * 641600000ULL);1033		st->lsb_energy = DIV_ROUND_CLOSEST_ULL(aux, rate_hz);1034	} else {1035		/* 19.89E-6 * 10E9 */1036		st->lsb_energy = 19890;1037	}1038	ret = device_property_read_u32_array(st->dev, "adi,accumulator-ctl-pol",1039					     accum, ARRAY_SIZE(accum));1040	if (!ret) {1041		u32 accum_reg = LTC2947_ACCUM_POL_1(accum[0]) |1042				LTC2947_ACCUM_POL_2(accum[1]);1043 1044		ret = regmap_write(st->map, LTC2947_REG_ACCUM_POL, accum_reg);1045		if (ret)1046			return ret;1047	}1048	ret = device_property_read_u32(st->dev,1049				       "adi,accumulation-deadband-microamp",1050				       &deadband);1051	if (!ret) {1052		/* the LSB is the same as the current, so 3mA */1053		ret = regmap_write(st->map, LTC2947_REG_ACCUM_DEADBAND,1054				   deadband / (1000 * 3));1055		if (ret)1056			return ret;1057	}1058	/* check gpio cfg */1059	ret = device_property_read_u32(st->dev, "adi,gpio-out-pol", &pol);1060	if (!ret) {1061		/* setup GPIO as output */1062		u32 gpio_ctl = LTC2947_GPIO_EN(1) | LTC2947_GPIO_FAN_EN(1) |1063			LTC2947_GPIO_FAN_POL(pol);1064 1065		st->gpio_out = true;1066		ret = regmap_write(st->map, LTC2947_REG_GPIOSTATCTL, gpio_ctl);1067		if (ret)1068			return ret;1069	}1070	ret = device_property_read_u32_array(st->dev, "adi,gpio-in-accum",1071					     accum, ARRAY_SIZE(accum));1072	if (!ret) {1073		/*1074		 * Setup the accum options. The gpioctl is already defined as1075		 * input by default.1076		 */1077		u32 accum_val = LTC2947_ACCUM_POL_1(accum[0]) |1078				LTC2947_ACCUM_POL_2(accum[1]);1079 1080		if (st->gpio_out) {1081			dev_err(st->dev,1082				"Cannot have input gpio config if already configured as output");1083			return -EINVAL;1084		}1085 1086		ret = regmap_write(st->map, LTC2947_REG_GPIO_ACCUM, accum_val);1087		if (ret)1088			return ret;1089	}1090 1091	/* set continuos mode */1092	return regmap_update_bits(st->map, LTC2947_REG_CTRL,1093				  LTC2947_CONT_MODE_MASK, LTC2947_CONT_MODE(1));1094}1095 1096int ltc2947_core_probe(struct regmap *map, const char *name)1097{1098	struct ltc2947_data *st;1099	struct device *dev = regmap_get_device(map);1100	struct device *hwmon;1101	int ret;1102 1103	st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);1104	if (!st)1105		return -ENOMEM;1106 1107	st->map = map;1108	st->dev = dev;1109	dev_set_drvdata(dev, st);1110	mutex_init(&st->lock);1111 1112	ret = ltc2947_setup(st);1113	if (ret)1114		return ret;1115 1116	hwmon = devm_hwmon_device_register_with_info(dev, name, st,1117						     &ltc2947_chip_info,1118						     ltc2947_groups);1119	return PTR_ERR_OR_ZERO(hwmon);1120}1121EXPORT_SYMBOL_GPL(ltc2947_core_probe);1122 1123static int ltc2947_resume(struct device *dev)1124{1125	struct ltc2947_data *st = dev_get_drvdata(dev);1126	u32 ctrl = 0;1127	int ret;1128 1129	/* dummy read to wake the device */1130	ret = regmap_read(st->map, LTC2947_REG_CTRL, &ctrl);1131	if (ret)1132		return ret;1133	/*1134	 * Wait for the device. It takes 100ms to wake up so, 10ms extra1135	 * should be enough.1136	 */1137	msleep(110);1138	ret = regmap_read(st->map, LTC2947_REG_CTRL, &ctrl);1139	if (ret)1140		return ret;1141	/* ctrl should be 0 */1142	if (ctrl != 0) {1143		dev_err(st->dev, "Device failed to wake up, ctl:%02X\n", ctrl);1144		return -ETIMEDOUT;1145	}1146 1147	/* set continuous mode */1148	return regmap_update_bits(st->map, LTC2947_REG_CTRL,1149				  LTC2947_CONT_MODE_MASK, LTC2947_CONT_MODE(1));1150}1151 1152static int ltc2947_suspend(struct device *dev)1153{1154	struct ltc2947_data *st = dev_get_drvdata(dev);1155 1156	return regmap_update_bits(st->map, LTC2947_REG_CTRL,1157				  LTC2947_SHUTDOWN_MASK, 1);1158}1159 1160EXPORT_SIMPLE_DEV_PM_OPS(ltc2947_pm_ops, ltc2947_suspend, ltc2947_resume);1161 1162const struct of_device_id ltc2947_of_match[] = {1163	{ .compatible = "adi,ltc2947" },1164	{}1165};1166EXPORT_SYMBOL_GPL(ltc2947_of_match);1167MODULE_DEVICE_TABLE(of, ltc2947_of_match);1168 1169MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");1170MODULE_DESCRIPTION("LTC2947 power and energy monitor core driver");1171MODULE_LICENSE("GPL");1172