aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2016-04-13 05:59:45 -0400
committerMark Brown <broonie@kernel.org>2016-04-13 12:19:26 -0400
commitd2d5437bdfdde20a75bdf59db1c1a77721613b22 (patch)
tree6823866b13d70fc22ef7f3b8775b1a280fd84f81
parent19dd159ce8086293b70bd8e1aeebe06aff8d7df8 (diff)
regulator: max8973: add support for junction thermal warning
The driver MAX8973 supports the driver for Maxim PMIC MAX77621. MAX77621 supports the junction temp warning at 120 degC and 140 degC which is configurable. It generates alert signal when junction temperature crosses these threshold. MAX77621 does not support the continuous temp monitoring of junction temperature. It just report whether junction temperature crossed the threshold or not. Add support to - Configure junction temp warning threshold via DT property to generate alert when it crosses the threshold. - Add support to interrupt the host from this device when alert occurred. - read the junction temp via thermal framework. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/Kconfig1
-rw-r--r--drivers/regulator/max8973-regulator.c97
-rw-r--r--include/linux/regulator/max8973-regulator.h5
3 files changed, 103 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c77dc08b1202..129359f775d0 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -409,6 +409,7 @@ config REGULATOR_MAX8952
409config REGULATOR_MAX8973 409config REGULATOR_MAX8973
410 tristate "Maxim MAX8973 voltage regulator " 410 tristate "Maxim MAX8973 voltage regulator "
411 depends on I2C 411 depends on I2C
412 depends on THERMAL && THERMAL_OF
412 select REGMAP_I2C 413 select REGMAP_I2C
413 help 414 help
414 The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down 415 The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 5b75b7c2e3ea..08d2f13eca00 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -38,6 +38,9 @@
38#include <linux/i2c.h> 38#include <linux/i2c.h>
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/regmap.h> 40#include <linux/regmap.h>
41#include <linux/thermal.h>
42#include <linux/irq.h>
43#include <linux/interrupt.h>
41 44
42/* Register definitions */ 45/* Register definitions */
43#define MAX8973_VOUT 0x0 46#define MAX8973_VOUT 0x0
@@ -74,6 +77,7 @@
74#define MAX8973_WDTMR_ENABLE BIT(6) 77#define MAX8973_WDTMR_ENABLE BIT(6)
75#define MAX8973_DISCH_ENBABLE BIT(5) 78#define MAX8973_DISCH_ENBABLE BIT(5)
76#define MAX8973_FT_ENABLE BIT(4) 79#define MAX8973_FT_ENABLE BIT(4)
80#define MAX77621_T_JUNCTION_120 BIT(7)
77 81
78#define MAX8973_CKKADV_TRIP_MASK 0xC 82#define MAX8973_CKKADV_TRIP_MASK 0xC
79#define MAX8973_CKKADV_TRIP_DISABLE 0xC 83#define MAX8973_CKKADV_TRIP_DISABLE 0xC
@@ -93,6 +97,12 @@
93#define MAX8973_VOLATGE_STEP 6250 97#define MAX8973_VOLATGE_STEP 6250
94#define MAX8973_BUCK_N_VOLTAGE 0x80 98#define MAX8973_BUCK_N_VOLTAGE 0x80
95 99
100#define MAX77621_CHIPID_TJINT_S BIT(0)
101
102#define MAX77621_NORMAL_OPERATING_TEMP 100000
103#define MAX77621_TJINT_WARNING_TEMP_120 120000
104#define MAX77621_TJINT_WARNING_TEMP_140 140000
105
96enum device_id { 106enum device_id {
97 MAX8973, 107 MAX8973,
98 MAX77621 108 MAX77621
@@ -112,6 +122,9 @@ struct max8973_chip {
112 int curr_gpio_val; 122 int curr_gpio_val;
113 struct regulator_ops ops; 123 struct regulator_ops ops;
114 enum device_id id; 124 enum device_id id;
125 int junction_temp_warning;
126 int irq;
127 struct thermal_zone_device *tz_device;
115}; 128};
116 129
117/* 130/*
@@ -391,6 +404,10 @@ static int max8973_init_dcdc(struct max8973_chip *max,
391 if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE) 404 if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
392 control1 |= MAX8973_FREQSHIFT_9PER; 405 control1 |= MAX8973_FREQSHIFT_9PER;
393 406
407 if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
408 (max->id == MAX77621))
409 control2 |= MAX77621_T_JUNCTION_120;
410
394 if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE)) 411 if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
395 control2 |= MAX8973_DISCH_ENBABLE; 412 control2 |= MAX8973_DISCH_ENBABLE;
396 413
@@ -457,6 +474,79 @@ static int max8973_init_dcdc(struct max8973_chip *max,
457 return ret; 474 return ret;
458} 475}
459 476
477static int max8973_thermal_read_temp(void *data, int *temp)
478{
479 struct max8973_chip *mchip = data;
480 unsigned int val;
481 int ret;
482
483 ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
484 if (ret < 0) {
485 dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
486 return ret;
487 }
488
489 /* +1 degC to trigger cool devive */
490 if (val & MAX77621_CHIPID_TJINT_S)
491 *temp = mchip->junction_temp_warning + 1000;
492 else
493 *temp = MAX77621_NORMAL_OPERATING_TEMP;
494
495 return 0;
496}
497
498static irqreturn_t max8973_thermal_irq(int irq, void *data)
499{
500 struct max8973_chip *mchip = data;
501
502 thermal_zone_device_update(mchip->tz_device);
503
504 return IRQ_HANDLED;
505}
506
507static const struct thermal_zone_of_device_ops max77621_tz_ops = {
508 .get_temp = max8973_thermal_read_temp,
509};
510
511static int max8973_thermal_init(struct max8973_chip *mchip)
512{
513 struct thermal_zone_device *tzd;
514 struct irq_data *irq_data;
515 unsigned long irq_flags = 0;
516 int ret;
517
518 if (mchip->id != MAX77621)
519 return 0;
520
521 tzd = devm_thermal_zone_of_sensor_register(mchip->dev, 0, mchip,
522 &max77621_tz_ops);
523 if (IS_ERR(tzd)) {
524 ret = PTR_ERR(tzd);
525 dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
526 ret);
527 return ret;
528 }
529
530 if (mchip->irq <= 0)
531 return 0;
532
533 irq_data = irq_get_irq_data(mchip->irq);
534 if (irq_data)
535 irq_flags = irqd_get_trigger_type(irq_data);
536
537 ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL,
538 max8973_thermal_irq,
539 IRQF_ONESHOT | IRQF_SHARED | irq_flags,
540 dev_name(mchip->dev), mchip);
541 if (ret < 0) {
542 dev_err(mchip->dev, "Failed to request irq %d, %d\n",
543 mchip->irq, ret);
544 return ret;
545 }
546
547 return 0;
548}
549
460static const struct regmap_config max8973_regmap_config = { 550static const struct regmap_config max8973_regmap_config = {
461 .reg_bits = 8, 551 .reg_bits = 8,
462 .val_bits = 8, 552 .val_bits = 8,
@@ -521,6 +611,11 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
521 pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED; 611 pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
522 } 612 }
523 613
614 pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
615 ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
616 if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
617 pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
618
524 return pdata; 619 return pdata;
525} 620}
526 621
@@ -608,6 +703,7 @@ static int max8973_probe(struct i2c_client *client,
608 max->enable_external_control = pdata->enable_ext_control; 703 max->enable_external_control = pdata->enable_ext_control;
609 max->curr_gpio_val = pdata->dvs_def_state; 704 max->curr_gpio_val = pdata->dvs_def_state;
610 max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state; 705 max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
706 max->junction_temp_warning = pdata->junction_temp_warning;
611 707
612 if (gpio_is_valid(max->enable_gpio)) 708 if (gpio_is_valid(max->enable_gpio))
613 max->enable_external_control = true; 709 max->enable_external_control = true;
@@ -718,6 +814,7 @@ static int max8973_probe(struct i2c_client *client,
718 return ret; 814 return ret;
719 } 815 }
720 816
817 max8973_thermal_init(max);
721 return 0; 818 return 0;
722} 819}
723 820
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
index f6a8a16a0d4d..2fcb9980262a 100644
--- a/include/linux/regulator/max8973-regulator.h
+++ b/include/linux/regulator/max8973-regulator.h
@@ -54,6 +54,10 @@
54 * @reg_init_data: The regulator init data. 54 * @reg_init_data: The regulator init data.
55 * @control_flags: Control flags which are ORed value of above flags to 55 * @control_flags: Control flags which are ORed value of above flags to
56 * configure device. 56 * configure device.
57 * @junction_temp_warning: Junction temp in millicelcius on which warning need
58 * to be set. Thermal functionality is only supported on
59 * MAX77621. The threshold warning supported by MAX77621
60 * are 120C and 140C.
57 * @enable_ext_control: Enable the voltage enable/disable through external 61 * @enable_ext_control: Enable the voltage enable/disable through external
58 * control signal from EN input pin. If it is false then 62 * control signal from EN input pin. If it is false then
59 * voltage output will be enabled/disabled through EN bit of 63 * voltage output will be enabled/disabled through EN bit of
@@ -67,6 +71,7 @@
67struct max8973_regulator_platform_data { 71struct max8973_regulator_platform_data {
68 struct regulator_init_data *reg_init_data; 72 struct regulator_init_data *reg_init_data;
69 unsigned long control_flags; 73 unsigned long control_flags;
74 unsigned long junction_temp_warning;
70 bool enable_ext_control; 75 bool enable_ext_control;
71 int enable_gpio; 76 int enable_gpio;
72 int dvs_gpio; 77 int dvs_gpio;