From 1c055e55a242a33e574e48be530e06770a210dcd Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 19 Feb 2024 03:26:26 +0000
Subject: [PATCH] add r8169 read mac form eeprom

---
 kernel/drivers/hwmon/shtc1.c |  101 +++++++++++++++++++++++++++++++++++---------------
 1 files changed, 70 insertions(+), 31 deletions(-)

diff --git a/kernel/drivers/hwmon/shtc1.c b/kernel/drivers/hwmon/shtc1.c
index 2a18539..18546eb 100644
--- a/kernel/drivers/hwmon/shtc1.c
+++ b/kernel/drivers/hwmon/shtc1.c
@@ -1,18 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /* Sensirion SHTC1 humidity and temperature sensor driver
  *
  * Copyright (C) 2014 Sensirion AG, Switzerland
  * Author: Johannes Winkelmann <johannes.winkelmann@sensirion.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 
 #include <linux/module.h>
@@ -24,6 +14,7 @@
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/platform_data/shtc1.h>
+#include <linux/of.h>
 
 /* commands (high precision mode) */
 static const unsigned char shtc1_cmd_measure_blocking_hpm[]    = { 0x7C, 0xA2 };
@@ -34,18 +25,32 @@
 static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
 
 /* command for reading the ID register */
-static const unsigned char shtc1_cmd_read_id_reg[]	       = { 0xef, 0xc8 };
+static const unsigned char shtc1_cmd_read_id_reg[]             = { 0xef, 0xc8 };
 
-/* constants for reading the ID register */
-#define SHTC1_ID	  0x07
-#define SHTC1_ID_REG_MASK 0x3f
+/*
+ * constants for reading the ID register
+ * SHTC1: 0x0007 with mask 0x003f
+ * SHTW1: 0x0007 with mask 0x003f
+ * SHTC3: 0x0807 with mask 0x083f
+ */
+#define SHTC3_ID      0x0807
+#define SHTC3_ID_MASK 0x083f
+#define SHTC1_ID      0x0007
+#define SHTC1_ID_MASK 0x003f
 
 /* delays for non-blocking i2c commands, both in us */
 #define SHTC1_NONBLOCKING_WAIT_TIME_HPM  14400
 #define SHTC1_NONBLOCKING_WAIT_TIME_LPM   1000
+#define SHTC3_NONBLOCKING_WAIT_TIME_HPM  12100
+#define SHTC3_NONBLOCKING_WAIT_TIME_LPM    800
 
 #define SHTC1_CMD_LENGTH      2
 #define SHTC1_RESPONSE_LENGTH 6
+
+enum shtcx_chips {
+	shtc1,
+	shtc3,
+};
 
 struct shtc1_data {
 	struct i2c_client *client;
@@ -57,6 +62,7 @@
 	unsigned int nonblocking_wait_time; /* in us */
 
 	struct shtc1_platform_data setup;
+	enum shtcx_chips chip;
 
 	int temperature; /* 1000 * temperature in dgr C */
 	int humidity; /* 1000 * relative humidity in %RH */
@@ -167,25 +173,32 @@
 		data->command = data->setup.blocking_io ?
 				shtc1_cmd_measure_blocking_hpm :
 				shtc1_cmd_measure_nonblocking_hpm;
-		data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_HPM;
-
+		data->nonblocking_wait_time = (data->chip == shtc1) ?
+				SHTC1_NONBLOCKING_WAIT_TIME_HPM :
+				SHTC3_NONBLOCKING_WAIT_TIME_HPM;
 	} else {
 		data->command = data->setup.blocking_io ?
 				shtc1_cmd_measure_blocking_lpm :
 				shtc1_cmd_measure_nonblocking_lpm;
-		data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_LPM;
+		data->nonblocking_wait_time = (data->chip == shtc1) ?
+				SHTC1_NONBLOCKING_WAIT_TIME_LPM :
+				SHTC3_NONBLOCKING_WAIT_TIME_LPM;
 	}
 }
 
-static int shtc1_probe(struct i2c_client *client,
-		       const struct i2c_device_id *id)
+static const struct i2c_device_id shtc1_id[];
+
+static int shtc1_probe(struct i2c_client *client)
 {
 	int ret;
-	char id_reg[2];
+	u16 id_reg;
+	char id_reg_buf[2];
 	struct shtc1_data *data;
 	struct device *hwmon_dev;
+	enum shtcx_chips chip = i2c_match_id(shtc1_id, client)->driver_data;
 	struct i2c_adapter *adap = client->adapter;
 	struct device *dev = &client->dev;
+	struct device_node *np = dev->of_node;
 
 	if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) {
 		dev_err(dev, "plain i2c transactions not supported\n");
@@ -197,13 +210,20 @@
 		dev_err(dev, "could not send read_id_reg command: %d\n", ret);
 		return ret < 0 ? ret : -ENODEV;
 	}
-	ret = i2c_master_recv(client, id_reg, sizeof(id_reg));
-	if (ret != sizeof(id_reg)) {
+	ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
+	if (ret != sizeof(id_reg_buf)) {
 		dev_err(dev, "could not read ID register: %d\n", ret);
 		return -ENODEV;
 	}
-	if ((id_reg[1] & SHTC1_ID_REG_MASK) != SHTC1_ID) {
-		dev_err(dev, "ID register doesn't match\n");
+
+	id_reg = be16_to_cpup((__be16 *)id_reg_buf);
+	if (chip == shtc3) {
+		if ((id_reg & SHTC3_ID_MASK) != SHTC3_ID) {
+			dev_err(dev, "SHTC3 ID register does not match\n");
+			return -ENODEV;
+		}
+	} else if ((id_reg & SHTC1_ID_MASK) != SHTC1_ID) {
+		dev_err(dev, "SHTC1 ID register does not match\n");
 		return -ENODEV;
 	}
 
@@ -214,9 +234,16 @@
 	data->setup.blocking_io = false;
 	data->setup.high_precision = true;
 	data->client = client;
+	data->chip = chip;
 
-	if (client->dev.platform_data)
-		data->setup = *(struct shtc1_platform_data *)dev->platform_data;
+	if (np) {
+		data->setup.blocking_io = of_property_read_bool(np, "sensirion,blocking-io");
+		data->setup.high_precision = !of_property_read_bool(np, "sensicon,low-precision");
+	} else {
+		if (client->dev.platform_data)
+			data->setup = *(struct shtc1_platform_data *)dev->platform_data;
+	}
+
 	shtc1_select_command(data);
 	mutex_init(&data->update_lock);
 
@@ -232,15 +259,27 @@
 
 /* device ID table */
 static const struct i2c_device_id shtc1_id[] = {
-	{ "shtc1", 0 },
-	{ "shtw1", 0 },
+	{ "shtc1", shtc1 },
+	{ "shtw1", shtc1 },
+	{ "shtc3", shtc3 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, shtc1_id);
 
+static const struct of_device_id shtc1_of_match[] = {
+	{ .compatible = "sensirion,shtc1" },
+	{ .compatible = "sensirion,shtw1" },
+	{ .compatible = "sensirion,shtc3" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, shtc1_of_match);
+
 static struct i2c_driver shtc1_i2c_driver = {
-	.driver.name  = "shtc1",
-	.probe        = shtc1_probe,
+	.driver = {
+		.name = "shtc1",
+		.of_match_table = shtc1_of_match,
+	},
+	.probe_new    = shtc1_probe,
 	.id_table     = shtc1_id,
 };
 

--
Gitblit v1.6.2