2022-06-07 17:11:30 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2012-11-19 05:28:29 +04:00
/*
2021-09-20 09:11:37 +03:00
* max8973 - regulator . c - - Maxim max8973A
2012-11-19 05:28:29 +04:00
*
2021-09-20 09:11:37 +03:00
* Regulator driver for MAXIM 8973 A DC - DC step - down switching regulator .
2012-11-19 05:28:29 +04:00
*
* Copyright ( c ) 2012 , NVIDIA Corporation .
*
* Author : Laxman Dewangan < ldewangan @ nvidia . com >
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/err.h>
2013-06-24 14:50:16 +04:00
# include <linux/of.h>
2015-06-09 16:47:53 +03:00
# include <linux/of_device.h>
2012-11-19 05:28:29 +04:00
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
# include <linux/regulator/max8973-regulator.h>
2013-06-24 14:50:16 +04:00
# include <linux/regulator/of_regulator.h>
2012-11-19 05:28:29 +04:00
# include <linux/gpio.h>
2018-05-14 11:06:25 +03:00
# include <linux/gpio/consumer.h>
2015-04-23 13:40:23 +03:00
# include <linux/of_gpio.h>
2012-11-19 05:28:29 +04:00
# include <linux/i2c.h>
# include <linux/slab.h>
# include <linux/regmap.h>
2016-04-13 12:59:45 +03:00
# include <linux/thermal.h>
# include <linux/irq.h>
# include <linux/interrupt.h>
2012-11-19 05:28:29 +04:00
/* Register definitions */
# define MAX8973_VOUT 0x0
# define MAX8973_VOUT_DVS 0x1
# define MAX8973_CONTROL1 0x2
# define MAX8973_CONTROL2 0x3
# define MAX8973_CHIPID1 0x4
# define MAX8973_CHIPID2 0x5
# define MAX8973_MAX_VOUT_REG 2
/* MAX8973_VOUT */
# define MAX8973_VOUT_ENABLE BIT(7)
# define MAX8973_VOUT_MASK 0x7F
/* MAX8973_VOUT_DVS */
# define MAX8973_DVS_VOUT_MASK 0x7F
/* MAX8973_CONTROL1 */
# define MAX8973_SNS_ENABLE BIT(7)
# define MAX8973_FPWM_EN_M BIT(6)
# define MAX8973_NFSR_ENABLE BIT(5)
# define MAX8973_AD_ENABLE BIT(4)
# define MAX8973_BIAS_ENABLE BIT(3)
# define MAX8973_FREQSHIFT_9PER BIT(2)
# define MAX8973_RAMP_12mV_PER_US 0x0
# define MAX8973_RAMP_25mV_PER_US 0x1
# define MAX8973_RAMP_50mV_PER_US 0x2
# define MAX8973_RAMP_200mV_PER_US 0x3
2015-06-09 16:47:52 +03:00
# define MAX8973_RAMP_MASK 0x3
2012-11-19 05:28:29 +04:00
/* MAX8973_CONTROL2 */
# define MAX8973_WDTMR_ENABLE BIT(6)
# define MAX8973_DISCH_ENBABLE BIT(5)
# define MAX8973_FT_ENABLE BIT(4)
2016-04-13 12:59:45 +03:00
# define MAX77621_T_JUNCTION_120 BIT(7)
2012-11-19 05:28:29 +04:00
2015-07-01 16:01:44 +03:00
# define MAX8973_CKKADV_TRIP_MASK 0xC
2012-11-19 05:28:29 +04:00
# define MAX8973_CKKADV_TRIP_DISABLE 0xC
# define MAX8973_CKKADV_TRIP_75mV_PER_US 0x0
# define MAX8973_CKKADV_TRIP_150mV_PER_US 0x4
# define MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8
# define MAX8973_CONTROL_CLKADV_TRIP_MASK 0x00030000
# define MAX8973_INDUCTOR_MIN_30_PER 0x0
# define MAX8973_INDUCTOR_NOMINAL 0x1
# define MAX8973_INDUCTOR_PLUS_30_PER 0x2
# define MAX8973_INDUCTOR_PLUS_60_PER 0x3
# define MAX8973_CONTROL_INDUCTOR_VALUE_MASK 0x00300000
# define MAX8973_MIN_VOLATGE 606250
# define MAX8973_MAX_VOLATGE 1400000
# define MAX8973_VOLATGE_STEP 6250
# define MAX8973_BUCK_N_VOLTAGE 0x80
2016-04-13 12:59:45 +03:00
# define MAX77621_CHIPID_TJINT_S BIT(0)
# define MAX77621_NORMAL_OPERATING_TEMP 100000
# define MAX77621_TJINT_WARNING_TEMP_120 120000
# define MAX77621_TJINT_WARNING_TEMP_140 140000
2015-06-09 16:47:53 +03:00
enum device_id {
MAX8973 ,
MAX77621
} ;
2012-11-19 05:28:29 +04:00
/* Maxim 8973 chip information */
struct max8973_chip {
struct device * dev ;
struct regulator_desc desc ;
struct regmap * regmap ;
bool enable_external_control ;
int dvs_gpio ;
int lru_index [ MAX8973_MAX_VOUT_REG ] ;
int curr_vout_val [ MAX8973_MAX_VOUT_REG ] ;
int curr_vout_reg ;
int curr_gpio_val ;
2013-06-21 10:30:22 +04:00
struct regulator_ops ops ;
2015-06-09 16:47:53 +03:00
enum device_id id ;
2016-04-13 12:59:45 +03:00
int junction_temp_warning ;
int irq ;
struct thermal_zone_device * tz_device ;
2012-11-19 05:28:29 +04:00
} ;
/*
* find_voltage_set_register : Find new voltage configuration register ( VOUT ) .
* The finding of the new VOUT register will be based on the LRU mechanism .
* Each VOUT register will have different voltage configured . This
* Function will look if any of the VOUT register have requested voltage set
* or not .
* - If it is already there then it will make that register as most
* recently used and return as found so that caller need not to set
* the VOUT register but need to set the proper gpios to select this
* VOUT register .
* - If requested voltage is not found then it will use the least
* recently mechanism to get new VOUT register for new configuration
* and will return not_found so that caller need to set new VOUT
* register and then gpios ( both ) .
*/
static bool find_voltage_set_register ( struct max8973_chip * tps ,
int req_vsel , int * vout_reg , int * gpio_val )
{
int i ;
bool found = false ;
int new_vout_reg = tps - > lru_index [ MAX8973_MAX_VOUT_REG - 1 ] ;
int found_index = MAX8973_MAX_VOUT_REG - 1 ;
for ( i = 0 ; i < MAX8973_MAX_VOUT_REG ; + + i ) {
if ( tps - > curr_vout_val [ tps - > lru_index [ i ] ] = = req_vsel ) {
new_vout_reg = tps - > lru_index [ i ] ;
found_index = i ;
found = true ;
goto update_lru_index ;
}
}
update_lru_index :
for ( i = found_index ; i > 0 ; i - - )
tps - > lru_index [ i ] = tps - > lru_index [ i - 1 ] ;
tps - > lru_index [ 0 ] = new_vout_reg ;
* gpio_val = new_vout_reg ;
* vout_reg = MAX8973_VOUT + new_vout_reg ;
return found ;
}
static int max8973_dcdc_get_voltage_sel ( struct regulator_dev * rdev )
{
struct max8973_chip * max = rdev_get_drvdata ( rdev ) ;
unsigned int data ;
int ret ;
ret = regmap_read ( max - > regmap , max - > curr_vout_reg , & data ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d read failed, err = %d \n " ,
max - > curr_vout_reg , ret ) ;
return ret ;
}
return data & MAX8973_VOUT_MASK ;
}
static int max8973_dcdc_set_voltage_sel ( struct regulator_dev * rdev ,
unsigned vsel )
{
struct max8973_chip * max = rdev_get_drvdata ( rdev ) ;
int ret ;
bool found = false ;
int vout_reg = max - > curr_vout_reg ;
int gpio_val = max - > curr_gpio_val ;
/*
* If gpios are available to select the VOUT register then least
* recently used register for new configuration .
*/
2015-05-06 15:50:10 +03:00
if ( gpio_is_valid ( max - > dvs_gpio ) )
2012-11-19 05:28:29 +04:00
found = find_voltage_set_register ( max , vsel ,
& vout_reg , & gpio_val ) ;
if ( ! found ) {
ret = regmap_update_bits ( max - > regmap , vout_reg ,
MAX8973_VOUT_MASK , vsel ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d update failed, err %d \n " ,
vout_reg , ret ) ;
return ret ;
}
max - > curr_vout_reg = vout_reg ;
max - > curr_vout_val [ gpio_val ] = vsel ;
}
/* Select proper VOUT register vio gpios */
2015-05-06 15:50:10 +03:00
if ( gpio_is_valid ( max - > dvs_gpio ) ) {
2012-11-19 05:28:29 +04:00
gpio_set_value_cansleep ( max - > dvs_gpio , gpio_val & 0x1 ) ;
max - > curr_gpio_val = gpio_val ;
}
return 0 ;
}
static int max8973_dcdc_set_mode ( struct regulator_dev * rdev , unsigned int mode )
{
struct max8973_chip * max = rdev_get_drvdata ( rdev ) ;
int ret ;
int pwm ;
/* Enable force PWM mode in FAST mode only. */
switch ( mode ) {
case REGULATOR_MODE_FAST :
pwm = MAX8973_FPWM_EN_M ;
break ;
case REGULATOR_MODE_NORMAL :
pwm = 0 ;
break ;
default :
return - EINVAL ;
}
ret = regmap_update_bits ( max - > regmap , MAX8973_CONTROL1 ,
MAX8973_FPWM_EN_M , pwm ) ;
if ( ret < 0 )
dev_err ( max - > dev , " register %d update failed, err %d \n " ,
MAX8973_CONTROL1 , ret ) ;
return ret ;
}
static unsigned int max8973_dcdc_get_mode ( struct regulator_dev * rdev )
{
struct max8973_chip * max = rdev_get_drvdata ( rdev ) ;
unsigned int data ;
int ret ;
ret = regmap_read ( max - > regmap , MAX8973_CONTROL1 , & data ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d read failed, err %d \n " ,
MAX8973_CONTROL1 , ret ) ;
return ret ;
}
return ( data & MAX8973_FPWM_EN_M ) ?
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL ;
}
2015-07-01 16:01:44 +03:00
static int max8973_set_current_limit ( struct regulator_dev * rdev ,
int min_ua , int max_ua )
{
struct max8973_chip * max = rdev_get_drvdata ( rdev ) ;
unsigned int val ;
int ret ;
if ( max_ua < = 9000000 )
val = MAX8973_CKKADV_TRIP_75mV_PER_US ;
else if ( max_ua < = 12000000 )
val = MAX8973_CKKADV_TRIP_150mV_PER_US ;
else
val = MAX8973_CKKADV_TRIP_DISABLE ;
ret = regmap_update_bits ( max - > regmap , MAX8973_CONTROL2 ,
MAX8973_CKKADV_TRIP_MASK , val ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d update failed: %d \n " ,
MAX8973_CONTROL2 , ret ) ;
return ret ;
}
return 0 ;
}
static int max8973_get_current_limit ( struct regulator_dev * rdev )
{
struct max8973_chip * max = rdev_get_drvdata ( rdev ) ;
unsigned int control2 ;
int ret ;
ret = regmap_read ( max - > regmap , MAX8973_CONTROL2 , & control2 ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d read failed: %d \n " ,
MAX8973_CONTROL2 , ret ) ;
return ret ;
}
switch ( control2 & MAX8973_CKKADV_TRIP_MASK ) {
case MAX8973_CKKADV_TRIP_DISABLE :
return 15000000 ;
case MAX8973_CKKADV_TRIP_150mV_PER_US :
return 12000000 ;
case MAX8973_CKKADV_TRIP_75mV_PER_US :
return 9000000 ;
default :
break ;
}
return 9000000 ;
}
2021-05-22 07:08:14 +03:00
static const unsigned int max8973_buck_ramp_table [ ] = {
12000 , 25000 , 50000 , 200000
} ;
2013-06-21 10:30:22 +04:00
static const struct regulator_ops max8973_dcdc_ops = {
2012-11-19 05:28:29 +04:00
. get_voltage_sel = max8973_dcdc_get_voltage_sel ,
. set_voltage_sel = max8973_dcdc_set_voltage_sel ,
. list_voltage = regulator_list_voltage_linear ,
. set_mode = max8973_dcdc_set_mode ,
. get_mode = max8973_dcdc_get_mode ,
2015-06-09 16:47:52 +03:00
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
2021-05-22 07:08:14 +03:00
. set_ramp_delay = regulator_set_ramp_delay_regmap ,
2012-11-19 05:28:29 +04:00
} ;
2012-12-22 01:26:06 +04:00
static int max8973_init_dcdc ( struct max8973_chip * max ,
struct max8973_regulator_platform_data * pdata )
2012-11-19 05:28:29 +04:00
{
int ret ;
uint8_t control1 = 0 ;
uint8_t control2 = 0 ;
2015-06-09 16:47:52 +03:00
unsigned int data ;
ret = regmap_read ( max - > regmap , MAX8973_CONTROL1 , & data ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d read failed, err = %d " ,
MAX8973_CONTROL1 , ret ) ;
return ret ;
}
control1 = data & MAX8973_RAMP_MASK ;
switch ( control1 ) {
case MAX8973_RAMP_12mV_PER_US :
max - > desc . ramp_delay = 12000 ;
break ;
case MAX8973_RAMP_25mV_PER_US :
2015-06-10 13:52:11 +03:00
max - > desc . ramp_delay = 25000 ;
2015-06-09 16:47:52 +03:00
break ;
case MAX8973_RAMP_50mV_PER_US :
max - > desc . ramp_delay = 50000 ;
break ;
case MAX8973_RAMP_200mV_PER_US :
max - > desc . ramp_delay = 200000 ;
break ;
}
2012-11-19 05:28:29 +04:00
if ( pdata - > control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE )
control1 | = MAX8973_SNS_ENABLE ;
if ( ! ( pdata - > control_flags & MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE ) )
control1 | = MAX8973_NFSR_ENABLE ;
if ( pdata - > control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE )
control1 | = MAX8973_AD_ENABLE ;
2015-04-23 13:40:22 +03:00
if ( pdata - > control_flags & MAX8973_CONTROL_BIAS_ENABLE ) {
2012-11-19 05:28:29 +04:00
control1 | = MAX8973_BIAS_ENABLE ;
2015-04-23 13:40:22 +03:00
max - > desc . enable_time = 20 ;
} else {
max - > desc . enable_time = 240 ;
}
2012-11-19 05:28:29 +04:00
if ( pdata - > control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE )
control1 | = MAX8973_FREQSHIFT_9PER ;
2016-04-13 12:59:45 +03:00
if ( ( pdata - > junction_temp_warning = = MAX77621_TJINT_WARNING_TEMP_120 ) & &
( max - > id = = MAX77621 ) )
control2 | = MAX77621_T_JUNCTION_120 ;
2012-11-19 05:28:29 +04:00
if ( ! ( pdata - > control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE ) )
control2 | = MAX8973_DISCH_ENBABLE ;
/* Clock advance trip configuration */
switch ( pdata - > control_flags & MAX8973_CONTROL_CLKADV_TRIP_MASK ) {
case MAX8973_CONTROL_CLKADV_TRIP_DISABLED :
control2 | = MAX8973_CKKADV_TRIP_DISABLE ;
break ;
case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US :
control2 | = MAX8973_CKKADV_TRIP_75mV_PER_US ;
break ;
case MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US :
control2 | = MAX8973_CKKADV_TRIP_150mV_PER_US ;
break ;
case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS :
control2 | = MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS ;
break ;
}
/* Configure inductor value */
switch ( pdata - > control_flags & MAX8973_CONTROL_INDUCTOR_VALUE_MASK ) {
case MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL :
control2 | = MAX8973_INDUCTOR_NOMINAL ;
break ;
case MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER :
control2 | = MAX8973_INDUCTOR_MIN_30_PER ;
break ;
case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER :
control2 | = MAX8973_INDUCTOR_PLUS_30_PER ;
break ;
case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER :
control2 | = MAX8973_INDUCTOR_PLUS_60_PER ;
break ;
}
ret = regmap_write ( max - > regmap , MAX8973_CONTROL1 , control1 ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d write failed, err = %d " ,
MAX8973_CONTROL1 , ret ) ;
return ret ;
}
ret = regmap_write ( max - > regmap , MAX8973_CONTROL2 , control2 ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " register %d write failed, err = %d " ,
MAX8973_CONTROL2 , ret ) ;
return ret ;
}
/* If external control is enabled then disable EN bit */
2015-06-09 16:47:53 +03:00
if ( max - > enable_external_control & & ( max - > id = = MAX8973 ) ) {
2012-11-19 05:28:29 +04:00
ret = regmap_update_bits ( max - > regmap , MAX8973_VOUT ,
MAX8973_VOUT_ENABLE , 0 ) ;
if ( ret < 0 )
dev_err ( max - > dev , " register %d update failed, err = %d " ,
MAX8973_VOUT , ret ) ;
}
return ret ;
}
2022-08-05 01:43:46 +03:00
static int max8973_thermal_read_temp ( struct thermal_zone_device * tz , int * temp )
2016-04-13 12:59:45 +03:00
{
2022-08-05 01:43:46 +03:00
struct max8973_chip * mchip = tz - > devdata ;
2016-04-13 12:59:45 +03:00
unsigned int val ;
int ret ;
ret = regmap_read ( mchip - > regmap , MAX8973_CHIPID1 , & val ) ;
if ( ret < 0 ) {
dev_err ( mchip - > dev , " Failed to read register CHIPID1, %d " , ret ) ;
return ret ;
}
2022-03-05 19:24:38 +03:00
/* +1 degC to trigger cool device */
2016-04-13 12:59:45 +03:00
if ( val & MAX77621_CHIPID_TJINT_S )
* temp = mchip - > junction_temp_warning + 1000 ;
else
* temp = MAX77621_NORMAL_OPERATING_TEMP ;
return 0 ;
}
static irqreturn_t max8973_thermal_irq ( int irq , void * data )
{
struct max8973_chip * mchip = data ;
2016-08-27 02:21:16 +03:00
thermal_zone_device_update ( mchip - > tz_device ,
THERMAL_EVENT_UNSPECIFIED ) ;
2016-04-13 12:59:45 +03:00
return IRQ_HANDLED ;
}
2022-08-05 01:43:46 +03:00
static const struct thermal_zone_device_ops max77621_tz_ops = {
2016-04-13 12:59:45 +03:00
. get_temp = max8973_thermal_read_temp ,
} ;
static int max8973_thermal_init ( struct max8973_chip * mchip )
{
struct thermal_zone_device * tzd ;
struct irq_data * irq_data ;
unsigned long irq_flags = 0 ;
int ret ;
if ( mchip - > id ! = MAX77621 )
return 0 ;
2022-08-05 01:43:46 +03:00
tzd = devm_thermal_of_zone_register ( mchip - > dev , 0 , mchip ,
& max77621_tz_ops ) ;
2016-04-13 12:59:45 +03:00
if ( IS_ERR ( tzd ) ) {
ret = PTR_ERR ( tzd ) ;
dev_err ( mchip - > dev , " Failed to register thermal sensor: %d \n " ,
ret ) ;
return ret ;
}
if ( mchip - > irq < = 0 )
return 0 ;
irq_data = irq_get_irq_data ( mchip - > irq ) ;
if ( irq_data )
irq_flags = irqd_get_trigger_type ( irq_data ) ;
ret = devm_request_threaded_irq ( mchip - > dev , mchip - > irq , NULL ,
max8973_thermal_irq ,
IRQF_ONESHOT | IRQF_SHARED | irq_flags ,
dev_name ( mchip - > dev ) , mchip ) ;
if ( ret < 0 ) {
dev_err ( mchip - > dev , " Failed to request irq %d, %d \n " ,
mchip - > irq , ret ) ;
return ret ;
}
return 0 ;
}
2012-11-19 05:28:29 +04:00
static const struct regmap_config max8973_regmap_config = {
. reg_bits = 8 ,
. val_bits = 8 ,
. max_register = MAX8973_CHIPID2 ,
. cache_type = REGCACHE_RBTREE ,
} ;
2015-04-23 13:40:23 +03:00
static struct max8973_regulator_platform_data * max8973_parse_dt (
struct device * dev )
{
struct max8973_regulator_platform_data * pdata ;
struct device_node * np = dev - > of_node ;
int ret ;
u32 pval ;
2015-07-01 16:01:43 +03:00
bool etr_enable ;
bool etr_sensitivity_high ;
2015-04-23 13:40:23 +03:00
pdata = devm_kzalloc ( dev , sizeof ( * pdata ) , GFP_KERNEL ) ;
if ( ! pdata )
return NULL ;
pdata - > enable_ext_control = of_property_read_bool ( np ,
" maxim,externally-enable " ) ;
pdata - > dvs_gpio = of_get_named_gpio ( np , " maxim,dvs-gpio " , 0 ) ;
ret = of_property_read_u32 ( np , " maxim,dvs-default-state " , & pval ) ;
if ( ! ret )
pdata - > dvs_def_state = pval ;
if ( of_property_read_bool ( np , " maxim,enable-remote-sense " ) )
pdata - > control_flags | = MAX8973_CONTROL_REMOTE_SENSE_ENABLE ;
if ( of_property_read_bool ( np , " maxim,enable-falling-slew-rate " ) )
pdata - > control_flags | =
MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE ;
if ( of_property_read_bool ( np , " maxim,enable-active-discharge " ) )
pdata - > control_flags | =
MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE ;
if ( of_property_read_bool ( np , " maxim,enable-frequency-shift " ) )
pdata - > control_flags | = MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE ;
if ( of_property_read_bool ( np , " maxim,enable-bias-control " ) )
2015-07-01 16:01:42 +03:00
pdata - > control_flags | = MAX8973_CONTROL_BIAS_ENABLE ;
2015-04-23 13:40:23 +03:00
2015-07-01 16:01:43 +03:00
etr_enable = of_property_read_bool ( np , " maxim,enable-etr " ) ;
etr_sensitivity_high = of_property_read_bool ( np ,
" maxim,enable-high-etr-sensitivity " ) ;
if ( etr_sensitivity_high )
etr_enable = true ;
if ( etr_enable ) {
if ( etr_sensitivity_high )
pdata - > control_flags | =
MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US ;
else
pdata - > control_flags | =
MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US ;
} else {
pdata - > control_flags | = MAX8973_CONTROL_CLKADV_TRIP_DISABLED ;
}
2016-04-13 12:59:45 +03:00
pdata - > junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140 ;
ret = of_property_read_u32 ( np , " junction-warn-millicelsius " , & pval ) ;
if ( ! ret & & ( pval < = MAX77621_TJINT_WARNING_TEMP_120 ) )
pdata - > junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120 ;
2015-04-23 13:40:23 +03:00
return pdata ;
}
2015-06-09 16:47:53 +03:00
static const struct of_device_id of_max8973_match_tbl [ ] = {
{ . compatible = " maxim,max8973 " , . data = ( void * ) MAX8973 , } ,
{ . compatible = " maxim,max77621 " , . data = ( void * ) MAX77621 , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , of_max8973_match_tbl ) ;
2012-12-22 01:26:06 +04:00
static int max8973_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
2012-11-19 05:28:29 +04:00
{
struct max8973_regulator_platform_data * pdata ;
2015-04-23 13:40:24 +03:00
struct regulator_init_data * ridata ;
2012-11-19 05:28:29 +04:00
struct regulator_config config = { } ;
struct regulator_dev * rdev ;
struct max8973_chip * max ;
2015-04-23 13:40:23 +03:00
bool pdata_from_dt = false ;
2015-06-09 16:47:53 +03:00
unsigned int chip_id ;
2018-05-14 11:06:25 +03:00
struct gpio_desc * gpiod ;
enum gpiod_flags gflags ;
2012-11-19 05:28:29 +04:00
int ret ;
2013-07-30 12:20:47 +04:00
pdata = dev_get_platdata ( & client - > dev ) ;
2013-06-24 14:50:16 +04:00
2015-04-23 13:40:23 +03:00
if ( ! pdata & & client - > dev . of_node ) {
pdata = max8973_parse_dt ( & client - > dev ) ;
pdata_from_dt = true ;
}
if ( ! pdata ) {
2012-11-19 05:28:29 +04:00
dev_err ( & client - > dev , " No Platform data " ) ;
return - EIO ;
}
2018-05-14 11:06:25 +03:00
if ( pdata - > dvs_gpio = = - EPROBE_DEFER )
2015-04-23 13:40:23 +03:00
return - EPROBE_DEFER ;
2012-11-19 05:28:29 +04:00
max = devm_kzalloc ( & client - > dev , sizeof ( * max ) , GFP_KERNEL ) ;
2014-02-18 14:41:00 +04:00
if ( ! max )
2012-11-19 05:28:29 +04:00
return - ENOMEM ;
max - > regmap = devm_regmap_init_i2c ( client , & max8973_regmap_config ) ;
if ( IS_ERR ( max - > regmap ) ) {
ret = PTR_ERR ( max - > regmap ) ;
dev_err ( & client - > dev , " regmap init failed, err %d \n " , ret ) ;
return ret ;
}
2015-06-09 16:47:53 +03:00
if ( client - > dev . of_node ) {
const struct of_device_id * match ;
match = of_match_device ( of_match_ptr ( of_max8973_match_tbl ) ,
& client - > dev ) ;
if ( ! match )
return - ENODATA ;
max - > id = ( u32 ) ( ( uintptr_t ) match - > data ) ;
} else {
max - > id = id - > driver_data ;
}
ret = regmap_read ( max - > regmap , MAX8973_CHIPID1 , & chip_id ) ;
if ( ret < 0 ) {
dev_err ( & client - > dev , " register CHIPID1 read failed, %d " , ret ) ;
return ret ;
}
dev_info ( & client - > dev , " CHIP-ID OTP: 0x%02x ID_M: 0x%02x \n " ,
( chip_id > > 4 ) & 0xF , ( chip_id > > 1 ) & 0x7 ) ;
2012-11-19 05:28:29 +04:00
i2c_set_clientdata ( client , max ) ;
2013-06-21 10:30:22 +04:00
max - > ops = max8973_dcdc_ops ;
2012-11-19 05:28:29 +04:00
max - > dev = & client - > dev ;
max - > desc . name = id - > name ;
max - > desc . id = 0 ;
2013-06-21 10:30:22 +04:00
max - > desc . ops = & max - > ops ;
2012-11-19 05:28:29 +04:00
max - > desc . type = REGULATOR_VOLTAGE ;
max - > desc . owner = THIS_MODULE ;
max - > desc . min_uV = MAX8973_MIN_VOLATGE ;
max - > desc . uV_step = MAX8973_VOLATGE_STEP ;
max - > desc . n_voltages = MAX8973_BUCK_N_VOLTAGE ;
2021-05-22 07:08:14 +03:00
max - > desc . ramp_reg = MAX8973_CONTROL1 ;
max - > desc . ramp_mask = MAX8973_RAMP_MASK ;
max - > desc . ramp_delay_table = max8973_buck_ramp_table ;
max - > desc . n_ramp_values = ARRAY_SIZE ( max8973_buck_ramp_table ) ;
2012-11-19 05:28:29 +04:00
2015-04-23 13:40:24 +03:00
max - > dvs_gpio = ( pdata - > dvs_gpio ) ? pdata - > dvs_gpio : - EINVAL ;
max - > enable_external_control = pdata - > enable_ext_control ;
max - > curr_gpio_val = pdata - > dvs_def_state ;
max - > curr_vout_reg = MAX8973_VOUT + pdata - > dvs_def_state ;
2016-04-13 12:59:45 +03:00
max - > junction_temp_warning = pdata - > junction_temp_warning ;
2015-04-23 13:40:24 +03:00
2012-11-19 05:28:29 +04:00
max - > lru_index [ 0 ] = max - > curr_vout_reg ;
if ( gpio_is_valid ( max - > dvs_gpio ) ) {
int gpio_flags ;
int i ;
gpio_flags = ( pdata - > dvs_def_state ) ?
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW ;
ret = devm_gpio_request_one ( & client - > dev , max - > dvs_gpio ,
gpio_flags , " max8973-dvs " ) ;
if ( ret ) {
dev_err ( & client - > dev ,
" gpio_request for gpio %d failed, err = %d \n " ,
max - > dvs_gpio , ret ) ;
return ret ;
}
/*
* Initialize the lru index with vout_reg id
* The index 0 will be most recently used and
* set with the max - > curr_vout_reg */
for ( i = 0 ; i < MAX8973_MAX_VOUT_REG ; + + i )
max - > lru_index [ i ] = i ;
max - > lru_index [ 0 ] = max - > curr_vout_reg ;
max - > lru_index [ max - > curr_vout_reg ] = 0 ;
2015-07-28 11:34:11 +03:00
} else {
/*
* If there is no DVS GPIO , the VOUT register
* address is fixed .
*/
max - > ops . set_voltage_sel = regulator_set_voltage_sel_regmap ;
max - > ops . get_voltage_sel = regulator_get_voltage_sel_regmap ;
max - > desc . vsel_reg = max - > curr_vout_reg ;
max - > desc . vsel_mask = MAX8973_VOUT_MASK ;
2012-11-19 05:28:29 +04:00
}
2015-04-23 13:40:23 +03:00
if ( pdata_from_dt )
pdata - > reg_init_data = of_get_regulator_init_data ( & client - > dev ,
client - > dev . of_node , & max - > desc ) ;
2015-06-09 16:47:53 +03:00
ridata = pdata - > reg_init_data ;
switch ( max - > id ) {
case MAX8973 :
if ( ! pdata - > enable_ext_control ) {
max - > desc . enable_reg = MAX8973_VOUT ;
max - > desc . enable_mask = MAX8973_VOUT_ENABLE ;
max - > ops . enable = regulator_enable_regmap ;
max - > ops . disable = regulator_disable_regmap ;
max - > ops . is_enabled = regulator_is_enabled_regmap ;
break ;
}
2018-05-14 11:06:25 +03:00
if ( ridata & & ( ridata - > constraints . always_on | |
ridata - > constraints . boot_on ) )
gflags = GPIOD_OUT_HIGH ;
else
gflags = GPIOD_OUT_LOW ;
2018-10-15 12:02:40 +03:00
gflags | = GPIOD_FLAGS_BIT_NONEXCLUSIVE ;
2018-05-14 11:06:25 +03:00
gpiod = devm_gpiod_get_optional ( & client - > dev ,
" maxim,enable " ,
gflags ) ;
if ( IS_ERR ( gpiod ) )
return PTR_ERR ( gpiod ) ;
if ( gpiod ) {
config . ena_gpiod = gpiod ;
max - > enable_external_control = true ;
2015-06-09 16:47:53 +03:00
}
2018-05-14 11:06:25 +03:00
2015-06-09 16:47:53 +03:00
break ;
case MAX77621 :
2018-05-14 11:06:25 +03:00
/*
* We do not let the core switch this regulator on / off ,
* we just leave it on .
*/
gpiod = devm_gpiod_get_optional ( & client - > dev ,
" maxim,enable " ,
GPIOD_OUT_HIGH ) ;
if ( IS_ERR ( gpiod ) )
return PTR_ERR ( gpiod ) ;
if ( gpiod )
max - > enable_external_control = true ;
2015-06-09 16:47:53 +03:00
max - > desc . enable_reg = MAX8973_VOUT ;
max - > desc . enable_mask = MAX8973_VOUT_ENABLE ;
max - > ops . enable = regulator_enable_regmap ;
max - > ops . disable = regulator_disable_regmap ;
max - > ops . is_enabled = regulator_is_enabled_regmap ;
2015-07-01 16:01:44 +03:00
max - > ops . set_current_limit = max8973_set_current_limit ;
max - > ops . get_current_limit = max8973_get_current_limit ;
2015-06-09 16:47:53 +03:00
break ;
default :
break ;
}
2015-04-23 13:40:23 +03:00
ret = max8973_init_dcdc ( max , pdata ) ;
if ( ret < 0 ) {
dev_err ( max - > dev , " Max8973 Init failed, err = %d \n " , ret ) ;
return ret ;
2012-11-19 05:28:29 +04:00
}
config . dev = & client - > dev ;
2015-04-23 13:40:23 +03:00
config . init_data = pdata - > reg_init_data ;
2012-11-19 05:28:29 +04:00
config . driver_data = max ;
config . of_node = client - > dev . of_node ;
config . regmap = max - > regmap ;
2018-12-06 15:43:47 +03:00
/*
* Register the regulators
* Turn the GPIO descriptor over to the regulator core for
* lifecycle management if we pass an ena_gpiod .
*/
if ( config . ena_gpiod )
devm_gpiod_unhinge ( & client - > dev , config . ena_gpiod ) ;
2013-09-04 09:38:00 +04:00
rdev = devm_regulator_register ( & client - > dev , & max - > desc , & config ) ;
2012-11-19 05:28:29 +04:00
if ( IS_ERR ( rdev ) ) {
ret = PTR_ERR ( rdev ) ;
dev_err ( max - > dev , " regulator register failed, err %d \n " , ret ) ;
return ret ;
}
2016-04-13 12:59:45 +03:00
max8973_thermal_init ( max ) ;
2012-11-19 05:28:29 +04:00
return 0 ;
}
static const struct i2c_device_id max8973_id [ ] = {
2015-06-09 16:47:53 +03:00
{ . name = " max8973 " , . driver_data = MAX8973 } ,
{ . name = " max77621 " , . driver_data = MAX77621 } ,
2012-11-19 05:28:29 +04:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( i2c , max8973_id ) ;
static struct i2c_driver max8973_i2c_driver = {
. driver = {
. name = " max8973 " ,
2015-06-09 16:47:53 +03:00
. of_match_table = of_max8973_match_tbl ,
2012-11-19 05:28:29 +04:00
} ,
. probe = max8973_probe ,
. id_table = max8973_id ,
} ;
static int __init max8973_init ( void )
{
return i2c_add_driver ( & max8973_i2c_driver ) ;
}
subsys_initcall ( max8973_init ) ;
static void __exit max8973_cleanup ( void )
{
i2c_del_driver ( & max8973_i2c_driver ) ;
}
module_exit ( max8973_cleanup ) ;
MODULE_AUTHOR ( " Laxman Dewangan <ldewangan@nvidia.com> " ) ;
MODULE_DESCRIPTION ( " MAX8973 voltage regulator driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;