forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/hwmon/pmbus/ucd9000.c
....@@ -1,25 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Hardware monitoring driver for UCD90xxx Sequencer and System Health
34 * Controller series
45 *
56 * Copyright (C) 2011 Ericsson AB.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
207 */
218
229 #include <linux/debugfs.h>
10
+#include <linux/delay.h>
2311 #include <linux/kernel.h>
2412 #include <linux/module.h>
2513 #include <linux/of_device.h>
....@@ -28,11 +16,12 @@
2816 #include <linux/slab.h>
2917 #include <linux/i2c.h>
3018 #include <linux/pmbus.h>
31
-#include <linux/gpio.h>
3219 #include <linux/gpio/driver.h>
20
+#include <linux/timekeeping.h>
3321 #include "pmbus.h"
3422
35
-enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };
23
+enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090,
24
+ ucd90910 };
3625
3726 #define UCD9000_MONITOR_CONFIG 0xd5
3827 #define UCD9000_NUM_PAGES 0xd6
....@@ -52,7 +41,7 @@
5241 #define UCD9000_GPIO_OUTPUT 1
5342
5443 #define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07)
55
-#define UCD9000_MON_PAGE(x) ((x) & 0x0f)
44
+#define UCD9000_MON_PAGE(x) ((x) & 0x1f)
5645
5746 #define UCD9000_MON_VOLTAGE 1
5847 #define UCD9000_MON_TEMPERATURE 2
....@@ -64,10 +53,12 @@
6453 #define UCD9000_GPIO_NAME_LEN 16
6554 #define UCD9090_NUM_GPIOS 23
6655 #define UCD901XX_NUM_GPIOS 26
56
+#define UCD90320_NUM_GPIOS 84
6757 #define UCD90910_NUM_GPIOS 26
6858
6959 #define UCD9000_DEBUGFS_NAME_LEN 24
7060 #define UCD9000_GPI_COUNT 8
61
+#define UCD90320_GPI_COUNT 32
7162
7263 struct ucd9000_data {
7364 u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX];
....@@ -76,6 +67,7 @@
7667 struct gpio_chip gpio;
7768 #endif
7869 struct dentry *debugfs;
70
+ ktime_t write_time;
7971 };
8072 #define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
8173
....@@ -83,6 +75,73 @@
8375 struct i2c_client *client;
8476 u8 index;
8577 };
78
+
79
+/*
80
+ * It has been observed that the UCD90320 randomly fails register access when
81
+ * doing another access right on the back of a register write. To mitigate this
82
+ * make sure that there is a minimum delay between a write access and the
83
+ * following access. The 250us is based on experimental data. At a delay of
84
+ * 200us the issue seems to go away. Add a bit of extra margin to allow for
85
+ * system to system differences.
86
+ */
87
+#define UCD90320_WAIT_DELAY_US 250
88
+
89
+static inline void ucd90320_wait(const struct ucd9000_data *data)
90
+{
91
+ s64 delta = ktime_us_delta(ktime_get(), data->write_time);
92
+
93
+ if (delta < UCD90320_WAIT_DELAY_US)
94
+ udelay(UCD90320_WAIT_DELAY_US - delta);
95
+}
96
+
97
+static int ucd90320_read_word_data(struct i2c_client *client, int page,
98
+ int phase, int reg)
99
+{
100
+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
101
+ struct ucd9000_data *data = to_ucd9000_data(info);
102
+
103
+ if (reg >= PMBUS_VIRT_BASE)
104
+ return -ENXIO;
105
+
106
+ ucd90320_wait(data);
107
+ return pmbus_read_word_data(client, page, phase, reg);
108
+}
109
+
110
+static int ucd90320_read_byte_data(struct i2c_client *client, int page, int reg)
111
+{
112
+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
113
+ struct ucd9000_data *data = to_ucd9000_data(info);
114
+
115
+ ucd90320_wait(data);
116
+ return pmbus_read_byte_data(client, page, reg);
117
+}
118
+
119
+static int ucd90320_write_word_data(struct i2c_client *client, int page,
120
+ int reg, u16 word)
121
+{
122
+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
123
+ struct ucd9000_data *data = to_ucd9000_data(info);
124
+ int ret;
125
+
126
+ ucd90320_wait(data);
127
+ ret = pmbus_write_word_data(client, page, reg, word);
128
+ data->write_time = ktime_get();
129
+
130
+ return ret;
131
+}
132
+
133
+static int ucd90320_write_byte(struct i2c_client *client, int page, u8 value)
134
+{
135
+ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
136
+ struct ucd9000_data *data = to_ucd9000_data(info);
137
+ int ret;
138
+
139
+ ucd90320_wait(data);
140
+ ret = pmbus_write_byte(client, page, value);
141
+ data->write_time = ktime_get();
142
+
143
+ return ret;
144
+}
86145
87146 static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
88147 {
....@@ -145,13 +204,14 @@
145204 {"ucd90120", ucd90120},
146205 {"ucd90124", ucd90124},
147206 {"ucd90160", ucd90160},
207
+ {"ucd90320", ucd90320},
148208 {"ucd9090", ucd9090},
149209 {"ucd90910", ucd90910},
150210 {}
151211 };
152212 MODULE_DEVICE_TABLE(i2c, ucd9000_id);
153213
154
-static const struct of_device_id ucd9000_of_match[] = {
214
+static const struct of_device_id __maybe_unused ucd9000_of_match[] = {
155215 {
156216 .compatible = "ti,ucd9000",
157217 .data = (void *)ucd9000
....@@ -167,6 +227,10 @@
167227 {
168228 .compatible = "ti,ucd90160",
169229 .data = (void *)ucd90160
230
+ },
231
+ {
232
+ .compatible = "ti,ucd90320",
233
+ .data = (void *)ucd90320
170234 },
171235 {
172236 .compatible = "ti,ucd9090",
....@@ -336,6 +400,9 @@
336400 case ucd90160:
337401 data->gpio.ngpio = UCD901XX_NUM_GPIOS;
338402 break;
403
+ case ucd90320:
404
+ data->gpio.ngpio = UCD90320_NUM_GPIOS;
405
+ break;
339406 case ucd90910:
340407 data->gpio.ngpio = UCD90910_NUM_GPIOS;
341408 break;
....@@ -373,7 +440,7 @@
373440 #ifdef CONFIG_DEBUG_FS
374441 static int ucd9000_get_mfr_status(struct i2c_client *client, u8 *buffer)
375442 {
376
- int ret = pmbus_set_page(client, 0);
443
+ int ret = pmbus_set_page(client, 0, 0xff);
377444
378445 if (ret < 0)
379446 return ret;
....@@ -386,17 +453,18 @@
386453 struct ucd9000_debugfs_entry *entry = data;
387454 struct i2c_client *client = entry->client;
388455 u8 buffer[I2C_SMBUS_BLOCK_MAX];
389
- int ret;
456
+ int ret, i;
390457
391458 ret = ucd9000_get_mfr_status(client, buffer);
392459 if (ret < 0)
393460 return ret;
394461
395462 /*
396
- * Attribute only created for devices with gpi fault bits at bits
397
- * 16-23, which is the second byte of the response.
463
+ * GPI fault bits are in sets of 8, two bytes from end of response.
398464 */
399
- *val = !!(buffer[1] & BIT(entry->index));
465
+ i = ret - 3 - entry->index / 8;
466
+ if (i >= 0)
467
+ *val = !!(buffer[i] & BIT(entry->index % 8));
400468
401469 return 0;
402470 }
....@@ -436,7 +504,7 @@
436504 {
437505 struct dentry *debugfs;
438506 struct ucd9000_debugfs_entry *entries;
439
- int i;
507
+ int i, gpi_count;
440508 char name[UCD9000_DEBUGFS_NAME_LEN];
441509
442510 debugfs = pmbus_get_debugfs_dir(client);
....@@ -449,18 +517,21 @@
449517
450518 /*
451519 * Of the chips this driver supports, only the UCD9090, UCD90160,
452
- * and UCD90910 report GPI faults in their MFR_STATUS register, so only
453
- * create the GPI fault debugfs attributes for those chips.
520
+ * UCD90320, and UCD90910 report GPI faults in their MFR_STATUS
521
+ * register, so only create the GPI fault debugfs attributes for those
522
+ * chips.
454523 */
455524 if (mid->driver_data == ucd9090 || mid->driver_data == ucd90160 ||
456
- mid->driver_data == ucd90910) {
525
+ mid->driver_data == ucd90320 || mid->driver_data == ucd90910) {
526
+ gpi_count = mid->driver_data == ucd90320 ? UCD90320_GPI_COUNT
527
+ : UCD9000_GPI_COUNT;
457528 entries = devm_kcalloc(&client->dev,
458
- UCD9000_GPI_COUNT, sizeof(*entries),
529
+ gpi_count, sizeof(*entries),
459530 GFP_KERNEL);
460531 if (!entries)
461532 return -ENOMEM;
462533
463
- for (i = 0; i < UCD9000_GPI_COUNT; i++) {
534
+ for (i = 0; i < gpi_count; i++) {
464535 entries[i].client = client;
465536 entries[i].index = i;
466537 scnprintf(name, UCD9000_DEBUGFS_NAME_LEN,
....@@ -486,8 +557,7 @@
486557 }
487558 #endif /* CONFIG_DEBUG_FS */
488559
489
-static int ucd9000_probe(struct i2c_client *client,
490
- const struct i2c_device_id *id)
560
+static int ucd9000_probe(struct i2c_client *client)
491561 {
492562 u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
493563 struct ucd9000_data *data;
....@@ -522,12 +592,12 @@
522592 if (client->dev.of_node)
523593 chip = (enum chips)of_device_get_match_data(&client->dev);
524594 else
525
- chip = id->driver_data;
595
+ chip = mid->driver_data;
526596
527
- if (chip != ucd9000 && chip != mid->driver_data)
597
+ if (chip != ucd9000 && strcmp(client->name, mid->name) != 0)
528598 dev_notice(&client->dev,
529599 "Device mismatch: Configured %s, detected %s\n",
530
- id->name, mid->name);
600
+ client->name, mid->name);
531601
532602 data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data),
533603 GFP_KERNEL);
....@@ -598,11 +668,16 @@
598668 info->read_byte_data = ucd9000_read_byte_data;
599669 info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
600670 | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
671
+ } else if (mid->driver_data == ucd90320) {
672
+ info->read_byte_data = ucd90320_read_byte_data;
673
+ info->read_word_data = ucd90320_read_word_data;
674
+ info->write_byte = ucd90320_write_byte;
675
+ info->write_word_data = ucd90320_write_word_data;
601676 }
602677
603678 ucd9000_probe_gpio(client, mid, data);
604679
605
- ret = pmbus_do_probe(client, mid, info);
680
+ ret = pmbus_do_probe(client, info);
606681 if (ret)
607682 return ret;
608683
....@@ -620,7 +695,7 @@
620695 .name = "ucd9000",
621696 .of_match_table = of_match_ptr(ucd9000_of_match),
622697 },
623
- .probe = ucd9000_probe,
698
+ .probe_new = ucd9000_probe,
624699 .remove = pmbus_do_remove,
625700 .id_table = ucd9000_id,
626701 };