[PATCH 2/3] iio: temperature: Add support for P3T1085

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Carlos Song <carlos.song@xxxxxxx>

Add basic function support for P3T1085 temperature sensor.

P3T1085UK is a temperature-to-digital converter with a -40 °C to +125 °C
range. The device can be communicated by a controller via the 2-wire serial
I3C (up to 12.5 MHz) and I2C (up to 3.4 MHz) interface.

Signed-off-by: Clark Wang <xiaoning.wang@xxxxxxx>
Signed-off-by: Carlos Song <carlos.song@xxxxxxx>
Signed-off-by: Frank Li <Frank.Li@xxxxxxx>
---
 drivers/iio/temperature/Kconfig            |  1 +
 drivers/iio/temperature/Makefile           |  2 +
 drivers/iio/temperature/p3t/Kconfig        | 29 +++++++++++
 drivers/iio/temperature/p3t/Makefile       |  5 ++
 drivers/iio/temperature/p3t/p3t1085.h      | 31 ++++++++++++
 drivers/iio/temperature/p3t/p3t1085_core.c | 79 ++++++++++++++++++++++++++++++
 drivers/iio/temperature/p3t/p3t1085_i2c.c  | 68 +++++++++++++++++++++++++
 drivers/iio/temperature/p3t/p3t1085_i3c.c  | 59 ++++++++++++++++++++++
 8 files changed, 274 insertions(+)

diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index 1244d8e17d504..7cdd49279aba2 100644
--- a/drivers/iio/temperature/Kconfig
+++ b/drivers/iio/temperature/Kconfig
@@ -182,4 +182,5 @@ config MCP9600
 	  This driver can also be built as a module. If so, the module
 	  will be called mcp9600.
 
+source "drivers/iio/temperature/p3t/Kconfig"
 endmenu
diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile
index 07d6e65709f7f..d5e89c20d58b6 100644
--- a/drivers/iio/temperature/Makefile
+++ b/drivers/iio/temperature/Makefile
@@ -19,3 +19,5 @@ obj-$(CONFIG_TMP007) += tmp007.o
 obj-$(CONFIG_TMP117) += tmp117.o
 obj-$(CONFIG_TSYS01) += tsys01.o
 obj-$(CONFIG_TSYS02D) += tsys02d.o
