forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 748e4f3d702def1a4bff191e0cf93b6a05340f01
kernel/drivers/hwmon/ina2xx.c
....@@ -1,28 +1,25 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Driver for Texas Instruments INA219, INA226 power monitor chips
34 *
45 * INA219:
56 * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
6
- * Datasheet: http://www.ti.com/product/ina219
7
+ * Datasheet: https://www.ti.com/product/ina219
78 *
89 * INA220:
910 * Bi-Directional Current/Power Monitor with I2C Interface
10
- * Datasheet: http://www.ti.com/product/ina220
11
+ * Datasheet: https://www.ti.com/product/ina220
1112 *
1213 * INA226:
1314 * Bi-Directional Current/Power Monitor with I2C Interface
14
- * Datasheet: http://www.ti.com/product/ina226
15
+ * Datasheet: https://www.ti.com/product/ina226
1516 *
1617 * INA230:
1718 * Bi-directional Current/Power Monitor with I2C Interface
18
- * Datasheet: http://www.ti.com/product/ina230
19
+ * Datasheet: https://www.ti.com/product/ina230
1920 *
2021 * Copyright (C) 2012 Lothar Felten <lothar.felten@gmail.com>
2122 * Thanks to Jan Volkering
22
- *
23
- * This program is free software; you can redistribute it and/or modify
24
- * it under the terms of the GNU General Public License as published by
25
- * the Free Software Foundation; version 2 of the License.
2623 */
2724
2825 #include <linux/kernel.h>
....@@ -76,6 +73,17 @@
7673
7774 #define INA226_READ_AVG(reg) (((reg) & INA226_AVG_RD_MASK) >> 9)
7875 #define INA226_SHIFT_AVG(val) ((val) << 9)
76
+
77
+/* bit number of alert functions in Mask/Enable Register */
78
+#define INA226_SHUNT_OVER_VOLTAGE_BIT 15
79
+#define INA226_SHUNT_UNDER_VOLTAGE_BIT 14
80
+#define INA226_BUS_OVER_VOLTAGE_BIT 13
81
+#define INA226_BUS_UNDER_VOLTAGE_BIT 12
82
+#define INA226_POWER_OVER_LIMIT_BIT 11
83
+
84
+/* bit mask for alert config bits of Mask/Enable Register */
85
+#define INA226_ALERT_CONFIG_MASK 0xFC00
86
+#define INA226_ALERT_FUNCTION_FLAG BIT(4)
7987
8088 /* common attrs, ina226 attrs and NULL */
8189 #define INA2XX_MAX_ATTRIBUTE_GROUPS 3
....@@ -140,7 +148,7 @@
140148 * Available averaging rates for ina226. The indices correspond with
141149 * the bit values expected by the chip (according to the ina226 datasheet,
142150 * table 3 AVG bit settings, found at
143
- * http://www.ti.com/lit/ds/symlink/ina226.pdf.
151
+ * https://www.ti.com/lit/ds/symlink/ina226.pdf.
144152 */
145153 static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 };
146154
....@@ -290,7 +298,7 @@
290298 return val;
291299 }
292300
293
-static ssize_t ina2xx_show_value(struct device *dev,
301
+static ssize_t ina2xx_value_show(struct device *dev,
294302 struct device_attribute *da, char *buf)
295303 {
296304 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
....@@ -304,6 +312,145 @@
304312
305313 return snprintf(buf, PAGE_SIZE, "%d\n",
306314 ina2xx_get_value(data, attr->index, regval));
315
+}
316
+
317
+static int ina226_reg_to_alert(struct ina2xx_data *data, u8 bit, u16 regval)
318
+{
319
+ int reg;
320
+
321
+ switch (bit) {
322
+ case INA226_SHUNT_OVER_VOLTAGE_BIT:
323
+ case INA226_SHUNT_UNDER_VOLTAGE_BIT:
324
+ reg = INA2XX_SHUNT_VOLTAGE;
325
+ break;
326
+ case INA226_BUS_OVER_VOLTAGE_BIT:
327
+ case INA226_BUS_UNDER_VOLTAGE_BIT:
328
+ reg = INA2XX_BUS_VOLTAGE;
329
+ break;
330
+ case INA226_POWER_OVER_LIMIT_BIT:
331
+ reg = INA2XX_POWER;
332
+ break;
333
+ default:
334
+ /* programmer goofed */
335
+ WARN_ON_ONCE(1);
336
+ return 0;
337
+ }
338
+
339
+ return ina2xx_get_value(data, reg, regval);
340
+}
341
+
342
+/*
343
+ * Turns alert limit values into register values.
344
+ * Opposite of the formula in ina2xx_get_value().
345
+ */
346
+static s16 ina226_alert_to_reg(struct ina2xx_data *data, u8 bit, int val)
347
+{
348
+ switch (bit) {
349
+ case INA226_SHUNT_OVER_VOLTAGE_BIT:
350
+ case INA226_SHUNT_UNDER_VOLTAGE_BIT:
351
+ val *= data->config->shunt_div;
352
+ return clamp_val(val, SHRT_MIN, SHRT_MAX);
353
+ case INA226_BUS_OVER_VOLTAGE_BIT:
354
+ case INA226_BUS_UNDER_VOLTAGE_BIT:
355
+ val = (val * 1000) << data->config->bus_voltage_shift;
356
+ val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb);
357
+ return clamp_val(val, 0, SHRT_MAX);
358
+ case INA226_POWER_OVER_LIMIT_BIT:
359
+ val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
360
+ return clamp_val(val, 0, USHRT_MAX);
361
+ default:
362
+ /* programmer goofed */
363
+ WARN_ON_ONCE(1);
364
+ return 0;
365
+ }
366
+}
367
+
368
+static ssize_t ina226_alert_show(struct device *dev,
369
+ struct device_attribute *da, char *buf)
370
+{
371
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
372
+ struct ina2xx_data *data = dev_get_drvdata(dev);
373
+ int regval;
374
+ int val = 0;
375
+ int ret;
376
+
377
+ mutex_lock(&data->config_lock);
378
+ ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
379
+ if (ret)
380
+ goto abort;
381
+
382
+ if (regval & BIT(attr->index)) {
383
+ ret = regmap_read(data->regmap, INA226_ALERT_LIMIT, &regval);
384
+ if (ret)
385
+ goto abort;
386
+ val = ina226_reg_to_alert(data, attr->index, regval);
387
+ }
388
+
389
+ ret = snprintf(buf, PAGE_SIZE, "%d\n", val);
390
+abort:
391
+ mutex_unlock(&data->config_lock);
392
+ return ret;
393
+}
394
+
395
+static ssize_t ina226_alert_store(struct device *dev,
396
+ struct device_attribute *da,
397
+ const char *buf, size_t count)
398
+{
399
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
400
+ struct ina2xx_data *data = dev_get_drvdata(dev);
401
+ unsigned long val;
402
+ int ret;
403
+
404
+ ret = kstrtoul(buf, 10, &val);
405
+ if (ret < 0)
406
+ return ret;
407
+
408
+ /*
409
+ * Clear all alerts first to avoid accidentally triggering ALERT pin
410
+ * due to register write sequence. Then, only enable the alert
411
+ * if the value is non-zero.
412
+ */
413
+ mutex_lock(&data->config_lock);
414
+ ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
415
+ INA226_ALERT_CONFIG_MASK, 0);
416
+ if (ret < 0)
417
+ goto abort;
418
+
419
+ ret = regmap_write(data->regmap, INA226_ALERT_LIMIT,
420
+ ina226_alert_to_reg(data, attr->index, val));
421
+ if (ret < 0)
422
+ goto abort;
423
+
424
+ if (val != 0) {
425
+ ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE,
426
+ INA226_ALERT_CONFIG_MASK,
427
+ BIT(attr->index));
428
+ if (ret < 0)
429
+ goto abort;
430
+ }
431
+
432
+ ret = count;
433
+abort:
434
+ mutex_unlock(&data->config_lock);
435
+ return ret;
436
+}
437
+
438
+static ssize_t ina226_alarm_show(struct device *dev,
439
+ struct device_attribute *da, char *buf)
440
+{
441
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
442
+ struct ina2xx_data *data = dev_get_drvdata(dev);
443
+ int regval;
444
+ int alarm = 0;
445
+ int ret;
446
+
447
+ ret = regmap_read(data->regmap, INA226_MASK_ENABLE, &regval);
448
+ if (ret)
449
+ return ret;
450
+
451
+ alarm = (regval & BIT(attr->index)) &&
452
+ (regval & INA226_ALERT_FUNCTION_FLAG);
453
+ return snprintf(buf, PAGE_SIZE, "%d\n", alarm);
307454 }
308455
309456 /*
....@@ -329,16 +476,15 @@
329476 return 0;
330477 }
331478
332
-static ssize_t ina2xx_show_shunt(struct device *dev,
333
- struct device_attribute *da,
334
- char *buf)
479
+static ssize_t ina2xx_shunt_show(struct device *dev,
480
+ struct device_attribute *da, char *buf)
335481 {
336482 struct ina2xx_data *data = dev_get_drvdata(dev);
337483
338484 return snprintf(buf, PAGE_SIZE, "%li\n", data->rshunt);
339485 }
340486
341
-static ssize_t ina2xx_store_shunt(struct device *dev,
487
+static ssize_t ina2xx_shunt_store(struct device *dev,
342488 struct device_attribute *da,
343489 const char *buf, size_t count)
344490 {
....@@ -356,9 +502,9 @@
356502 return count;
357503 }
358504
359
-static ssize_t ina226_set_interval(struct device *dev,
360
- struct device_attribute *da,
361
- const char *buf, size_t count)
505
+static ssize_t ina226_interval_store(struct device *dev,
506
+ struct device_attribute *da,
507
+ const char *buf, size_t count)
362508 {
363509 struct ina2xx_data *data = dev_get_drvdata(dev);
364510 unsigned long val;
....@@ -380,7 +526,7 @@
380526 return count;
381527 }
382528
383
-static ssize_t ina226_show_interval(struct device *dev,
529
+static ssize_t ina226_interval_show(struct device *dev,
384530 struct device_attribute *da, char *buf)
385531 {
386532 struct ina2xx_data *data = dev_get_drvdata(dev);
....@@ -395,29 +541,45 @@
395541 }
396542
397543 /* shunt voltage */
398
-static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina2xx_show_value, NULL,
399
- INA2XX_SHUNT_VOLTAGE);
544
+static SENSOR_DEVICE_ATTR_RO(in0_input, ina2xx_value, INA2XX_SHUNT_VOLTAGE);
545
+/* shunt voltage over/under voltage alert setting and alarm */
546
+static SENSOR_DEVICE_ATTR_RW(in0_crit, ina226_alert,
547
+ INA226_SHUNT_OVER_VOLTAGE_BIT);
548
+static SENSOR_DEVICE_ATTR_RW(in0_lcrit, ina226_alert,
549
+ INA226_SHUNT_UNDER_VOLTAGE_BIT);
550
+static SENSOR_DEVICE_ATTR_RO(in0_crit_alarm, ina226_alarm,
551
+ INA226_SHUNT_OVER_VOLTAGE_BIT);
552
+static SENSOR_DEVICE_ATTR_RO(in0_lcrit_alarm, ina226_alarm,
553
+ INA226_SHUNT_UNDER_VOLTAGE_BIT);
400554
401555 /* bus voltage */
402
-static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ina2xx_show_value, NULL,
403
- INA2XX_BUS_VOLTAGE);
556
+static SENSOR_DEVICE_ATTR_RO(in1_input, ina2xx_value, INA2XX_BUS_VOLTAGE);
557
+/* bus voltage over/under voltage alert setting and alarm */
558
+static SENSOR_DEVICE_ATTR_RW(in1_crit, ina226_alert,
559
+ INA226_BUS_OVER_VOLTAGE_BIT);
560
+static SENSOR_DEVICE_ATTR_RW(in1_lcrit, ina226_alert,
561
+ INA226_BUS_UNDER_VOLTAGE_BIT);
562
+static SENSOR_DEVICE_ATTR_RO(in1_crit_alarm, ina226_alarm,
563
+ INA226_BUS_OVER_VOLTAGE_BIT);
564
+static SENSOR_DEVICE_ATTR_RO(in1_lcrit_alarm, ina226_alarm,
565
+ INA226_BUS_UNDER_VOLTAGE_BIT);
404566
405567 /* calculated current */
406
-static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ina2xx_show_value, NULL,
407
- INA2XX_CURRENT);
568
+static SENSOR_DEVICE_ATTR_RO(curr1_input, ina2xx_value, INA2XX_CURRENT);
408569
409570 /* calculated power */
410
-static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL,
411
- INA2XX_POWER);
571
+static SENSOR_DEVICE_ATTR_RO(power1_input, ina2xx_value, INA2XX_POWER);
572
+/* over-limit power alert setting and alarm */
573
+static SENSOR_DEVICE_ATTR_RW(power1_crit, ina226_alert,
574
+ INA226_POWER_OVER_LIMIT_BIT);
575
+static SENSOR_DEVICE_ATTR_RO(power1_crit_alarm, ina226_alarm,
576
+ INA226_POWER_OVER_LIMIT_BIT);
412577
413578 /* shunt resistance */
414
-static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR,
415
- ina2xx_show_shunt, ina2xx_store_shunt,
416
- INA2XX_CALIBRATION);
579
+static SENSOR_DEVICE_ATTR_RW(shunt_resistor, ina2xx_shunt, INA2XX_CALIBRATION);
417580
418581 /* update interval (ina226 only) */
419
-static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR,
420
- ina226_show_interval, ina226_set_interval, 0);
582
+static SENSOR_DEVICE_ATTR_RW(update_interval, ina226_interval, 0);
421583
422584 /* pointers to created device attributes */
423585 static struct attribute *ina2xx_attrs[] = {
....@@ -434,6 +596,16 @@
434596 };
435597
436598 static struct attribute *ina226_attrs[] = {
599
+ &sensor_dev_attr_in0_crit.dev_attr.attr,
600
+ &sensor_dev_attr_in0_lcrit.dev_attr.attr,
601
+ &sensor_dev_attr_in0_crit_alarm.dev_attr.attr,
602
+ &sensor_dev_attr_in0_lcrit_alarm.dev_attr.attr,
603
+ &sensor_dev_attr_in1_crit.dev_attr.attr,
604
+ &sensor_dev_attr_in1_lcrit.dev_attr.attr,
605
+ &sensor_dev_attr_in1_crit_alarm.dev_attr.attr,
606
+ &sensor_dev_attr_in1_lcrit_alarm.dev_attr.attr,
607
+ &sensor_dev_attr_power1_crit.dev_attr.attr,
608
+ &sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
437609 &sensor_dev_attr_update_interval.dev_attr.attr,
438610 NULL,
439611 };
....@@ -442,8 +614,9 @@
442614 .attrs = ina226_attrs,
443615 };
444616
445
-static int ina2xx_probe(struct i2c_client *client,
446
- const struct i2c_device_id *id)
617
+static const struct i2c_device_id ina2xx_id[];
618
+
619
+static int ina2xx_probe(struct i2c_client *client)
447620 {
448621 struct device *dev = &client->dev;
449622 struct ina2xx_data *data;
....@@ -455,7 +628,7 @@
455628 if (client->dev.of_node)
456629 chip = (enum ina2xx_ids)of_device_get_match_data(&client->dev);
457630 else
458
- chip = id->driver_data;
631
+ chip = i2c_match_id(ina2xx_id, client)->driver_data;
459632
460633 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
461634 if (!data)
....@@ -515,7 +688,7 @@
515688 };
516689 MODULE_DEVICE_TABLE(i2c, ina2xx_id);
517690
518
-static const struct of_device_id ina2xx_of_match[] = {
691
+static const struct of_device_id __maybe_unused ina2xx_of_match[] = {
519692 {
520693 .compatible = "ti,ina219",
521694 .data = (void *)ina219
....@@ -545,7 +718,7 @@
545718 .name = "ina2xx",
546719 .of_match_table = of_match_ptr(ina2xx_of_match),
547720 },
548
- .probe = ina2xx_probe,
721
+ .probe_new = ina2xx_probe,
549722 .id_table = ina2xx_id,
550723 };
551724