From nobody Fri Oct 10 13:44:21 2025 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (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 2461DA29; Fri, 13 Jun 2025 13:02:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749819765; cv=none; b=Gx8sfgCaW+2mgppT4xF2l/xPl32FXcesBdA4kEcHS1xKnbPHhPnmgBpm1xVEWV0qutr4lyrD4vI8HXTH7NwT2v6j9UpzB1jFRhqLNyqqFspa1UzXSSlUy2b2Ka4tKQYx6q47t2SElXEyeKt7l5Ak778iHufjIK1SKJbTol0ZkjQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749819765; c=relaxed/simple; bh=iDUHzb5KiG2udZG4Gth0ZpjkeGyywdN49zxcOfgKPrQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Jb9EoqazBSDy3RAa71l2GN6vWgn9iYxrdFXDw/TtDJKequuCTgKL1TftLTxDBcv/igqhpNYbAjxRNUsAgh2pF3bUZXaeeZ5uK+hVC/k1tKmC1WcDrb3FTyxjYrzMTzFkfKaeuowNXyVAd6D7vismWRMfNeNcmr2SPGQvfmTidnQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=UUV/8l2l; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="UUV/8l2l" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1749819765; x=1781355765; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iDUHzb5KiG2udZG4Gth0ZpjkeGyywdN49zxcOfgKPrQ=; b=UUV/8l2lWPf3ewvke1n2qago0c/AElDgD+vRIoyjUkIK7xoPdR2+xIwJ kSaeLvxjzGEpSL5pFZklz35lMStMSKNw/1rd7ydMMAAc01N0+s9rhYh5D eDcPFqSzroaatsgFn95P7Wr1XetqqBIu8VeR+9KohpEWpqYR14BnodAem dbM1ssM4xH6VCjCsdDe/3PEl7IoH17KgVGuvXkdR3bDDqx0zYci6rWZdr tzO3epTpChdA+w0HucWoZQNPTNZCGzx5x/KMSdXqd1ZcdbNfQRCEwcx+n 8i5/RfQ+uCDzNg00A4TxxwJKLIQkAxaWGAkAIqFy0GDenk+OfxzxpwXmR g==; X-CSE-ConnectionGUID: Aonm0V6kTF+56eNzH0aNCQ== X-CSE-MsgGUID: 9NF5q4BDT/iTtvAlCk2Uiw== X-IronPort-AV: E=Sophos;i="6.16,233,1744095600"; d="scan'208";a="274154965" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa5.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 13 Jun 2025 06:02:38 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.44; Fri, 13 Jun 2025 06:02:27 -0700 Received: from vduicu-Virtual-Machine.mshome.net (10.10.85.11) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.44 via Frontend Transport; Fri, 13 Jun 2025 06:02:24 -0700 From: To: , , , , , , CC: , , , , Subject: [PATCH v3 1/2] dt-bindings: iio: temperature: add support for MCP998X Date: Fri, 13 Jun 2025 16:02:06 +0300 Message-ID: <20250613130207.8560-2-victor.duicu@microchip.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250613130207.8560-1-victor.duicu@microchip.com> References: <20250613130207.8560-1-victor.duicu@microchip.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 Content-Type: text/plain; charset="utf-8" From: Victor Duicu This is the devicetree schema for Microchip MCP998X/33 and MCP998XD/33D Automotive Temperature Monitor Family. Signed-off-by: Victor Duicu --- .../iio/temperature/microchip,mcp9982.yaml | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/temperature/micro= chip,mcp9982.yaml diff --git a/Documentation/devicetree/bindings/iio/temperature/microchip,mc= p9982.yaml b/Documentation/devicetree/bindings/iio/temperature/microchip,mc= p9982.yaml new file mode 100644 index 000000000000..ec939d463612 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/temperature/microchip,mcp9982.y= aml @@ -0,0 +1,211 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/temperature/microchip,mcp9982.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip MCP998X/33 and MCP998XD/33D Multichannel Automotive + Temperature Monitor Family + +maintainers: + - Victor Duicu + +description: | + The MCP998X/33 and MCP998XD/33D family is a high-accuracy 2-wire multich= annel + automotive temperature monitor. + The datasheet can be found here: + https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/Produc= tDocuments/DataSheets/MCP998X-Family-Data-Sheet-DS20006827.pdf + +properties: + compatible: + enum: + - microchip,mcp9933 + - microchip,mcp9933d + - microchip,mcp9982 + - microchip,mcp9982d + - microchip,mcp9983 + - microchip,mcp9983d + - microchip,mcp9984 + - microchip,mcp9984d + - microchip,mcp9985 + - microchip,mcp9985d + + reg: + maxItems: 1 + + interrupts: + minItems: 2 + maxItems: 2 + + interrupt-names: + description: + -alert-therm is used to handle a HIGH or LOW limit. + -therm-addr is used to handle a THERM limit on chips + without "D" in the name. + -sys-shutdown is used to handle a THERM limit on chips + with "D" in the name. + items: + - const: alert-therm + - const: therm-addr + - const: sys-shutdown + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + microchip,enable-anti-parallel: + description: + Enable anti-parallel diode mode operation. + MCP9984/84D/85/85D and MCP9933/33D support reading two external diod= es + in anti-parallel connection on the same set of pins. + type: boolean + + microchip,beta1: + description: + Set beta compensation value for external channel 1. + <0> 0.050 + <1> 0.066 + <2> 0.087 + <3> 0.114 + <4> 0.150 + <5> 0.197 + <6> 0.260 + <7> 0.342 + <8> 0.449 + <9> 0.591 + <10> 0.778 + <11> 1.024 + <12> 1.348 + <13> 1.773 + <14> 2.333 + <15> Diode_Mode + <16> Auto + - Diode_Mode is used when measuring a discrete thermal diode + or a CPU diode that functions like a discrete thermal diode. + - Auto enables beta auto-detection. The chip monitors + external diode/transistor and determines the optimum + setting. + $ref: /schemas/types.yaml#/definitions/uint32 + default: 16 + + microchip,beta2: + description: + Set beta compensation value for external channel 2. + $ref: /schemas/types.yaml#/definitions/uint32 + default: 16 + + microchip,resistance-comp-ch1-2-enable: + description: + Enable resistance error correction(REC) for external channels 1 and = 2. + The chip internal hardware counterbalances the parasitic resistance = in + series with the external diodes. The compensation can be activated or + disabled in hardware for both channels 1 and 2 at the same time. + type: boolean + + microchip,resistance-comp-ch3-4-enable: + description: + Enable resistance error correction(REC) for external channels 3 and = 4. + The chip internal hardware counterbalances the parasitic resistance = in + series with the external diodes. The compensation can be activated or + disabled in hardware for both channels 3 and 4 at the same time. + type: boolean + + + vdd-supply: true + +patternProperties: + "^channel@[1-4]$": + description: + Represents the external temperature channels to which + a remote diode is connected. + type: object + + properties: + reg: + items: + minimum: 1 + maximum: 4 + + microchip,ideality-factor: + description: + Each channel has an ideality factor. + Beta compensation and resistance error correction automatically + correct for most ideality errors. So ideality factor does not ne= ed + to be adjusted in general. + $ref: /schemas/types.yaml#/definitions/uint32 + default: 18 + + label: + description: Unique name to identify which channel this is. + + required: + - reg + + additionalProperties: false + +required: + - compatible + - reg + - vdd-supply + +allOf: + - if: + properties: + compatible: + contains: + enum: + - microchip,mcp9982d + - microchip,mcp9983d + - microchip,mcp9984d + - microchip,mcp9985d + - microchip,mcp9933d + then: + properties: + interrupts-names: + items: + - const: alert-therm + - const: sys-shutdown + else: + properties: + interrupts-names: + items: + - const: alert-therm + - const: therm-addr + +additionalProperties: false + +examples: + - | + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + temperature-sensor@4c { + compatible =3D "microchip,mcp9985"; + reg =3D <0x4c>; + + #address-cells =3D <1>; + #size-cells =3D <0>; + + microchip,enable-anti-parallel; + microchip,resistance-comp-ch1-2-enable; + microchip,resistance-comp-ch3-4-enable; + microchip,beta1 =3D <16>; + microchip,beta2 =3D <16>; + vdd-supply =3D <&vdd>; + + channel@1 { + reg =3D <1>; + label =3D "CPU Temperature"; + }; + + channel@2 { + reg =3D <2>; + label =3D "GPU Temperature"; + }; + }; + }; + +... --=20 2.48.1 From nobody Fri Oct 10 13:44:21 2025 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (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 110DF60B8A; Fri, 13 Jun 2025 13:02:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749819768; cv=none; b=S2Nq2Sv2/0KU0+vySvFGlhFf0jii4UAdceWCetBmqOll5Bvbct3jUF2OdK1bMyQex27/vixnk4GjWn4RV0/pZwyuNmBPS37CK32K5rLbJ/KzHMJkSwQZ9O7QJgAP5qo34fajSFQ6B5EB+mE3YOEgzgI86OYFj4pX3b5T0aHeAyc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749819768; c=relaxed/simple; bh=2reAc8VrCoNjPEtFIG8NE8GEAn3xRXXZRjTRTsIsR5w=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bEx5MrpWgQ3/bWLYJzYao6BXKjWPz88YM6Et/5FEHiySplHgI1zWOW2jbFMdoijLN9lVEW0kZmbGhyze++6vR/4OjkyP/T6Dd9e1aJLe9AiL7WgwwXZ0bNBi+y27AF82aox4C8vuzlCu8lWGTODOOBw9uQSz8EFgfJbUBQl23Sk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=R4rGG08J; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="R4rGG08J" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1749819767; x=1781355767; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2reAc8VrCoNjPEtFIG8NE8GEAn3xRXXZRjTRTsIsR5w=; b=R4rGG08JzLRdcDv5T11i7pnfTw45a2XFl9JcA4KwBYhxeS/8UXqjm3KJ OTZZX7qJAWfcncLiVOlt+Ywrr+i8eekH7093QX7obCep/IUkYaonpU7HG DFRuOqYRafcVd+bLCn0nRInScV9t6ocn6R3XkbVodXBLuSTBXTdi/R+Nd dIU1wAg3/PPXmVcOgXvZdnW0MEiSvxWw3MkIdXZADnATGVzwK6Iri98Sf XNDeeGAJ/hpxHWDBM7LsnAse/Xn5TN5NAE8/ES8euo1zmmOKCpiw7Aw8j 1u2pQwwkQ+09wPCV9mNSP31JUfA61hx9muCD9OxmENNmi7iZzXgkJVqnq Q==; X-CSE-ConnectionGUID: Q/C0oHGPR/isfC6vMelafQ== X-CSE-MsgGUID: BnTmrFAKR3eOE0al60Rrhw== X-IronPort-AV: E=Sophos;i="6.16,233,1744095600"; d="scan'208";a="274154975" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa5.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 13 Jun 2025 06:02:45 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.44; Fri, 13 Jun 2025 06:02:30 -0700 Received: from vduicu-Virtual-Machine.mshome.net (10.10.85.11) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.44 via Frontend Transport; Fri, 13 Jun 2025 06:02:27 -0700 From: To: , , , , , , CC: , , , , Subject: [PATCH v3 2/2] iio: temperature: add support for MCP998X Date: Fri, 13 Jun 2025 16:02:07 +0300 Message-ID: <20250613130207.8560-3-victor.duicu@microchip.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250613130207.8560-1-victor.duicu@microchip.com> References: <20250613130207.8560-1-victor.duicu@microchip.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 Content-Type: text/plain; charset="utf-8" From: Victor Duicu This is the driver for Microchip MCP998X/33 and MCP998XD/33D Multichannel Automotive Temperature Monitor Family. Signed-off-by: Victor Duicu --- MAINTAINERS | 7 + drivers/iio/temperature/Kconfig | 10 + drivers/iio/temperature/Makefile | 1 + drivers/iio/temperature/mcp9982.c | 778 ++++++++++++++++++++++++++++++ 4 files changed, 796 insertions(+) create mode 100644 drivers/iio/temperature/mcp9982.c diff --git a/MAINTAINERS b/MAINTAINERS index 86a2045ba62e..63573c517603 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15887,6 +15887,13 @@ S: Maintained F: Documentation/devicetree/bindings/iio/adc/microchip,mcp3911.yaml F: drivers/iio/adc/mcp3911.c =20 +MICROCHIP MCP9982 TEMPERATURE DRIVER +M: Victor Duicu +L: linux-iio@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/iio/temperature/microchip,mcp9982.yaml +F: drivers/iio/temperature/mcp9982.c + MICROCHIP MMC/SD/SDIO MCI DRIVER M: Aubin Constans S: Maintained diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kcon= fig index 1244d8e17d50..e72b49f95f86 100644 --- a/drivers/iio/temperature/Kconfig +++ b/drivers/iio/temperature/Kconfig @@ -182,4 +182,14 @@ config MCP9600 This driver can also be built as a module. If so, the module will be called mcp9600. =20 +config MCP9982 + tristate "Microchip Technology MCP9982 driver" + depends on I2C + help + Say yes here to build support for Microchip Technology's MCP998X/= 33 + and MCP998XD/33D Multichannel Automotive Temperature Monitor Fami= ly. + + This driver can also be built as a module. If so, the module + will be called mcp9982. + endmenu diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Mak= efile index 07d6e65709f7..83f5f4bb4ff3 100644 --- a/drivers/iio/temperature/Makefile +++ b/drivers/iio/temperature/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MAX30208) +=3D max30208.o obj-$(CONFIG_MAX31856) +=3D max31856.o obj-$(CONFIG_MAX31865) +=3D max31865.o obj-$(CONFIG_MCP9600) +=3D mcp9600.o +obj-$(CONFIG_MCP9982) +=3D mcp9982.o obj-$(CONFIG_MLX90614) +=3D mlx90614.o obj-$(CONFIG_MLX90632) +=3D mlx90632.o obj-$(CONFIG_MLX90632) +=3D mlx90635.o diff --git a/drivers/iio/temperature/mcp9982.c b/drivers/iio/temperature/mc= p9982.c new file mode 100644 index 000000000000..b1ae77c6e691 --- /dev/null +++ b/drivers/iio/temperature/mcp9982.c @@ -0,0 +1,778 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * IIO driver for MCP998X/33 and MCP998XD/33D Multichannel Automotive Temp= erature Monitor Family + * + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * Author: Victor Duicu + * + * Datasheet can be found here: + * https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/Product= Documents/DataSheets/MCP998X-Family-Data-Sheet-DS20006827.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* MCP9982 Registers */ +#define MCP9982_INT_VALUE_ADDR(index) (2 * (index)) +#define MCP9982_FRAC_VALUE_ADDR(index) (2 * (index) + 1) +#define MCP9982_ONE_SHOT_ADDR 0x0A +#define MCP9982_INTERNAL_HIGH_LIMIT_ADDR 0x0B +#define MCP9982_INTERNAL_LOW_LIMIT_ADDR 0x0C +#define MCP9982_EXT1_HIGH_LIMIT_INT_VALUE_ADDR 0x0D +#define MCP9982_EXT1_HIGH_LIMIT_FRAC_VALUE_ADDR 0x0E +#define MCP9982_EXT1_LOW_LIMIT_INT_VALUE_ADDR 0x0F +#define MCP9982_EXT1_LOW_LIMIT_FRAC_VALUE_ADDR 0x10 +#define MCP9982_INTERNAL_THERM_LIMIT_ADDR 0x1D +#define MCP9982_EXT1_THERM_LIMIT_ADDR 0x1E +#define MCP9982_CFG_ADDR 0x22 +#define MCP9982_CONV_ADDR 0x24 +#define MCP9982_HYS_ADDR 0x25 +#define MCP9982_CONSEC_ALRT_ADDR 0x26 +#define MCP9982_ALRT_CFG_ADDR 0x27 +#define MCP9982_RUNNING_AVG_ADDR 0x28 +#define MCP9982_HOTTEST_CFG_ADDR 0x29 +#define MCP9982_STATUS_ADDR 0x2A +#define MCP9982_EXT_FAULT_STATUS_ADDR 0x2B +#define MCP9982_HIGH_LIMIT_STATUS_ADDR 0x2C +#define MCP9982_LOW_LIMIT_STATUS_ADDR 0x2D +#define MCP9982_THERM_LIMIT_STATUS_ADDR 0x2E +#define MCP9982_HOTTEST_INT_VALUE_ADDR 0x2F +#define MCP9982_HOTTEST_FRAC_VALUE_ADDR 0x30 +#define MCP9982_HOTTEST_STATUS_ADDR 0x31 +#define MCP9982_THERM_SHTDWN_CFG_ADDR 0x32 +#define MCP9982_HRDW_THERM_SHTDWN_LIMIT_ADDR 0x33 +#define MCP9982_EXT_BETA_CFG_ADDR(index) ((index) + 52) +#define MCP9982_EXT_IDEAL_ADDR(index) ((index) + 54) + +/* MCP9982 Bits */ +#define MCP9982_CFG_MSKAL BIT(7) +#define MCP9982_CFG_RS BIT(6) +#define MCP9982_CFG_ATTHM BIT(5) +#define MCP9982_CFG_RECD12 BIT(4) +#define MCP9982_CFG_RECD34 BIT(3) +#define MCP9982_CFG_RANGE BIT(2) +#define MCP9982_CFG_DA_ENA BIT(1) +#define MCP9982_CFG_APDD BIT(0) + +/* The maximum number of channels a member of the family can have */ +#define MCP9982_MAX_NUM_CHANNELS 5 + +#define MCP9982_CHAN(index, si, __address) ({ \ + struct iio_chan_spec __chan =3D { \ + .type =3D IIO_TEMP, \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_all_available =3D BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .info_mask_shared_by_all =3D BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_HYSTERESIS) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .channel =3D index, \ + .address =3D __address, \ + .scan_index =3D si, \ + .scan_type =3D { \ + .sign =3D 'u', \ + .realbits =3D 8, \ + .storagebits =3D 8, \ + }, \ + .indexed =3D 1, \ + }; \ + __chan; \ +}) + +/** + * struct mcp9982_features - features of a mcp9982 instance + * @name: chip's name + * @phys_channels: number of physical channels supported by the chip + */ +struct mcp9982_features { + const char *name; + u8 phys_channels; +}; + +static const struct mcp9982_features mcp9933_chip_config =3D { + .name =3D "mcp9933", + .phys_channels =3D 3, +}; + +static const struct mcp9982_features mcp9933d_chip_config =3D { + .name =3D "mcp9933d", + .phys_channels =3D 3, +}; + +static const struct mcp9982_features mcp9982_chip_config =3D { + .name =3D "mcp9982", + .phys_channels =3D 2, +}; + +static const struct mcp9982_features mcp9982d_chip_config =3D { + .name =3D "mcp9982d", + .phys_channels =3D 2, +}; + +static const struct mcp9982_features mcp9983_chip_config =3D { + .name =3D "mcp9983", + .phys_channels =3D 3, +}; + +static const struct mcp9982_features mcp9983d_chip_config =3D { + .name =3D "mcp9983d", + .phys_channels =3D 3, +}; + +static const struct mcp9982_features mcp9984_chip_config =3D { + .name =3D "mcp9984", + .phys_channels =3D 4, +}; + +static const struct mcp9982_features mcp9984d_chip_config =3D { + .name =3D "mcp9984d", + .phys_channels =3D 4, +}; + +static const struct mcp9982_features mcp9985_chip_config =3D { + .name =3D "mcp9985", + .phys_channels =3D 5, +}; + +static const struct mcp9982_features mcp9985d_chip_config =3D { + .name =3D "mcp9985d", + .phys_channels =3D 5, +}; + +static const unsigned int mcp9982_fractional_values[] =3D { + 0, + 125000, + 250000, + 375000, + 500000, + 625000, + 750000, + 875000, +}; + +static const unsigned int mcp9982_conv_rate[][2] =3D { + { 0, 62500 }, + { 0, 125000 }, + { 0, 250000 }, + { 0, 500000 }, + { 1, 0 }, + { 2, 0 }, + { 4, 0 }, + { 8, 0 }, + { 16, 0 }, + { 32, 0 }, + { 64, 0 }, +}; + +static unsigned int mcp9982_3db_values_map_tbl[11][3][2]; +static const unsigned int mcp9982_sampl_fr[][2] =3D { + { 1, 16 }, + { 1, 8 }, + { 1, 4 }, + { 1, 2 }, + { 1, 1 }, + { 2, 1 }, + { 4, 1 }, + { 8, 1 }, + { 16, 1 }, + { 32, 1 }, + { 64, 1 }, +}; + +static const unsigned int mcp9982_window_size[3] =3D {1, 4, 8}; + +/* + * (Sampling_Frequency * 1000000) / (Window_Size * 2) + */ +static unsigned int mcp9982_calc_all_3db_values(void) +{ + u32 denominator, remainder; + unsigned int i, j; + u64 numerator; + + for (i =3D 0; i < ARRAY_SIZE(mcp9982_window_size); i++) + for (j =3D 0; j < ARRAY_SIZE(mcp9982_sampl_fr); j++) { + numerator =3D MICRO * mcp9982_sampl_fr[j][0]; + denominator =3D 2 * mcp9982_window_size[i] * mcp9982_sampl_fr[j][1]; + remainder =3D do_div(numerator, denominator); + remainder =3D do_div(numerator, MICRO); + mcp9982_3db_values_map_tbl[j][i][0] =3D numerator; + mcp9982_3db_values_map_tbl[j][i][1] =3D remainder; + } + return 0; +} + +/* mcp9982 regmap configuration */ +static const struct regmap_range mcp9982_regmap_wr_ranges[] =3D { + regmap_reg_range(MCP9982_ONE_SHOT_ADDR, MCP9982_EXT1_LOW_LIMIT_FRAC_VALUE= _ADDR), + regmap_reg_range(MCP9982_INTERNAL_THERM_LIMIT_ADDR, MCP9982_EXT1_THERM_LI= MIT_ADDR), + regmap_reg_range(MCP9982_CFG_ADDR, MCP9982_CFG_ADDR), + regmap_reg_range(MCP9982_CONV_ADDR, MCP9982_HOTTEST_CFG_ADDR), + regmap_reg_range(MCP9982_THERM_SHTDWN_CFG_ADDR, MCP9982_THERM_SHTDWN_CFG_= ADDR), + regmap_reg_range(MCP9982_EXT_BETA_CFG_ADDR(0), MCP9982_EXT_IDEAL_ADDR(3)), +}; + +static const struct regmap_access_table mcp9982_regmap_wr_table =3D { + .yes_ranges =3D mcp9982_regmap_wr_ranges, + .n_yes_ranges =3D ARRAY_SIZE(mcp9982_regmap_wr_ranges), +}; + +static const struct regmap_range mcp9982_regmap_rd_ranges[] =3D { + regmap_reg_range(MCP9982_INT_VALUE_ADDR(0), + MCP9982_EXT1_LOW_LIMIT_FRAC_VALUE_ADDR), + regmap_reg_range(MCP9982_INTERNAL_THERM_LIMIT_ADDR, MCP9982_EXT1_THERM_LI= MIT_ADDR), + regmap_reg_range(MCP9982_CFG_ADDR, MCP9982_CFG_ADDR), + regmap_reg_range(MCP9982_CONV_ADDR, MCP9982_EXT_IDEAL_ADDR(3)), +}; + +static const struct regmap_access_table mcp9982_regmap_rd_table =3D { + .yes_ranges =3D mcp9982_regmap_rd_ranges, + .n_yes_ranges =3D ARRAY_SIZE(mcp9982_regmap_rd_ranges), +}; + +static bool mcp9982_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MCP9982_ONE_SHOT_ADDR: + case MCP9982_INTERNAL_HIGH_LIMIT_ADDR: + case MCP9982_INTERNAL_LOW_LIMIT_ADDR: + case MCP9982_EXT1_HIGH_LIMIT_INT_VALUE_ADDR: + case MCP9982_EXT1_HIGH_LIMIT_FRAC_VALUE_ADDR: + case MCP9982_EXT1_LOW_LIMIT_INT_VALUE_ADDR: + case MCP9982_EXT1_LOW_LIMIT_FRAC_VALUE_ADDR: + case MCP9982_INTERNAL_THERM_LIMIT_ADDR: + case MCP9982_EXT1_THERM_LIMIT_ADDR: + case MCP9982_CFG_ADDR: + case MCP9982_CONV_ADDR: + case MCP9982_HYS_ADDR: + case MCP9982_CONSEC_ALRT_ADDR: + case MCP9982_ALRT_CFG_ADDR: + case MCP9982_RUNNING_AVG_ADDR: + case MCP9982_HOTTEST_CFG_ADDR: + case MCP9982_THERM_SHTDWN_CFG_ADDR: + return false; + default: + return true; + } +} + +static const struct regmap_config mcp9982_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .rd_table =3D &mcp9982_regmap_rd_table, + .wr_table =3D &mcp9982_regmap_wr_table, + .volatile_reg =3D mcp9982_is_volatile_reg, +}; + +/** + * struct mcp9992_priv - information about chip parameters + * @regmap: device register map + * @num_channels number of physical channels + * @extended_temp_range use extended temperature range or not + * @recd34_enable state of REC on channels 3 and 4 + * @recd12_enable state of REC on channels 1 and 2 + * @beta_values beta compensation value for external channel 1 and 2 + * @lock synchronize access to driver's state members + * @iio_chan specifications of channels + * @labels labels of the channels + * @ideality_value ideality factor value for each external channel + * @sampl_idx index representing the current sampling frequency + * @dev_name name of the device + * @apdd_enable state of anti-parallel diode mode + */ +struct mcp9982_priv { + struct regmap *regmap; + u8 num_channels; + bool extended_temp_range; + bool recd34_enable; + bool recd12_enable; + unsigned int beta_values[2]; + /* + * Synchronize access to private members, and ensure + * atomicity of consecutive regmap operations. + */ + struct mutex lock; + struct iio_chan_spec *iio_chan; + const char *labels[MCP9982_MAX_NUM_CHANNELS]; + unsigned int ideality_value[4]; + unsigned int sampl_idx; + const char *dev_name; + bool apdd_enable; +}; + +static int mcp9982_read_avail(struct iio_dev *indio_dev, struct iio_chan_s= pec const *chan, + const int **vals, int *type, int *length, long mask) +{ + struct mcp9982_priv *priv =3D iio_priv(indio_dev); + static const int offset[2] =3D {0, -64}; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *type =3D IIO_VAL_INT_PLUS_MICRO; + if (strchr(priv->dev_name, 'd')) { + *vals =3D mcp9982_conv_rate[4]; + *length =3D (ARRAY_SIZE(mcp9982_conv_rate) - 4) * 2; + } else { + *vals =3D mcp9982_conv_rate[0]; + *length =3D ARRAY_SIZE(mcp9982_conv_rate) * 2; + } + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + *type =3D IIO_VAL_INT_PLUS_MICRO; + *vals =3D mcp9982_3db_values_map_tbl[priv->sampl_idx][0]; + *length =3D ARRAY_SIZE(mcp9982_3db_values_map_tbl[priv->sampl_idx]) * 2; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_OFFSET: + *type =3D IIO_VAL_INT; + *vals =3D offset; + *length =3D 2; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int mcp9982_read_raw(struct iio_dev *indio_dev, struct iio_chan_spe= c const *chan, + int *val, int *val2, long mask) +{ + unsigned int index, idx, tmp_reg; + struct mcp9982_priv *priv =3D iio_priv(indio_dev); + int ret; + + ret =3D regmap_write(priv->regmap, MCP9982_ONE_SHOT_ADDR, 1); + if (ret) + return ret; + + guard(mutex)(&priv->lock); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret =3D regmap_read(priv->regmap, MCP9982_INT_VALUE_ADDR(chan->channel),= val); + if (ret) + return ret; + + /* The extended temperature range is offset by 64 degrees C */ + if (priv->extended_temp_range) + *val -=3D 64; + + ret =3D regmap_read(priv->regmap, MCP9982_FRAC_VALUE_ADDR(chan->channel)= , val2); + if (ret) + return ret; + + /* Only the 3 MSB in fractional registers are used */ + *val2 =3D mcp9982_fractional_values[*val2 >> 5]; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_SAMP_FREQ: + *val =3D mcp9982_conv_rate[priv->sampl_idx][0]; + *val2 =3D mcp9982_conv_rate[priv->sampl_idx][1]; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + + ret =3D regmap_read(priv->regmap, MCP9982_RUNNING_AVG_ADDR, &tmp_reg); + if (ret) + return ret; + /* + * In Filter Selection Register values 1 and 2 + * are mapped to the same setting. + */ + switch (tmp_reg) { + case 0: + idx =3D 0; + break; + case 1: + case 2: + idx =3D 1; + break; + default: + idx =3D 2; + break; + } + + *val =3D mcp9982_3db_values_map_tbl[priv->sampl_idx][idx][0]; + *val2 =3D mcp9982_3db_values_map_tbl[priv->sampl_idx][idx][1]; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_HYSTERESIS: + ret =3D regmap_read(priv->regmap, MCP9982_HYS_ADDR, &index); + if (ret) + return ret; + + *val =3D index; + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + if (priv->extended_temp_range) + *val =3D -64; + else + *val =3D 0; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int mcp9982_read_label(struct iio_dev *indio_dev, struct iio_chan_s= pec const *chan, + char *label) +{ + struct mcp9982_priv *priv =3D iio_priv(indio_dev); + + if (chan->channel < 0 || chan->channel > 4) + return -EINVAL; + + return sysfs_emit(label, "%s\n", priv->labels[chan->channel]); +} + +static int mcp9982_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio= _chan_spec const *chan, + long info) +{ + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_HYSTERESIS: + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int mcp9982_write_raw(struct iio_dev *indio_dev, struct iio_chan_sp= ec const *chan, + int val, int val2, long mask) +{ + struct mcp9982_priv *priv =3D iio_priv(indio_dev); + int ret; + unsigned int i; + unsigned int start =3D 0; + + guard(mutex)(&priv->lock); + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + /* + * For MCP998XD and MCP9933D sampling frequency can't + * be set lower than 1. + */ + if (strchr(priv->dev_name, 'd')) + start =3D 4; + for (i =3D start; i < ARRAY_SIZE(mcp9982_conv_rate); i++) + if (val =3D=3D mcp9982_conv_rate[i][0] && val2 =3D=3D mcp9982_conv_rate= [i][1]) + break; + + if (i =3D=3D ARRAY_SIZE(mcp9982_conv_rate)) + return -EINVAL; + + ret =3D regmap_write(priv->regmap, MCP9982_CONV_ADDR, i); + if (ret) + return ret; + + priv->sampl_idx =3D i; + return 0; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + for (i =3D 0; i < ARRAY_SIZE(mcp9982_3db_values_map_tbl[priv->sampl_idx]= ); i++) + if (val =3D=3D mcp9982_3db_values_map_tbl[priv->sampl_idx][i][0] && + val2 =3D=3D mcp9982_3db_values_map_tbl[priv->sampl_idx][i][1]) + break; + + if (i =3D=3D ARRAY_SIZE(mcp9982_3db_values_map_tbl[priv->sampl_idx])) + return -EINVAL; + + /* + * In mcp9982_3db_values_map_tbl the second index maps: + * 0 for filter off + * 1 for filter at level 1 + * 2 for filter at level 2 + */ + if (i =3D=3D 2) + i =3D 3; + ret =3D regmap_write(priv->regmap, MCP9982_RUNNING_AVG_ADDR, i); + + return ret; + case IIO_CHAN_INFO_HYSTERESIS: + if (val < 0 || val > 255) + return -EINVAL; + + ret =3D regmap_write(priv->regmap, MCP9982_HYS_ADDR, val); + return ret; + case IIO_CHAN_INFO_OFFSET: + if (val !=3D 0 && val !=3D -64) + return -EINVAL; + priv->extended_temp_range =3D !(val =3D=3D 0); + ret =3D regmap_assign_bits(priv->regmap, MCP9982_CFG_ADDR, MCP9982_CFG_R= ANGE, + priv->extended_temp_range); + return ret; + default: + return -EINVAL; + } +} + +static const struct iio_info mcp9982_info =3D { + .read_raw =3D mcp9982_read_raw, + .read_label =3D mcp9982_read_label, + .read_avail =3D mcp9982_read_avail, + .write_raw_get_fmt =3D mcp9982_write_raw_get_fmt, + .write_raw =3D mcp9982_write_raw, +}; + +static int mcp9982_init(struct mcp9982_priv *priv) +{ + int ret; + unsigned int i; + u8 val; + + /* + * For chips with "D" in the name + * set the below parameters to default to + * ensure that hardware shutdown feature + * can't be overridden. + */ + if (strchr(priv->dev_name, 'd')) { + priv->recd12_enable =3D true; + priv->recd34_enable =3D true; + for (i =3D 0; i < 2; i++) + priv->beta_values[i] =3D 16; + for (i =3D 0; i < 4; i++) + priv->ideality_value[i] =3D 18; + } + + /* + * Set default values in registers. + * APDD, RECD12 and RECD34 are active on 0. + */ + val =3D FIELD_PREP(MCP9982_CFG_MSKAL, 1) | FIELD_PREP(MCP9982_CFG_RS, 1) | + FIELD_PREP(MCP9982_CFG_ATTHM, 1) | + FIELD_PREP(MCP9982_CFG_RECD12, !priv->recd12_enable) | + FIELD_PREP(MCP9982_CFG_RECD34, !priv->recd34_enable) | + FIELD_PREP(MCP9982_CFG_RANGE, 0) | FIELD_PREP(MCP9982_CFG_DA_ENA, 0= ) | + FIELD_PREP(MCP9982_CFG_APDD, !priv->apdd_enable); + + ret =3D regmap_write(priv->regmap, MCP9982_CFG_ADDR, val); + if (ret) + return ret; + priv->extended_temp_range =3D false; + + ret =3D regmap_write(priv->regmap, MCP9982_CONV_ADDR, 6); + if (ret) + return ret; + priv->sampl_idx =3D 6; + + ret =3D regmap_write(priv->regmap, MCP9982_HYS_ADDR, 10); + if (ret) + return ret; + + ret =3D regmap_write(priv->regmap, MCP9982_CONSEC_ALRT_ADDR, 112); + if (ret) + return ret; + + ret =3D regmap_write(priv->regmap, MCP9982_RUNNING_AVG_ADDR, 0); + if (ret) + return ret; + + ret =3D regmap_write(priv->regmap, MCP9982_HOTTEST_CFG_ADDR, 0); + if (ret) + return ret; + + /* Set beta compensation for channels 1 and 2 */ + for (i =3D 0; i < 2; i++) { + ret =3D regmap_write(priv->regmap, MCP9982_EXT_BETA_CFG_ADDR(i), + priv->beta_values[i]); + if (ret) + return ret; + } + /* Set ideality factor for all external channels */ + for (i =3D 0; i < 4; i++) { + ret =3D regmap_write(priv->regmap, MCP9982_EXT_IDEAL_ADDR(i), + priv->ideality_value[i]); + if (ret) + return ret; + } + + return 0; +} + +static int mcp9982_parse_of_config(struct iio_dev *indio_dev, struct devic= e *dev, + int device_nr_channels) +{ + unsigned int reg_nr, iio_idx; + struct mcp9982_priv *priv =3D iio_priv(indio_dev); + + priv->apdd_enable =3D device_property_read_bool(dev, "microchip,enable-an= ti-parallel"); + + priv->recd12_enable =3D device_property_read_bool(dev, + "microchip,resistance-comp-ch1-2-enable"); + + priv->recd34_enable =3D device_property_read_bool(dev, + "microchip,resistance-comp-ch3-4-enable"); + + priv->beta_values[0] =3D 16; + priv->beta_values[1] =3D 16; + device_property_read_u32(dev, "microchip,beta1", &priv->beta_values[0]); + device_property_read_u32(dev, "microchip,beta2", &priv->beta_values[1]); + if (priv->beta_values[0] > 16 || priv->beta_values[1] > 16) + return -EINVAL; + + priv->num_channels =3D device_get_child_node_count(dev) + 1; + + if (priv->num_channels > device_nr_channels) + return dev_err_probe(dev, -EINVAL, "More channels than the chip supports= \n"); + + priv->iio_chan =3D devm_kcalloc(dev, priv->num_channels, sizeof(*priv->ii= o_chan), GFP_KERNEL); + if (!priv->iio_chan) + return -ENOMEM; + + priv->iio_chan[0] =3D MCP9982_CHAN(0, 0, MCP9982_INT_VALUE_ADDR(0)); + + priv->labels[0] =3D "internal diode"; + iio_idx++; + device_for_each_child_node_scoped(dev, child) { + fwnode_property_read_u32(child, "reg", ®_nr); + if (!reg_nr || reg_nr >=3D device_nr_channels) + return dev_err_probe(dev, -EINVAL, + "The index of the channels does not match the chip\n"); + + priv->ideality_value[reg_nr - 1] =3D 18; + if (fwnode_property_present(child, "microchip,ideality-factor")) { + fwnode_property_read_u32(child, "microchip,ideality-factor", + &priv->ideality_value[reg_nr - 1]); + if (priv->ideality_value[reg_nr - 1] > 63) + return dev_err_probe(dev, -EINVAL, + "The ideality value is higher than maximum\n"); + } + + fwnode_property_read_string(child, "label", + &priv->labels[reg_nr]); + + priv->iio_chan[iio_idx++] =3D MCP9982_CHAN(reg_nr, reg_nr, + MCP9982_INT_VALUE_ADDR(reg_nr)); + } + + return 0; +} + +static int mcp9982_probe(struct i2c_client *client) +{ + struct device *dev =3D &client->dev; + struct mcp9982_priv *priv; + struct iio_dev *indio_dev; + const struct mcp9982_features *chip; + int ret; + + indio_dev =3D devm_iio_device_alloc(dev, sizeof(*priv)); + if (!indio_dev) + return -ENOMEM; + + priv =3D iio_priv(indio_dev); + priv->regmap =3D devm_regmap_init_i2c(client, &mcp9982_regmap_config); + if (IS_ERR(priv->regmap)) + return dev_err_probe(dev, PTR_ERR(priv->regmap), + "Cannot initialize register map\n"); + + ret =3D devm_mutex_init(dev, &priv->lock); + if (ret) + return ret; + + chip =3D i2c_get_match_data(client); + if (!chip) + return -EINVAL; + priv->dev_name =3D chip->name; + + ret =3D mcp9982_parse_of_config(indio_dev, &client->dev, chip->phys_chann= els); + if (ret) + return dev_err_probe(dev, ret, "Parameter parsing error\n"); + + mcp9982_calc_all_3db_values(); + ret =3D mcp9982_init(priv); + if (ret) + return dev_err_probe(dev, ret, "Cannot initialize device\n"); + + indio_dev->name =3D chip->name; + indio_dev->info =3D &mcp9982_info; + indio_dev->modes =3D INDIO_DIRECT_MODE; + indio_dev->channels =3D priv->iio_chan; + indio_dev->num_channels =3D priv->num_channels; + + ret =3D devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Cannot register IIO device\n"); + + return 0; +} + +static const struct i2c_device_id mcp9982_id[] =3D { + { .name =3D "mcp9933", .driver_data =3D (kernel_ulong_t)&mcp9933_chip_con= fig }, + { .name =3D "mcp9933d", .driver_data =3D (kernel_ulong_t)&mcp9933d_chip_c= onfig }, + { .name =3D "mcp9982", .driver_data =3D (kernel_ulong_t)&mcp9982_chip_con= fig }, + { .name =3D "mcp9982d", .driver_data =3D (kernel_ulong_t)&mcp9982d_chip_c= onfig }, + { .name =3D "mcp9983", .driver_data =3D (kernel_ulong_t)&mcp9983_chip_con= fig }, + { .name =3D "mcp9983d", .driver_data =3D (kernel_ulong_t)&mcp9983d_chip_c= onfig }, + { .name =3D "mcp9984", .driver_data =3D (kernel_ulong_t)&mcp9984_chip_con= fig }, + { .name =3D "mcp9984d", .driver_data =3D (kernel_ulong_t)&mcp9984d_chip_c= onfig }, + { .name =3D "mcp9985", .driver_data =3D (kernel_ulong_t)&mcp9985_chip_con= fig }, + { .name =3D "mcp9985d", .driver_data =3D (kernel_ulong_t)&mcp9985d_chip_c= onfig }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mcp9982_id); + +static const struct of_device_id mcp9982_of_match[] =3D { + { + .compatible =3D "microchip,mcp9933", + .data =3D &mcp9933_chip_config + }, { + .compatible =3D "microchip,mcp9933d", + .data =3D &mcp9933d_chip_config + }, { + .compatible =3D "microchip,mcp9982", + .data =3D &mcp9982_chip_config + }, { + .compatible =3D "microchip,mcp9982d", + .data =3D &mcp9982d_chip_config + }, { + .compatible =3D "microchip,mcp9983", + .data =3D &mcp9983_chip_config + }, { + .compatible =3D "microchip,mcp9983d", + .data =3D &mcp9983d_chip_config + }, { + .compatible =3D "microchip,mcp9984", + .data =3D &mcp9984_chip_config + }, { + .compatible =3D "microchip,mcp9984d", + .data =3D &mcp9984d_chip_config + }, { + .compatible =3D "microchip,mcp9985", + .data =3D &mcp9985_chip_config + }, { + .compatible =3D "microchip,mcp9985d", + .data =3D &mcp9985d_chip_config + }, + { } +}; +MODULE_DEVICE_TABLE(of, mcp9982_of_match); + +static struct i2c_driver mcp9982_driver =3D { + .driver =3D { + .name =3D "mcp9982", + .of_match_table =3D mcp9982_of_match, + }, + .probe =3D mcp9982_probe, + .id_table =3D mcp9982_id, +}; +module_i2c_driver(mcp9982_driver); + +MODULE_AUTHOR("Victor Duicu "); +MODULE_DESCRIPTION("MCP998X/33 and MCP998XD/33D Multichannel Automotive Te= mperature Monitor Driver"); +MODULE_LICENSE("GPL"); --=20 2.48.1