+
+obj-y += p3t/
diff --git a/drivers/iio/temperature/p3t/Kconfig b/drivers/iio/temperature/p3t/Kconfig
new file mode 100644
index 0000000000000..09e925024b66f
--- /dev/null
+++ b/drivers/iio/temperature/p3t/Kconfig
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config IIO_P3T1085
+	tristate
+	depends on (I2C || I3C)
+
+config IIO_P3T1085_I2C
+	tristate "NXP P3T1085 temperature sensor I2C driver"
+	depends on I2C
+	select IIO_P3T1085
+	select REGMAP_I2C
+	help
+	  Say yes here to build support for NXP P3T1085 I2C temperature
+	  sensor.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called p3t1085_i2c
+
+config IIO_P3T1085_I3C
+	tristate "NXP P3T1085 temperature sensor I3C driver"
+	depends on I3C
+	select IIO_P3T1085
+	select REGMAP_I3C
+	help
+	  Say yes here to build support for NXP P3T1085 I3C temperature
+	  sensor.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called p3t1085_i3c
diff --git a/drivers/iio/temperature/p3t/Makefile b/drivers/iio/temperature/p3t/Makefile
new file mode 100644
index 0000000000000..21aaeb51e044d
--- /dev/null
+++ b/drivers/iio/temperature/p3t/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_IIO_P3T1085) += p3t1085_core.o
+obj-$(CONFIG_IIO_P3T1085_I2C) += p3t1085_i2c.o
+obj-$(CONFIG_IIO_P3T1085_I3C) += p3t1085_i3c.o
diff --git a/drivers/iio/temperature/p3t/p3t1085.h b/drivers/iio/temperature/p3t/p3t1085.h
new file mode 100644
index 0000000000000..b018a04e4aee4
--- /dev/null
+++ b/drivers/iio/temperature/p3t/p3t1085.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * NXP P3T1085 Temperature Sensor Driver
+ *
+ * Copyright 2024 NXP
+ */
+#ifndef P3T1085_H
+#define P3T1085_H
+
+#include <linux/device.h>
+#include <linux/iio/iio.h>
+
+#define P3T1085_REG_TEMP		0x0
+#define P3T1085_REG_CFGR		0x1
+#define P3T1085_REG_HIGH_LIM		0x2
+#define P3T1085_REG_LOW_LIM		0x3
+
+#define P3T1085_RESOLUTION_10UC		62500
+
+enum p3t1085_hw_id {
+	P3T1085_ID,
+};
+
+struct p3t1085_data {
+	struct device *dev;
+	struct regmap *regmap;
+};
+
+int p3t1085_probe(struct device *dev, int irq, int hw_id, struct regmap *regmap);
+
+#endif /* P3T1085_H */
diff --git a/drivers/iio/temperature/p3t/p3t1085_core.c b/drivers/iio/temperature/p3t/p3t1085_core.c
new file mode 100644
index 0000000000000..4b00e606a6d04
--- /dev/null
+++ b/drivers/iio/temperature/p3t/p3t1085_core.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * NXP P3T1085 Temperature Sensor Driver
+ *
+ * Copyright 2024 NXP
+ */
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/kernel.h>
+#include <linux/limits.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include "p3t1085.h"
+
+static int p3t1085_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *channel, int *val,
+			    int *val2, long mask)
+{
+	struct p3t1085_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = regmap_read(data->regmap, P3T1085_REG_TEMP, val);
+		if (ret < 0) {
+			dev_err(data->dev, "failed to read temperature register\n");
+			return ret;
+		}
+		*val = *val >> 4;
+		return IIO_VAL_INT;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_chan_spec p3t1085_channels[] = {
+	{
+		.type = IIO_TEMP,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+	},
+};
+
+static const struct iio_info p3t1085_info = {
+	.read_raw = p3t1085_read_raw,
+};
+
+int p3t1085_probe(struct device *dev, int irq, int hw_id, struct regmap *regmap)
+{
+	struct p3t1085_data *data;
+	struct iio_dev *iio_dev;
+
+	iio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+	if (!iio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(iio_dev);
+	data->dev = dev;
+	data->regmap = regmap;
+
+	iio_dev->name = "p3t1085";
+	iio_dev->modes = INDIO_DIRECT_MODE;
+	iio_dev->info = &p3t1085_info;
+
+	iio_dev->channels = p3t1085_channels;
+	iio_dev->num_channels = ARRAY_SIZE(p3t1085_channels);
+
+	return devm_iio_device_register(dev, iio_dev);
+}
+EXPORT_SYMBOL_NS(p3t1085_probe, IIO_P3T1085);
+
+MODULE_AUTHOR("Xiaoning Wang <xiaoning.wang@xxxxxxx>");
+MODULE_DESCRIPTION("NXP P3T1085 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/temperature/p3t/p3t1085_i2c.c b/drivers/iio/temperature/p3t/p3t1085_i2c.c
new file mode 100644
index 0000000000000..20e5f7a68dd9e
--- /dev/null
+++ b/drivers/iio/temperature/p3t/p3t1085_i2c.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * NXP P3T1085 Temperature Sensor Driver
+ *
+ * Copyright 2024 NXP
+ */
+
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include "p3t1085.h"
+
+static const struct regmap_config p3t1085_i2c_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 16,
+};
+
+static int p3t1085_i2c_probe(struct i2c_client *client)
+{
+	const struct i2c_device_id *id;
+	struct regmap *regmap;
+	int ret;
+
+	id = i2c_client_get_device_id(client);
+	if (!id)
+		return -EINVAL;
+
+	regmap = devm_regmap_init_i2c(client, &p3t1085_i2c_regmap_config);
+	if (IS_ERR(regmap))
+		return dev_err_probe(&client->dev, PTR_ERR(regmap),
+				     "Failed to register i2c regmap %ld\n", PTR_ERR(regmap));
+
+	ret = p3t1085_probe(&client->dev, client->irq, id->driver_data, regmap);
+	if (ret)
+		return dev_err_probe(&client->dev, ret, "Failed to probe\n");
+
+	return 0;
+}
+
+static const struct of_device_id p3t1085_i2c_of_match[] = {
+	{ .compatible = "nxp,p3t1085", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, p3t1085_i2c_of_match);
+
+static const struct i2c_device_id p3t1085_i2c_id_table[] = {
+	{ "p3t1085", P3T1085_ID },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, p3t1085_i2c_id_table);
+
+static struct i2c_driver p3t1085_driver = {
+	.driver = {
+		.name = "p3t1085_i2c",
+		.of_match_table = p3t1085_i2c_of_match,
+	},
+	.probe = p3t1085_i2c_probe,
+	.id_table = p3t1085_i2c_id_table,
+};
+module_i2c_driver(p3t1085_driver);
+
+MODULE_AUTHOR("Xiaoning Wang <xiaoning.wang@xxxxxxx>");
+MODULE_DESCRIPTION("NXP P3T1085 i2c driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_P3T1085);
diff --git a/drivers/iio/temperature/p3t/p3t1085_i3c.c b/drivers/iio/temperature/p3t/p3t1085_i3c.c
new file mode 100644
index 0000000000000..0007d79aa0a6d
--- /dev/null
+++ b/drivers/iio/temperature/p3t/p3t1085_i3c.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP P3T1085 Temperature Sensor Driver
+ *
+ * Copyright 2024 NXP
+ */
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/i3c/device.h>
+#include <linux/i3c/master.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+
+#include "p3t1085.h"
+
+static const struct i3c_device_id p3t1085_i3c_ids[] = {
+	I3C_DEVICE(0x011B, 0x1529, (void *)P3T1085_ID),
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(i3c, p3t1085_i3c_ids);
+
+static int p3t1085_i3c_probe(struct i3c_device *i3cdev)
+{
+	const struct regmap_config p3t1085_i3c_regmap_config = {
+		.reg_bits = 8,
+		.val_bits = 16,
+	};
+	int ret;
+
+	const struct i3c_device_id *id = i3c_device_match_id(i3cdev,
+							    p3t1085_i3c_ids);
+	struct regmap *regmap;
+
+	regmap = devm_regmap_init_i3c(i3cdev, &p3t1085_i3c_regmap_config);
+	if (IS_ERR(regmap))
+		return dev_err_probe(&i3cdev->dev, PTR_ERR(regmap),
+				     "Failed to register i3c regmap\n");
+
+	ret = p3t1085_probe(&i3cdev->dev, 0, (uintptr_t)id->data, regmap);
+	if (ret)
+		return dev_err_probe(&i3cdev->dev, ret, "Failed to probe\n");
+
+	return 0;
+}
+
+static struct i3c_driver p3t1085_driver = {
+	.driver = {
+		.name = "p3t1085_i3c",
+	},
+	.probe = p3t1085_i3c_probe,
+	.id_table = p3t1085_i3c_ids,
+};
+module_i3c_driver(p3t1085_driver);
+
+MODULE_AUTHOR("Xiaoning Wang <xiaoning.wang@xxxxxxx>");
+MODULE_DESCRIPTION("NXP p3t1085 i3c driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_P3T1085);

-- 
2.34.1





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux