From nobody Fri Dec 19 19:17:15 2025 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A15A21E9B2E; Wed, 8 Jan 2025 08:26:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736324775; cv=none; b=cfaiW9QCdSv72ACszJcOUUhLKR07l8akzj8R/TLPSKgtZeDxJl1u/AGKO94FRRjf+QO1lSmtmUAXMhdhqfC3x039RDTFGmG9runJ5q03X3H+ShUCNdiVfpL0ZO3XIfjmkqL1SkTuBvHmqF/Q1L9b3P1+SI7qSjQqAXAtqN23oaA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736324775; c=relaxed/simple; bh=iDABl9+NhqWTOWEAfUCqcJjC1oejM2UBhPR5FN14MoY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NFvmTvPVheJkYPp8lE+lwis/nSe/NOxDolm1IEdyXKEdyaPzSPW9ukS8MJ6tP1Juil95tarMd/ZC4+tiY+Qq63He2CVmYzzMXlkC13dWQz/BqOPep9aozVXYJsSUe0+0tvVsj6Jnx3WV9o6LjLiYAfLh5r6jKe3zFQX/JkgIH1g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=am4vldzR; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="am4vldzR" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5083aVZY007711; Wed, 8 Jan 2025 03:25:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=zjK8G Re2VWdfcq/PmwVvtZOo4TQxRk/G/oEYmsWccfQ=; b=am4vldzRuskhJfCdygPMG 5ngRMVpsyvKuFejeCFX5v84h7PlYg9ojtdyO1t56nuaL7UfjzkjfON32BNmXJe0/ BfBD1Le4JqKljDWw/ULBaNc1qQoYxuNDUS+AcnLFaAusEywX473Lapj0HMjdPNIi h3pHP9hCy8fiooH1jOG21hZKYOYty7+zkz45WQ/GMiM8SSV1lpWSEK9OhYaz3O4o hq0vAHcUw3JmCxnfQy/3FqWu3cSHbkfZ2Pb1jkdyfsFdu/Ucyd9P3cmoQzrT1Rvl csYpUhwO2g+kd8KAlbhxqO1IgQHhFJ5Qunv2D63mh8vam0cD3H46q97uSJK3Bt2O g== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 441dh3a578-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 08 Jan 2025 03:25:58 -0500 (EST) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 5088PuKE037181 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 8 Jan 2025 03:25:57 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Wed, 8 Jan 2025 03:25:56 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Wed, 8 Jan 2025 03:25:56 -0500 Received: from JGERONI2-L01.ad.analog.com (JGERONI2-L01.ad.analog.com [10.117.223.6]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5088PfdO026945; Wed, 8 Jan 2025 03:25:51 -0500 From: John Erasmus Mari Geronimo To: , , , CC: Jean Delvare , Guenter Roeck , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet Subject: [PATCH 1/3] hwmon: (max31827) refactor enum chips to chip info Date: Wed, 8 Jan 2025 16:25:29 +0800 Message-ID: <20250108082531.15467-2-johnerasmusmari.geronimo@analog.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250108082531.15467-1-johnerasmusmari.geronimo@analog.com> References: <20250108082531.15467-1-johnerasmusmari.geronimo@analog.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: umVG1VVLsp6ZEC4gBHIZZIje1wyE3Hzi X-Proofpoint-ORIG-GUID: umVG1VVLsp6ZEC4gBHIZZIje1wyE3Hzi X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxlogscore=999 spamscore=0 mlxscore=0 malwarescore=0 suspectscore=0 phishscore=0 priorityscore=1501 clxscore=1015 bulkscore=0 lowpriorityscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501080067 Content-Type: text/plain; charset="utf-8" Utilized chip info to replace enum chips to cater similar devices with different configurations. Signed-off-by: John Erasmus Mari Geronimo --- drivers/hwmon/max31827.c | 86 ++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/hwmon/max31827.c b/drivers/hwmon/max31827.c index 48e8f8ba4..5d319d401 100644 --- a/drivers/hwmon/max31827.c +++ b/drivers/hwmon/max31827.c @@ -47,12 +47,6 @@ #define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000) #define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0) =20 -/* - * The enum passed in the .data pointer of struct of_device_id must - * start with a value !=3D 0 since that is a requirement for using - * device_get_match_data(). - */ -enum chips { max31827 =3D 1, max31828, max31829 }; =20 enum max31827_cnv { MAX31827_CNV_1_DIV_64_HZ =3D 1, @@ -95,6 +89,17 @@ static const u16 max31827_conv_times[] =3D { [MAX31827_RES_12_BIT] =3D MAX31827_12_BIT_CNV_TIME, }; =20 +struct max31827_state; +static const struct max31827_chip_info max31827; +static const struct max31827_chip_info max31828; +static const struct max31827_chip_info max31829; +static const struct max31827_chip_info max31875; + +struct max31827_chip_info { + u8 alarm_pol_default; + u32 fault_q_default; +}; + struct max31827_state { /* * Prevent simultaneous access to the i2c client. @@ -104,6 +109,7 @@ struct max31827_state { bool enable; unsigned int resolution; unsigned int update_interval; + const struct max31827_chip_info *chip_info; }; =20 static const struct regmap_config max31827_regmap =3D { @@ -493,9 +499,9 @@ static struct attribute *max31827_attrs[] =3D { ATTRIBUTE_GROUPS(max31827); =20 static const struct i2c_device_id max31827_i2c_ids[] =3D { - { "max31827", max31827 }, - { "max31828", max31828 }, - { "max31829", max31829 }, + { "max31827", (kernel_ulong_t)&max31827 }, + { "max31828", (kernel_ulong_t)&max31828 }, + { "max31829", (kernel_ulong_t)&max31829 }, { } }; MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids); @@ -506,7 +512,6 @@ static int max31827_init_client(struct max31827_state *= st, struct fwnode_handle *fwnode; unsigned int res =3D 0; u32 data, lsb_idx; - enum chips type; bool prop; int ret; =20 @@ -523,8 +528,6 @@ static int max31827_init_client(struct max31827_state *= st, prop =3D fwnode_property_read_bool(fwnode, "adi,timeout-enable"); res |=3D FIELD_PREP(MAX31827_CONFIGURATION_TIMEOUT_MASK, !prop); =20 - type =3D (enum chips)(uintptr_t)device_get_match_data(dev); - if (fwnode_property_present(fwnode, "adi,alarm-pol")) { ret =3D fwnode_property_read_u32(fwnode, "adi,alarm-pol", &data); if (ret) @@ -535,19 +538,8 @@ static int max31827_init_client(struct max31827_state = *st, /* * Set default value. */ - switch (type) { - case max31827: - case max31828: - res |=3D FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, - MAX31827_ALRM_POL_LOW); - break; - case max31829: - res |=3D FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, - MAX31827_ALRM_POL_HIGH); - break; - default: - return -EOPNOTSUPP; - } + res |=3D FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, + st->chip_info->alarm_pol_default); } =20 if (fwnode_property_present(fwnode, "adi,fault-q")) { @@ -571,19 +563,8 @@ static int max31827_init_client(struct max31827_state = *st, /* * Set default value. */ - switch (type) { - case max31827: - res |=3D FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, - MAX31827_FLT_Q_1); - break; - case max31828: - case max31829: - res |=3D FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, - MAX31827_FLT_Q_4); - break; - default: - return -EOPNOTSUPP; - } + res |=3D FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, + st->chip_info->fault_q_default); } =20 return regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, res); @@ -604,11 +585,25 @@ static const struct hwmon_ops max31827_hwmon_ops =3D { .write =3D max31827_write, }; =20 -static const struct hwmon_chip_info max31827_chip_info =3D { +static const struct hwmon_chip_info max31827_hwmon_chip_info =3D { .ops =3D &max31827_hwmon_ops, .info =3D max31827_info, }; =20 +static const struct max31827_chip_info max31827 =3D { + .alarm_pol_default =3D MAX31827_ALRM_POL_LOW, + .fault_q_default =3D MAX31827_FLT_Q_1, +}; + +static const struct max31827_chip_info max31828 =3D { + .alarm_pol_default =3D MAX31827_ALRM_POL_LOW, + .fault_q_default =3D MAX31827_FLT_Q_4, + +static const struct max31827_chip_info max31829 =3D { + .alarm_pol_default =3D MAX31827_ALRM_POL_HIGH, + .fault_q_default =3D MAX31827_FLT_Q_4, +}; + static int max31827_probe(struct i2c_client *client) { struct device *dev =3D &client->dev; @@ -623,6 +618,10 @@ static int max31827_probe(struct i2c_client *client) if (!st) return -ENOMEM; =20 + st->chip_info =3D device_get_match_data(dev); + if (!st->chip_info) + return -ENODEV; + mutex_init(&st->lock); =20 st->regmap =3D devm_regmap_init_i2c(client, &max31827_regmap); @@ -639,7 +638,7 @@ static int max31827_probe(struct i2c_client *client) return err; =20 hwmon_dev =3D devm_hwmon_device_register_with_info(dev, client->name, st, - &max31827_chip_info, + &max31827_hwmon_chip_info, max31827_groups); =20 return PTR_ERR_OR_ZERO(hwmon_dev); @@ -648,15 +647,15 @@ static int max31827_probe(struct i2c_client *client) static const struct of_device_id max31827_of_match[] =3D { { .compatible =3D "adi,max31827", - .data =3D (void *)max31827 + .data =3D &max31827 }, { .compatible =3D "adi,max31828", - .data =3D (void *)max31828 + .data =3D &max31828 }, { .compatible =3D "adi,max31829", - .data =3D (void *)max31829 + .data =3D &max31829 }, { } }; @@ -672,6 +671,7 @@ static struct i2c_driver max31827_driver =3D { }; module_i2c_driver(max31827_driver); =20 +MODULE_AUTHOR("John Erasmus Mari Geronimo "); MODULE_AUTHOR("Daniel Matyas "); MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver"); MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Fri Dec 19 19:17:15 2025 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0D511E9B2E; Wed, 8 Jan 2025 08:26:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736324781; cv=none; b=BGPHYnB3KbeGIGy48XNMzDiWu7B0hrr6pmzpXh4tf/cyk1wyjvzo5am0nyrTi5S+sS7A4k1C0n42/WqA6Zy89rhjla/AnR07/CQDPJ1YCMIkj7jff89545/C7cRM+siI8qF0s66w7i6AHS4bD6W6keWXbRMytsbf5/C8WT8KT5U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736324781; c=relaxed/simple; bh=a0YPgtylA5E+liBLT4TjoEdEWBwhuBdoUIaX2jDgvlA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=A3LKf5GGypi2rWckF4YZAqI1l4fF03VW5BObyfCy60A9x6pAu1KatKL0cprYpdOy9bYeZO38yrMAbCdNIBWlSDSYcsq0B/GHDkAGePTaXj1cD/sKhe+2FpAMWPrglfpSiVR82XAiK/g7QhKFTDus1dzFog6aFkgo04Nf7HErJAo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=glCFowiw; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="glCFowiw" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 50870mPu027777; Wed, 8 Jan 2025 03:26:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=g/7tl Lr3+6QuviIsykKK4MGYluAM3YsXVNwTtvuF/3k=; b=glCFowiwkeXC+ryRo8wA+ oUDofR1477Q3yJluvjbgHYPexYlg9BS47EyAiIjZRWQ48t2QM0viBh8YWA36yuRt 2Fb95+4YsZXHIL2V7ifSyqp2WGfcNo57t8kM/ViWwbxQ0oGH1cPQGtqcOinQUVfr bjNvTEt96PKDSWkLxD47VN7b2eNOaSoZTHhRzUCwu1K2TLlzHzYiZGboYtabJUGv pXiaeax2hifnx860qOiP2pEaMzIPLpEWXprPj5jsYCf/oCSUFplQ16MxldlvDvGS pdCY3E/EGmVh2wfHJtaJ+MsFcORO1+FjL1xfMEcfFbnG9bRvvYp11fMQzyo6zcdM A== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 441fw19gca-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 08 Jan 2025 03:26:03 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 5088Q2cK037237 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 8 Jan 2025 03:26:02 -0500 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Wed, 8 Jan 2025 03:26:02 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Wed, 8 Jan 2025 03:26:02 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Wed, 8 Jan 2025 03:26:02 -0500 Received: from JGERONI2-L01.ad.analog.com (JGERONI2-L01.ad.analog.com [10.117.223.6]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5088PfdP026945; Wed, 8 Jan 2025 03:25:54 -0500 From: John Erasmus Mari Geronimo To: , , , CC: Jean Delvare , Guenter Roeck , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Jonathan Corbet Subject: [PATCH 2/3] dt-bindings: hwmon: adi,max31827: add MAX31875 Date: Wed, 8 Jan 2025 16:25:30 +0800 Message-ID: <20250108082531.15467-3-johnerasmusmari.geronimo@analog.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250108082531.15467-1-johnerasmusmari.geronimo@analog.com> References: <20250108082531.15467-1-johnerasmusmari.geronimo@analog.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: 5PJ1x1a4xXl9Y_TmZb3bfX053EZd-3fk X-Proofpoint-ORIG-GUID: 5PJ1x1a4xXl9Y_TmZb3bfX053EZd-3fk X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 adultscore=0 clxscore=1015 bulkscore=0 phishscore=0 suspectscore=0 spamscore=0 mlxlogscore=999 priorityscore=1501 malwarescore=0 lowpriorityscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501080067 Content-Type: text/plain; charset="utf-8" Add max31875 to dt-bindings of max31827 MAX31875 is low-power I2C temperature sensor similar to MAX31827 Signed-off-by: John Erasmus Mari Geronimo --- .../bindings/hwmon/adi,max31827.yaml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml b/Do= cumentation/devicetree/bindings/hwmon/adi,max31827.yaml index f60e06ab7..9363fa371 100644 --- a/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml +++ b/Documentation/devicetree/bindings/hwmon/adi,max31827.yaml @@ -4,16 +4,19 @@ $id: http://devicetree.org/schemas/hwmon/adi,max31827.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# =20 -title: Analog Devices MAX31827, MAX31828, MAX31829 Low-Power Temperature S= witch +title: Analog Devices MAX31827, MAX31828, MAX31829, MAX31875 Low-Power Tem= perature Switch =20 maintainers: - - Daniel Matyas + - John Erasmus Mari Geronimo =20 description: | Analog Devices MAX31827, MAX31828, MAX31829 Low-Power Temperature Switch= with I2C Interface https://www.analog.com/media/en/technical-documentation/data-sheets/MAX3= 1827-MAX31829.pdf =20 + Analog Devices MAX31875 Low-Power I2C Temperature Sensor in WLP Package + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX3= 1875.pdf + properties: compatible: oneOf: @@ -22,6 +25,7 @@ properties: - enum: - adi,max31828 - adi,max31829 + - adi,max31875 - const: adi,max31827 =20 reg: @@ -93,6 +97,16 @@ allOf: adi,fault-q: default: 4 =20 + - if: + properties: + compatible: + contains: + const: adi,max31875 + + then: + properties: + adi,fault-q: + enum: [1, 2, 4, 6] =20 required: - compatible --=20 2.34.1 From nobody Fri Dec 19 19:17:15 2025 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 315901B0433; Wed, 8 Jan 2025 08:26:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736324783; cv=none; b=rkYAW7wAFftMuMQTpYb/MZXAcnHqCq49TK2BuoFNjOv0E/M3SOkMAEFioklgKAZ6YGPte8bDD6K9TNnMRbrjKBw25NQlltdSbSLvdfrFythPHrMNzPPfI11yuTrq/6zAyUDW5Stwik3SPa/0+xQ9ouReU9KgtvaVo7rY5FpAXpE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736324783; c=relaxed/simple; bh=ZukFbVRijDYOIz/mvmZrDFov2e1yeYsY8vXpRq3T4bQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kiaUPUKKbDYtbtqbpldoFWBpCRG7f44I3InYnloQySZ7QqQfd9KJThT6XsbR46HJyEyopLhT4UvIBW9jd0W77TsyK8g+NbTX7IZXaXS1P8IC5eUEmYGzUT0stgqZEEeNO/FAa5qjnF8myp9m+bqrwuHK1wG6YBL7OZ1c+LY2Pvc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=fR+m10Di; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="fR+m10Di" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5087u6oW006016; Wed, 8 Jan 2025 03:26:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=x7y8N YBwvSfAFQlXvrHh6PN2IpZtqKRGW16XGIH9k4Q=; b=fR+m10DizlRODNQPY2JO9 jnYrUSmH6Kb851IgEiZyp8EatBl/FexPNqoniZe0hnj4MOf1KOyuNS9PrpKwfFls dFg+NN0NljrAwHitye3wszsiG3c683eOTWKizKtGrbaIh8jfn+Vj7qzg9hbn2eTA W4wPSagUbpzOorM6y1EHw0G9fLV/iMptxiIey/u7VCvQbDGIjzdLpqkuPyHAgjVh 5C5IYbDEuYb63TnEvPM7H19t1tPsmIk7hXkdTh4oRtIaZgkhrGJvRo46mNdeJTOe LFeJ8RytS70uDyfCiV8S4C+Q4ukPStZr9lrYWwSdhC0uDg+RbyYordCtWAhpssLZ g== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 441ndj03vf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 08 Jan 2025 03:26:04 -0500 (EST) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 5088Q3Rq037244 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 8 Jan 2025 03:26:03 -0500 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Wed, 8 Jan 2025 03:26:03 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Wed, 8 Jan 2025 03:26:03 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Wed, 8 Jan 2025 03:26:03 -0500 Received: from JGERONI2-L01.ad.analog.com (JGERONI2-L01.ad.analog.com [10.117.223.6]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5088PfdQ026945; Wed, 8 Jan 2025 03:25:58 -0500 From: John Erasmus Mari Geronimo To: , , , CC: Jean Delvare , Guenter Roeck , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Jonathan Corbet Subject: [PATCH 3/3] hwmon: (max31827) add max31875 support Date: Wed, 8 Jan 2025 16:25:31 +0800 Message-ID: <20250108082531.15467-4-johnerasmusmari.geronimo@analog.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250108082531.15467-1-johnerasmusmari.geronimo@analog.com> References: <20250108082531.15467-1-johnerasmusmari.geronimo@analog.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: mC0QLgk9PRWtWPrFMsTVVXDcJBu8M_kV X-Proofpoint-ORIG-GUID: mC0QLgk9PRWtWPrFMsTVVXDcJBu8M_kV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 adultscore=0 suspectscore=0 phishscore=0 clxscore=1015 impostorscore=0 spamscore=0 bulkscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501080067 Content-Type: text/plain; charset="utf-8" Add support for max31875 which is similar to max31827 and other chips of the series. Signed-off-by: John Erasmus Mari Geronimo --- Documentation/hwmon/max31827.rst | 40 ++- drivers/hwmon/max31827.c | 506 +++++++++++++++++++++++++++++-- 2 files changed, 516 insertions(+), 30 deletions(-) diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max3182= 7.rst index 6cc5088b2..f8468cb0b 100644 --- a/Documentation/hwmon/max31827.rst +++ b/Documentation/hwmon/max31827.rst @@ -29,9 +29,18 @@ Supported chips: =20 Datasheet: Publicly available at the Analog Devices website =20 + * Maxim MAX31875 + + Prefix: 'max31875' + + Addresses scanned: I2C 0x48 - 0x4f + + Datasheet: Publicly available at the Analog Devices website + =20 Authors: - Daniel Matyas + - John Erasmus Mari Geronimo =20 Description ----------- @@ -45,13 +54,20 @@ configured to operate in the same manner with 1 write o= peration to the configuration register. From here on, we will refer to all these chips as MAX31827. =20 -MAX31827 implements a temperature sensor with a 6 WLP packaging scheme. Th= is -sensor measures the temperature of the chip itself. +This driver also supports the MAX31875. Its fault queue is set to 1 and it= has +no alarm polarity. + +MAX31827 implements a temperature sensor with a 6 WLP packaging scheme whi= le +MAX31875 has a 4 WLP packaging scheme. This sensor measures the temperatur= e of +the chip itself. =20 MAX31827 has low and over temperature alarms with an effective value and a hysteresis value: -40 and -30 degrees for under temperature alarm and +100= and +90 degrees for over temperature alarm. =20 +MAX31875 has only an over temperature alarm with an effective value and a +hysteresis value: +80 and +75 degrees. + The alarm can be configured in comparator and interrupt mode from the devicetree. In Comparator mode, the OT/UT status bits have a value of 1 wh= en the temperature rises above the TH value or falls below TL, which is also subj= ect to @@ -75,7 +91,8 @@ it is recommended to perform a read of the configuration/= status register to clear the status bits before changing the operating mode. =20 The conversions can be manual with the one-shot functionality and automati= c with -a set frequency. When powered on, the chip measures temperatures with 1 co= nv/s. +a set frequency. When powered on, the MAX31827 measures temperatures with 1 +conv/s while the MAX31875 measures temperatures with 0.25 conv/s or 1 conv= /4s. The conversion rate can be modified with update_interval attribute of the = chip. Conversion/second =3D 1/update_interval. Thus, the available options accor= ding to the data sheet are: @@ -83,11 +100,13 @@ the data sheet are: - 64000 (ms) =3D 1 conv/64 sec - 32000 (ms) =3D 1 conv/32 sec - 16000 (ms) =3D 1 conv/16 sec -- 4000 (ms) =3D 1 conv/4 sec -- 1000 (ms) =3D 1 conv/sec (default) +- 4000 (ms) =3D 1 conv/4 sec (MAX31875 default) +- 1000 (ms) =3D 1 conv/sec (MAX31827 default) - 250 (ms) =3D 4 conv/sec - 125 (ms) =3D 8 conv/sec =20 +The MAX31875 only supports the last four values above. + Enabling the device when it is already enabled has the side effect of sett= ing the conversion frequency to 1 conv/s. The conversion time varies depending= on the resolution. @@ -97,16 +116,16 @@ available resolutions are: =20 - 8 bit -> 8.75 ms conversion time - 9 bit -> 17.5 ms conversion time -- 10 bit -> 35 ms conversion time -- 12 bit (default) -> 140 ms conversion time +- 10 bit (MAX31875 default) -> 35 ms conversion time +- 12 bit (MAX31827 default) -> 140 ms conversion time =20 There is a temp1_resolution attribute which indicates the unit change in t= he input temperature in milli-degrees C. =20 - 1000 mC -> 8 bit - 500 mC -> 9 bit -- 250 mC -> 10 bit -- 62 mC -> 12 bit (default) - actually this is 62.5, but the fil returns 62 +- 250 mC -> 10 bit (MAX31875 default) +- 62 mC -> 12 bit (MAX31827 default) - actually this is 62.5, but the fil = returns 62 =20 When chip is in shutdown mode and a read operation is requested, one-shot = is triggered, the device waits for ms, and only after that = is @@ -125,7 +144,8 @@ Bus timeout resets the I2C-compatible interface when SC= L is low for more than =20 Alarm polarity determines if the active state of the alarm is low or high.= The behavior for both settings is dependent on the Fault Queue setting. The AL= ARM -pin is an open-drain output and requires a pullup resistor to operate. +pin is an open-drain output and requires a pullup resistor to operate. The +MAX31875 does not have this feature. =20 The Fault Queue bits select how many consecutive temperature faults must o= ccur before overtemperature or undertemperature faults are indicated in the diff --git a/drivers/hwmon/max31827.c b/drivers/hwmon/max31827.c index 5d319d401..0c6211e03 100644 --- a/drivers/hwmon/max31827.c +++ b/drivers/hwmon/max31827.c @@ -22,6 +22,10 @@ #define MAX31827_TH_HYST_REG 0x8 #define MAX31827_TL_HYST_REG 0xA =20 +#define MAX31875_CONFIGURATION_REG 0x1 +#define MAX31875_TH_HYST_REG 0x2 +#define MAX31875_TH_REG 0x3 + #define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0) #define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1) #define MAX31827_CONFIGURATION_PEC_EN_MASK BIT(4) @@ -33,6 +37,13 @@ #define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14) #define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15) =20 +#define MAX31875_CONFIGURATION_CNV_RATE_MASK GENMASK(2, 1) +#define MAX31875_CONFIGURATION_PEC_EN_MASK BIT(3) +#define MAX31875_CONFIGURATION_TIMEOUT_MASK BIT(4) +#define MAX31875_CONFIGURATION_RESOLUTION_MASK GENMASK(6, 5) +#define MAX31875_CONFIGURATION_SHUTDOWN_MASK BIT(8) +#define MAX31875_CONFIGURATION_FLT_Q_MASK GENMASK(12, 11) + #define MAX31827_ALRM_POL_LOW 0x0 #define MAX31827_ALRM_POL_HIGH 0x1 #define MAX31827_FLT_Q_1 0x0 @@ -47,6 +58,10 @@ #define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000) #define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0) =20 +#define MAX31875_16_BIT_TO_M_DGR(x) (sign_extend32(x, 15) * 1000 / 256) +#define MAX31875_M_DGR_TO_16_BIT(x) (((x) << 8) / 1000) +#define MAX31875_DEVICE_ENABLE(x) \ + FIELD_PREP(MAX31875_CONFIGURATION_SHUTDOWN_MASK, !(x)) =20 enum max31827_cnv { MAX31827_CNV_1_DIV_64_HZ =3D 1, @@ -58,6 +73,13 @@ enum max31827_cnv { MAX31827_CNV_8_HZ, }; =20 +enum max31875_cnv { + MAX31875_CNV_1_DIV_4_HZ, + MAX31875_CNV_1_HZ, + MAX31875_CNV_4_HZ, + MAX31875_CNV_8_HZ, +}; + static const u16 max31827_conversions[] =3D { [MAX31827_CNV_1_DIV_64_HZ] =3D 64000, [MAX31827_CNV_1_DIV_32_HZ] =3D 32000, @@ -68,6 +90,13 @@ static const u16 max31827_conversions[] =3D { [MAX31827_CNV_8_HZ] =3D 125, }; =20 +static const u16 max31875_conversions[] =3D { + [MAX31875_CNV_1_DIV_4_HZ] =3D 4000, + [MAX31875_CNV_1_HZ] =3D 1000, + [MAX31875_CNV_4_HZ] =3D 250, + [MAX31875_CNV_8_HZ] =3D 125, +}; + enum max31827_resolution { MAX31827_RES_8_BIT =3D 0, MAX31827_RES_9_BIT, @@ -98,6 +127,15 @@ static const struct max31827_chip_info max31875; struct max31827_chip_info { u8 alarm_pol_default; u32 fault_q_default; + const struct regmap_config *regmap; + const struct hwmon_chip_info *hwmon_chip_info; + int (*init_client)(struct max31827_state *st, struct device *dev); + ssize_t (*show_resolution)(struct max31827_state *st, + struct device_attribute *devattr, + char *buf); + ssize_t (*store_resolution)(struct max31827_state *st, + struct device_attribute *devattr, + const char *buf, size_t count); }; =20 struct max31827_state { @@ -118,8 +156,14 @@ static const struct regmap_config max31827_regmap =3D { .max_register =3D 0xA, }; =20 -static int shutdown_write(struct max31827_state *st, unsigned int reg, - unsigned int mask, unsigned int val) +static const struct regmap_config max31875_regmap =3D { + .reg_bits =3D 8, + .val_bits =3D 16, + .max_register =3D 0x3, +}; + +static int max31827_shutdown_write(struct max31827_state *st, unsigned int= reg, + unsigned int mask, unsigned int val) { unsigned int cfg; unsigned int cnv_rate; @@ -171,12 +215,68 @@ static int shutdown_write(struct max31827_state *st, = unsigned int reg, return ret; } =20 -static int write_alarm_val(struct max31827_state *st, unsigned int reg, - long val) +static int max31875_shutdown_write(struct max31827_state *st, unsigned int= reg, + unsigned int mask, unsigned int val) +{ + int ret; + + /* + * Before the Temperature Threshold Alarm, Alarm Hysteresis Threshold + * and Resolution bits from Configuration register are changed over I2C, + * the part must be in shutdown mode. + * + * Mutex is used to ensure, that some other process doesn't change the + * configuration register. + */ + mutex_lock(&st->lock); + + if (!st->enable) { + if (!mask) + ret =3D regmap_write(st->regmap, reg, val); + else + ret =3D regmap_update_bits(st->regmap, reg, mask, val); + goto unlock; + } + + ret =3D regmap_update_bits(st->regmap, MAX31875_CONFIGURATION_REG, + MAX31875_CONFIGURATION_SHUTDOWN_MASK, + FIELD_PREP(MAX31875_CONFIGURATION_SHUTDOWN_MASK, + 1)); + if (ret) + goto unlock; + + if (!mask) + ret =3D regmap_write(st->regmap, reg, val); + else + ret =3D regmap_update_bits(st->regmap, reg, mask, val); + + if (ret) + goto unlock; + + ret =3D regmap_update_bits(st->regmap, MAX31875_CONFIGURATION_REG, + MAX31875_CONFIGURATION_SHUTDOWN_MASK, + FIELD_PREP(MAX31875_CONFIGURATION_SHUTDOWN_MASK, + 0)); + +unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int max31827_write_alarm_val(struct max31827_state *st, unsigned in= t reg, + long val) { val =3D MAX31827_M_DGR_TO_16_BIT(val); =20 - return shutdown_write(st, reg, 0, val); + return max31827_shutdown_write(st, reg, 0, val); +} + +static int max31875_write_alarm_val(struct max31827_state *st, unsigned in= t reg, + long val) +{ + val =3D MAX31875_M_DGR_TO_16_BIT(val); + + return max31875_shutdown_write(st, reg, 0, val); } =20 static umode_t max31827_is_visible(const void *state, @@ -344,6 +444,119 @@ static int max31827_read(struct device *dev, enum hwm= on_sensor_types type, return ret; } =20 +static int max31875_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct max31827_state *st =3D dev_get_drvdata(dev); + unsigned int uval; + int ret =3D 0; + + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_enable: + ret =3D regmap_read(st->regmap, + MAX31875_CONFIGURATION_REG, &uval); + if (ret) + break; + + uval =3D FIELD_GET(MAX31875_CONFIGURATION_SHUTDOWN_MASK, + uval); + *val =3D !uval; + + break; + case hwmon_temp_input: + mutex_lock(&st->lock); + + if (!st->enable) { + /* + * This operation requires mutex protection, + * because the chip configuration should not + * be changed during the conversion process. + */ + + ret =3D regmap_update_bits(st->regmap, + MAX31875_CONFIGURATION_REG, + MAX31827_CONFIGURATION_1SHOT_MASK, + 1); + if (ret) { + mutex_unlock(&st->lock); + return ret; + } + msleep(max31827_conv_times[st->resolution]); + } + + /* + * For 12-bit resolution the conversion time is 140 ms, + * thus an additional 15 ms is needed to complete the + * conversion: 125 ms + 15 ms =3D 140 ms + */ + if (max31827_resolutions[st->resolution] =3D=3D 12 && + st->update_interval =3D=3D 125) + usleep_range(15000, 20000); + + ret =3D regmap_read(st->regmap, MAX31827_T_REG, &uval); + + mutex_unlock(&st->lock); + + if (ret) + break; + + *val =3D MAX31875_16_BIT_TO_M_DGR(uval); + + break; + case hwmon_temp_max: + ret =3D regmap_read(st->regmap, MAX31875_TH_REG, &uval); + if (ret) + break; + + *val =3D MAX31875_16_BIT_TO_M_DGR(uval); + break; + case hwmon_temp_max_hyst: + ret =3D regmap_read(st->regmap, MAX31875_TH_HYST_REG, + &uval); + if (ret) + break; + + *val =3D MAX31875_16_BIT_TO_M_DGR(uval); + break; + case hwmon_temp_max_alarm: + ret =3D regmap_read(st->regmap, + MAX31875_CONFIGURATION_REG, &uval); + if (ret) + break; + + *val =3D FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK, + uval); + break; + default: + ret =3D -EOPNOTSUPP; + break; + } + + break; + + case hwmon_chip: + if (attr =3D=3D hwmon_chip_update_interval) { + ret =3D regmap_read(st->regmap, + MAX31827_CONFIGURATION_REG, &uval); + if (ret) + break; + + uval =3D FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK, + uval); + *val =3D max31827_conversions[uval]; + } + break; + + default: + ret =3D -EOPNOTSUPP; + break; + } + + return ret; +} + static int max31827_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long val) { @@ -378,16 +591,16 @@ static int max31827_write(struct device *dev, enum hw= mon_sensor_types type, return ret; =20 case hwmon_temp_max: - return write_alarm_val(st, MAX31827_TH_REG, val); + return max31827_write_alarm_val(st, MAX31827_TH_REG, val); =20 case hwmon_temp_max_hyst: - return write_alarm_val(st, MAX31827_TH_HYST_REG, val); + return max31827_write_alarm_val(st, MAX31827_TH_HYST_REG, val); =20 case hwmon_temp_min: - return write_alarm_val(st, MAX31827_TL_REG, val); + return max31827_write_alarm_val(st, MAX31827_TL_REG, val); =20 case hwmon_temp_min_hyst: - return write_alarm_val(st, MAX31827_TL_HYST_REG, val); + return max31827_write_alarm_val(st, MAX31827_TL_HYST_REG, val); =20 default: return -EOPNOTSUPP; @@ -437,11 +650,94 @@ static int max31827_write(struct device *dev, enum hw= mon_sensor_types type, } } =20 -static ssize_t temp1_resolution_show(struct device *dev, - struct device_attribute *devattr, - char *buf) +static int max31875_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) { struct max31827_state *st =3D dev_get_drvdata(dev); + int res =3D 0; + int ret; + + switch (type) { + case hwmon_temp: + switch (attr) { + case hwmon_temp_enable: + if (val >> 1) + return -EOPNOTSUPP; + + mutex_lock(&st->lock); + /** + * The chip should not be enabled while a conversion is + * performed. Neither should the chip be enabled when + * the alarm values are changed. + */ + + st->enable =3D val; + + ret =3D regmap_update_bits(st->regmap, + MAX31875_CONFIGURATION_REG, + MAX31875_CONFIGURATION_SHUTDOWN_MASK, + MAX31875_DEVICE_ENABLE(val)); + + mutex_unlock(&st->lock); + + return ret; + + case hwmon_temp_max: + return max31875_write_alarm_val(st, MAX31875_TH_REG, val); + + case hwmon_temp_max_hyst: + return max31875_write_alarm_val(st, MAX31875_TH_HYST_REG, val); + + default: + return -EOPNOTSUPP; + } + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + if (!st->enable) + return -EOPNOTSUPP; + + /* + * Convert the desired conversion rate into register + * bits. res is already initialized with 0. + * + * This was inspired by lm73 driver. + */ + while (res < ARRAY_SIZE(max31875_conversions) && + val < max31875_conversions[res]) + res++; + + if (res =3D=3D ARRAY_SIZE(max31875_conversions)) + res =3D ARRAY_SIZE(max31875_conversions) - 1; + + res =3D FIELD_PREP(MAX31875_CONFIGURATION_CNV_RATE_MASK, + res); + + ret =3D regmap_update_bits(st->regmap, + MAX31875_CONFIGURATION_REG, + MAX31875_CONFIGURATION_CNV_RATE_MASK, + res); + if (ret) + return ret; + + st->update_interval =3D val; + return 0; + case hwmon_chip_pec: + return regmap_update_bits(st->regmap, MAX31875_CONFIGURATION_REG, + MAX31875_CONFIGURATION_PEC_EN_MASK, + val ? MAX31875_CONFIGURATION_PEC_EN_MASK : 0); + default: + return -EOPNOTSUPP; + } + default: + return -EOPNOTSUPP; + } +} + +static ssize_t max31827_temp1_resolution_show(struct max31827_state *st, + struct device_attribute *devattr, + char *buf) +{ unsigned int val; int ret; =20 @@ -454,11 +750,26 @@ static ssize_t temp1_resolution_show(struct device *d= ev, return scnprintf(buf, PAGE_SIZE, "%u\n", max31827_resolutions[val]); } =20 -static ssize_t temp1_resolution_store(struct device *dev, - struct device_attribute *devattr, - const char *buf, size_t count) +static ssize_t max31875_temp1_resolution_show(struct max31827_state *st, + struct device_attribute *devattr, + char *buf) +{ + unsigned int val; + int ret; + + ret =3D regmap_read(st->regmap, MAX31875_CONFIGURATION_REG, &val); + if (ret) + return ret; + + val =3D FIELD_GET(MAX31875_CONFIGURATION_RESOLUTION_MASK, val); + + return scnprintf(buf, PAGE_SIZE, "%u\n", max31827_resolutions[val]); +} + +static ssize_t max31827_temp1_resolution_store(struct max31827_state *st, + struct device_attribute *devattr, + const char *buf, size_t count) { - struct max31827_state *st =3D dev_get_drvdata(dev); unsigned int idx =3D 0; unsigned int val; int ret; @@ -482,7 +793,7 @@ static ssize_t temp1_resolution_store(struct device *de= v, =20 st->resolution =3D idx; =20 - ret =3D shutdown_write(st, MAX31827_CONFIGURATION_REG, + ret =3D max31827_shutdown_write(st, MAX31827_CONFIGURATION_REG, MAX31827_CONFIGURATION_RESOLUTION_MASK, FIELD_PREP(MAX31827_CONFIGURATION_RESOLUTION_MASK, idx)); @@ -490,6 +801,59 @@ static ssize_t temp1_resolution_store(struct device *d= ev, return ret ? ret : count; } =20 +static ssize_t max31875_temp1_resolution_store(struct max31827_state *st, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned int idx =3D 0; + unsigned int val; + int ret; + + ret =3D kstrtouint(buf, 10, &val); + if (ret) + return ret; + + /* + * Convert the desired resolution into register + * bits. idx is already initialized with 0. + * + * This was inspired by lm73 driver. + */ + while (idx < ARRAY_SIZE(max31827_resolutions) && + val < max31827_resolutions[idx]) + idx++; + + if (idx =3D=3D ARRAY_SIZE(max31827_resolutions)) + idx =3D ARRAY_SIZE(max31827_resolutions) - 1; + + st->resolution =3D idx; + + ret =3D max31875_shutdown_write(st, MAX31875_CONFIGURATION_REG, + MAX31875_CONFIGURATION_RESOLUTION_MASK, + FIELD_PREP(MAX31875_CONFIGURATION_RESOLUTION_MASK, + idx)); + + return ret ? ret : count; +} + +static ssize_t temp1_resolution_show(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct max31827_state *st =3D dev_get_drvdata(dev); + + return st->chip_info->show_resolution(st, devattr, buf); +} + +static ssize_t temp1_resolution_store(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct max31827_state *st =3D dev_get_drvdata(dev); + + return st->chip_info->store_resolution(st, devattr, buf, count); +} + static DEVICE_ATTR_RW(temp1_resolution); =20 static struct attribute *max31827_attrs[] =3D { @@ -502,6 +866,7 @@ static const struct i2c_device_id max31827_i2c_ids[] = =3D { { "max31827", (kernel_ulong_t)&max31827 }, { "max31828", (kernel_ulong_t)&max31828 }, { "max31829", (kernel_ulong_t)&max31829 }, + { "max31875", (kernel_ulong_t)&max31875 }, { } }; MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids); @@ -570,6 +935,59 @@ static int max31827_init_client(struct max31827_state = *st, return regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, res); } =20 +static int max31875_init_client(struct max31827_state *st, + struct device *dev) +{ + struct fwnode_handle *fwnode; + unsigned int res =3D 0; + u32 data; + bool prop; + int ret; + + fwnode =3D dev_fwnode(dev); + + st->enable =3D true; + res |=3D MAX31875_DEVICE_ENABLE(1); + + res |=3D MAX31875_CONFIGURATION_RESOLUTION_MASK; + + prop =3D fwnode_property_read_bool(fwnode, "adi,comp-int"); + res |=3D FIELD_PREP(MAX31827_CONFIGURATION_COMP_INT_MASK, prop); + + prop =3D fwnode_property_read_bool(fwnode, "adi,timeout-enable"); + res |=3D FIELD_PREP(MAX31875_CONFIGURATION_TIMEOUT_MASK, !prop); + + if (fwnode_property_present(fwnode, "adi,fault-q")) { + ret =3D fwnode_property_read_u32(fwnode, "adi,fault-q", &data); + if (ret) + return ret; + + /* + * Convert the desired fault queue into register bits. + */ + switch (data) { + case 1: + case 2: + case 4: + case 6: + res |=3D FIELD_PREP(MAX31875_CONFIGURATION_FLT_Q_MASK, + data >> 1); + break; + default: + return dev_err_probe(dev, -EINVAL, + "Invalid data in adi,fault-q\n"); + } + } else { + /* + * Set default value. + */ + res |=3D FIELD_PREP(MAX31875_CONFIGURATION_FLT_Q_MASK, + st->chip_info->fault_q_default); + } + + return regmap_write(st->regmap, MAX31875_CONFIGURATION_REG, res); +} + static const struct hwmon_channel_info *max31827_info[] =3D { HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM | @@ -579,6 +997,14 @@ static const struct hwmon_channel_info *max31827_info[= ] =3D { NULL, }; =20 +static const struct hwmon_channel_info *max31875_info[] =3D { + HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | + HWMON_T_MAX | HWMON_T_MAX_HYST | + HWMON_T_MAX_ALARM), + HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL | HWMON_C_PEC), + NULL, +}; + static const struct hwmon_ops max31827_hwmon_ops =3D { .is_visible =3D max31827_is_visible, .read =3D max31827_read, @@ -590,18 +1016,54 @@ static const struct hwmon_chip_info max31827_hwmon_c= hip_info =3D { .info =3D max31827_info, }; =20 +static const struct hwmon_ops max31875_hwmon_ops =3D { + .is_visible =3D max31827_is_visible, + .read =3D max31875_read, + .write =3D max31875_write, +}; + +static const struct hwmon_chip_info max31875_hwmon_chip_info =3D { + .ops =3D &max31875_hwmon_ops, + .info =3D max31875_info, +}; + static const struct max31827_chip_info max31827 =3D { .alarm_pol_default =3D MAX31827_ALRM_POL_LOW, .fault_q_default =3D MAX31827_FLT_Q_1, + .regmap =3D &max31827_regmap, + .hwmon_chip_info =3D &max31827_hwmon_chip_info, + .init_client =3D max31827_init_client, + .show_resolution =3D max31827_temp1_resolution_show, + .store_resolution =3D max31827_temp1_resolution_store, }; =20 static const struct max31827_chip_info max31828 =3D { .alarm_pol_default =3D MAX31827_ALRM_POL_LOW, .fault_q_default =3D MAX31827_FLT_Q_4, + .regmap =3D &max31827_regmap, + .hwmon_chip_info =3D &max31827_hwmon_chip_info, + .init_client =3D max31827_init_client, + .show_resolution =3D max31827_temp1_resolution_show, + .store_resolution =3D max31827_temp1_resolution_store, +}; =20 static const struct max31827_chip_info max31829 =3D { .alarm_pol_default =3D MAX31827_ALRM_POL_HIGH, .fault_q_default =3D MAX31827_FLT_Q_4, + .regmap =3D &max31827_regmap, + .hwmon_chip_info =3D &max31827_hwmon_chip_info, + .init_client =3D max31827_init_client, + .show_resolution =3D max31827_temp1_resolution_show, + .store_resolution =3D max31827_temp1_resolution_store, +}; + +static const struct max31827_chip_info max31875 =3D { + .fault_q_default =3D MAX31827_FLT_Q_1, + .regmap =3D &max31875_regmap, + .hwmon_chip_info =3D &max31875_hwmon_chip_info, + .init_client =3D max31875_init_client, + .show_resolution =3D max31875_temp1_resolution_show, + .store_resolution =3D max31875_temp1_resolution_store, }; =20 static int max31827_probe(struct i2c_client *client) @@ -624,7 +1086,7 @@ static int max31827_probe(struct i2c_client *client) =20 mutex_init(&st->lock); =20 - st->regmap =3D devm_regmap_init_i2c(client, &max31827_regmap); + st->regmap =3D devm_regmap_init_i2c(client, st->chip_info->regmap); if (IS_ERR(st->regmap)) return dev_err_probe(dev, PTR_ERR(st->regmap), "Failed to allocate regmap.\n"); @@ -633,12 +1095,12 @@ static int max31827_probe(struct i2c_client *client) if (err) return dev_err_probe(dev, err, "failed to enable regulator\n"); =20 - err =3D max31827_init_client(st, dev); + err =3D st->chip_info->init_client(st, dev); if (err) return err; =20 hwmon_dev =3D devm_hwmon_device_register_with_info(dev, client->name, st, - &max31827_hwmon_chip_info, + st->chip_info->hwmon_chip_info, max31827_groups); =20 return PTR_ERR_OR_ZERO(hwmon_dev); @@ -657,6 +1119,10 @@ static const struct of_device_id max31827_of_match[] = =3D { .compatible =3D "adi,max31829", .data =3D &max31829 }, + { + .compatible =3D "adi,max31875", + .data =3D &max31875 + }, { } }; MODULE_DEVICE_TABLE(of, max31827_of_match); --=20 2.34.1