2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-05-03 01:20:08 +04:00
/*
* tps65910 . c - - TI tps65910
*
* Copyright 2010 Texas Instruments Inc .
*
* Author : Graeme Gregory < gg @ slimlogic . co . uk >
* Author : Jorge Eduardo Candelaria < jedu @ slimlogic . co . uk >
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/err.h>
2015-03-15 16:03:50 +03:00
# include <linux/of.h>
2011-05-03 01:20:08 +04:00
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
# include <linux/slab.h>
# include <linux/gpio.h>
# include <linux/mfd/tps65910.h>
2012-05-08 22:42:41 +04:00
# include <linux/regulator/of_regulator.h>
2011-05-03 01:20:08 +04:00
# define TPS65910_SUPPLY_STATE_ENABLED 0x1
2012-01-28 13:37:57 +04:00
# define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \
2012-03-07 16:51:49 +04:00
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \
TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP )
2011-05-03 01:20:08 +04:00
2012-06-21 14:48:00 +04:00
/* supported VIO voltages in microvolts */
static const unsigned int VIO_VSEL_table [ ] = {
1500000 , 1800000 , 2500000 , 3300000 ,
2011-05-03 01:20:08 +04:00
} ;
2011-05-17 03:35:03 +04:00
/* VSEL tables for TPS65910 specific LDOs and dcdc's */
2012-10-15 16:15:58 +04:00
/* supported VRTC voltages in microvolts */
static const unsigned int VRTC_VSEL_table [ ] = {
1800000 ,
} ;
2012-06-21 14:48:00 +04:00
/* supported VDD3 voltages in microvolts */
static const unsigned int VDD3_VSEL_table [ ] = {
5000000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VDIG1 voltages in microvolts */
static const unsigned int VDIG1_VSEL_table [ ] = {
1200000 , 1500000 , 1800000 , 2700000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VDIG2 voltages in microvolts */
static const unsigned int VDIG2_VSEL_table [ ] = {
1000000 , 1100000 , 1200000 , 1800000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VPLL voltages in microvolts */
static const unsigned int VPLL_VSEL_table [ ] = {
1000000 , 1100000 , 1800000 , 2500000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VDAC voltages in microvolts */
static const unsigned int VDAC_VSEL_table [ ] = {
1800000 , 2600000 , 2800000 , 2850000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VAUX1 voltages in microvolts */
static const unsigned int VAUX1_VSEL_table [ ] = {
1800000 , 2500000 , 2800000 , 2850000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VAUX2 voltages in microvolts */
static const unsigned int VAUX2_VSEL_table [ ] = {
1800000 , 2800000 , 2900000 , 3300000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VAUX33 voltages in microvolts */
static const unsigned int VAUX33_VSEL_table [ ] = {
1800000 , 2000000 , 2800000 , 3300000 ,
2011-05-03 01:20:08 +04:00
} ;
2012-06-21 14:48:00 +04:00
/* supported VMMC voltages in microvolts */
static const unsigned int VMMC_VSEL_table [ ] = {
1800000 , 2800000 , 3000000 , 3300000 ,
2011-05-03 01:20:08 +04:00
} ;
2013-12-20 15:43:27 +04:00
/* supported BBCH voltages in microvolts */
static const unsigned int VBB_VSEL_table [ ] = {
3000000 , 2520000 , 3150000 , 5000000 ,
} ;
2011-05-03 01:20:08 +04:00
struct tps_info {
const char * name ;
2012-07-06 12:43:12 +04:00
const char * vin_name ;
2012-01-20 15:06:22 +04:00
u8 n_voltages ;
2012-06-21 14:48:00 +04:00
const unsigned int * voltage_table ;
2012-03-13 10:05:20 +04:00
int enable_time_us ;
2011-05-03 01:20:08 +04:00
} ;
static struct tps_info tps65910_regs [ ] = {
{
2012-05-19 18:34:06 +04:00
. name = " vrtc " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc7 " ,
2012-10-15 16:15:58 +04:00
. n_voltages = ARRAY_SIZE ( VRTC_VSEL_table ) ,
. voltage_table = VRTC_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 2200 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vio " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vccio " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VIO_VSEL_table ) ,
. voltage_table = VIO_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 350 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdd1 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc1 " ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 350 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdd2 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc2 " ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 350 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdd3 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VDD3_VSEL_table ) ,
. voltage_table = VDD3_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 200 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdig1 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc6 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VDIG1_VSEL_table ) ,
. voltage_table = VDIG1_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdig2 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc6 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VDIG2_VSEL_table ) ,
. voltage_table = VDIG2_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vpll " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc5 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VPLL_VSEL_table ) ,
. voltage_table = VPLL_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdac " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc5 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VDAC_VSEL_table ) ,
. voltage_table = VDAC_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vaux1 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc4 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VAUX1_VSEL_table ) ,
. voltage_table = VAUX1_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vaux2 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc4 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VAUX2_VSEL_table ) ,
. voltage_table = VAUX2_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vaux33 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc3 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VAUX33_VSEL_table ) ,
. voltage_table = VAUX33_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vmmc " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc3 " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VMMC_VSEL_table ) ,
. voltage_table = VMMC_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 100 ,
2011-05-03 01:20:08 +04:00
} ,
2013-12-20 15:43:27 +04:00
{
. name = " vbb " ,
. vin_name = " vcc7 " ,
. n_voltages = ARRAY_SIZE ( VBB_VSEL_table ) ,
. voltage_table = VBB_VSEL_table ,
} ,
2011-05-03 01:20:08 +04:00
} ;
2011-05-17 03:35:03 +04:00
static struct tps_info tps65911_regs [ ] = {
2012-01-18 19:16:56 +04:00
{
2012-05-19 18:34:06 +04:00
. name = " vrtc " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc7 " ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 2200 ,
2012-01-18 19:16:56 +04:00
} ,
2011-05-17 03:35:03 +04:00
{
2012-05-19 18:34:06 +04:00
. name = " vio " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vccio " ,
2012-01-20 15:06:22 +04:00
. n_voltages = ARRAY_SIZE ( VIO_VSEL_table ) ,
. voltage_table = VIO_VSEL_table ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 350 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdd1 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc1 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x4C ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 350 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vdd2 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc2 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x4C ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 350 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " vddctrl " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x44 ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 900 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo1 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc6 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x33 ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 420 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo2 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc6 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x33 ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 420 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo3 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc5 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x1A ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 230 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo4 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc5 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x33 ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 230 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo5 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc4 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x1A ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 230 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo6 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc3 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x1A ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 230 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo7 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc3 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x1A ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 230 ,
2011-05-17 03:35:03 +04:00
} ,
{
2012-05-19 18:34:06 +04:00
. name = " ldo8 " ,
2012-07-06 12:43:12 +04:00
. vin_name = " vcc3 " ,
2012-07-09 18:57:13 +04:00
. n_voltages = 0x1A ,
2012-03-13 10:05:20 +04:00
. enable_time_us = 230 ,
2011-05-17 03:35:03 +04:00
} ,
} ;
2012-01-28 13:37:57 +04:00
# define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits))
static unsigned int tps65910_ext_sleep_control [ ] = {
0 ,
EXT_CONTROL_REG_BITS ( VIO , 1 , 0 ) ,
EXT_CONTROL_REG_BITS ( VDD1 , 1 , 1 ) ,
EXT_CONTROL_REG_BITS ( VDD2 , 1 , 2 ) ,
EXT_CONTROL_REG_BITS ( VDD3 , 1 , 3 ) ,
EXT_CONTROL_REG_BITS ( VDIG1 , 0 , 1 ) ,
EXT_CONTROL_REG_BITS ( VDIG2 , 0 , 2 ) ,
EXT_CONTROL_REG_BITS ( VPLL , 0 , 6 ) ,
EXT_CONTROL_REG_BITS ( VDAC , 0 , 7 ) ,
EXT_CONTROL_REG_BITS ( VAUX1 , 0 , 3 ) ,
EXT_CONTROL_REG_BITS ( VAUX2 , 0 , 4 ) ,
EXT_CONTROL_REG_BITS ( VAUX33 , 0 , 5 ) ,
EXT_CONTROL_REG_BITS ( VMMC , 0 , 0 ) ,
} ;
static unsigned int tps65911_ext_sleep_control [ ] = {
0 ,
EXT_CONTROL_REG_BITS ( VIO , 1 , 0 ) ,
EXT_CONTROL_REG_BITS ( VDD1 , 1 , 1 ) ,
EXT_CONTROL_REG_BITS ( VDD2 , 1 , 2 ) ,
EXT_CONTROL_REG_BITS ( VDDCTRL , 1 , 3 ) ,
EXT_CONTROL_REG_BITS ( LDO1 , 0 , 1 ) ,
EXT_CONTROL_REG_BITS ( LDO2 , 0 , 2 ) ,
EXT_CONTROL_REG_BITS ( LDO3 , 0 , 7 ) ,
EXT_CONTROL_REG_BITS ( LDO4 , 0 , 6 ) ,
EXT_CONTROL_REG_BITS ( LDO5 , 0 , 3 ) ,
EXT_CONTROL_REG_BITS ( LDO6 , 0 , 0 ) ,
EXT_CONTROL_REG_BITS ( LDO7 , 0 , 5 ) ,
EXT_CONTROL_REG_BITS ( LDO8 , 0 , 4 ) ,
} ;
2011-05-03 01:20:08 +04:00
struct tps65910_reg {
2011-07-11 05:57:43 +04:00
struct regulator_desc * desc ;
2011-05-03 01:20:08 +04:00
struct tps65910 * mfd ;
2011-07-11 05:57:43 +04:00
struct regulator_dev * * rdev ;
struct tps_info * * info ;
int num_regulators ;
2011-05-03 01:20:08 +04:00
int mode ;
2011-05-17 03:35:03 +04:00
int ( * get_ctrl_reg ) ( int ) ;
2012-01-28 13:37:57 +04:00
unsigned int * ext_sleep_control ;
unsigned int board_ext_control [ TPS65910_NUM_REGS ] ;
2011-05-03 01:20:08 +04:00
} ;
static int tps65910_get_ctrl_register ( int id )
{
switch ( id ) {
case TPS65910_REG_VRTC :
return TPS65910_VRTC ;
case TPS65910_REG_VIO :
return TPS65910_VIO ;
case TPS65910_REG_VDD1 :
return TPS65910_VDD1 ;
case TPS65910_REG_VDD2 :
return TPS65910_VDD2 ;
case TPS65910_REG_VDD3 :
return TPS65910_VDD3 ;
case TPS65910_REG_VDIG1 :
return TPS65910_VDIG1 ;
case TPS65910_REG_VDIG2 :
return TPS65910_VDIG2 ;
case TPS65910_REG_VPLL :
return TPS65910_VPLL ;
case TPS65910_REG_VDAC :
return TPS65910_VDAC ;
case TPS65910_REG_VAUX1 :
return TPS65910_VAUX1 ;
case TPS65910_REG_VAUX2 :
return TPS65910_VAUX2 ;
case TPS65910_REG_VAUX33 :
return TPS65910_VAUX33 ;
case TPS65910_REG_VMMC :
return TPS65910_VMMC ;
2013-12-20 15:43:27 +04:00
case TPS65910_REG_VBB :
return TPS65910_BBCH ;
2011-05-03 01:20:08 +04:00
default :
return - EINVAL ;
}
}
2011-05-17 03:35:03 +04:00
static int tps65911_get_ctrl_register ( int id )
{
switch ( id ) {
case TPS65910_REG_VRTC :
return TPS65910_VRTC ;
case TPS65910_REG_VIO :
return TPS65910_VIO ;
case TPS65910_REG_VDD1 :
return TPS65910_VDD1 ;
case TPS65910_REG_VDD2 :
return TPS65910_VDD2 ;
case TPS65911_REG_VDDCTRL :
return TPS65911_VDDCTRL ;
case TPS65911_REG_LDO1 :
return TPS65911_LDO1 ;
case TPS65911_REG_LDO2 :
return TPS65911_LDO2 ;
case TPS65911_REG_LDO3 :
return TPS65911_LDO3 ;
case TPS65911_REG_LDO4 :
return TPS65911_LDO4 ;
case TPS65911_REG_LDO5 :
return TPS65911_LDO5 ;
case TPS65911_REG_LDO6 :
return TPS65911_LDO6 ;
case TPS65911_REG_LDO7 :
return TPS65911_LDO7 ;
case TPS65911_REG_LDO8 :
return TPS65911_LDO8 ;
default :
return - EINVAL ;
}
}
2011-05-03 01:20:08 +04:00
static int tps65910_set_mode ( struct regulator_dev * dev , unsigned int mode )
{
struct tps65910_reg * pmic = rdev_get_drvdata ( dev ) ;
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
int reg , id = rdev_get_id ( dev ) ;
2011-05-17 03:35:03 +04:00
reg = pmic - > get_ctrl_reg ( id ) ;
2011-05-03 01:20:08 +04:00
if ( reg < 0 )
return reg ;
switch ( mode ) {
case REGULATOR_MODE_NORMAL :
2020-09-27 02:59:15 +03:00
return regmap_update_bits ( regmap , reg ,
LDO_ST_MODE_BIT | LDO_ST_ON_BIT ,
LDO_ST_ON_BIT ) ;
2011-05-03 01:20:08 +04:00
case REGULATOR_MODE_IDLE :
2020-09-27 02:59:15 +03:00
return regmap_set_bits ( regmap , reg ,
LDO_ST_ON_BIT | LDO_ST_MODE_BIT ) ;
2011-05-03 01:20:08 +04:00
case REGULATOR_MODE_STANDBY :
2020-09-27 02:59:15 +03:00
return regmap_clear_bits ( regmap , reg , LDO_ST_ON_BIT ) ;
2011-05-03 01:20:08 +04:00
}
return - EINVAL ;
}
static unsigned int tps65910_get_mode ( struct regulator_dev * dev )
{
struct tps65910_reg * pmic = rdev_get_drvdata ( dev ) ;
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
2012-07-11 15:44:13 +04:00
int ret , reg , value , id = rdev_get_id ( dev ) ;
2011-05-03 01:20:08 +04:00
2011-05-17 03:35:03 +04:00
reg = pmic - > get_ctrl_reg ( id ) ;
2011-05-03 01:20:08 +04:00
if ( reg < 0 )
return reg ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , reg , & value ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-03 01:20:08 +04:00
2012-03-13 03:15:27 +04:00
if ( ! ( value & LDO_ST_ON_BIT ) )
2011-05-03 01:20:08 +04:00
return REGULATOR_MODE_STANDBY ;
else if ( value & LDO_ST_MODE_BIT )
return REGULATOR_MODE_IDLE ;
else
return REGULATOR_MODE_NORMAL ;
}
2012-03-14 11:30:58 +04:00
static int tps65910_get_voltage_dcdc_sel ( struct regulator_dev * dev )
2011-05-03 01:20:08 +04:00
{
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
2012-07-11 15:44:13 +04:00
int ret , id = rdev_get_id ( dev ) ;
2011-05-17 03:35:03 +04:00
int opvsel = 0 , srvsel = 0 , vselmax = 0 , mult = 0 , sr = 0 ;
2011-05-03 01:20:08 +04:00
switch ( id ) {
case TPS65910_REG_VDD1 :
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65910_VDD1_OP , & opvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65910_VDD1 , & mult ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-03 01:20:08 +04:00
mult = ( mult & VDD1_VGAIN_SEL_MASK ) > > VDD1_VGAIN_SEL_SHIFT ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65910_VDD1_SR , & srvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-03 01:20:08 +04:00
sr = opvsel & VDD1_OP_CMD_MASK ;
opvsel & = VDD1_OP_SEL_MASK ;
srvsel & = VDD1_SR_SEL_MASK ;
2011-05-17 03:35:03 +04:00
vselmax = 75 ;
2011-05-03 01:20:08 +04:00
break ;
case TPS65910_REG_VDD2 :
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65910_VDD2_OP , & opvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65910_VDD2 , & mult ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-03 01:20:08 +04:00
mult = ( mult & VDD2_VGAIN_SEL_MASK ) > > VDD2_VGAIN_SEL_SHIFT ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65910_VDD2_SR , & srvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-03 01:20:08 +04:00
sr = opvsel & VDD2_OP_CMD_MASK ;
opvsel & = VDD2_OP_SEL_MASK ;
srvsel & = VDD2_SR_SEL_MASK ;
2011-05-17 03:35:03 +04:00
vselmax = 75 ;
break ;
case TPS65911_REG_VDDCTRL :
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65911_VDDCTRL_OP , & opvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , TPS65911_VDDCTRL_SR , & srvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-17 03:35:03 +04:00
sr = opvsel & VDDCTRL_OP_CMD_MASK ;
opvsel & = VDDCTRL_OP_SEL_MASK ;
srvsel & = VDDCTRL_SR_SEL_MASK ;
vselmax = 64 ;
2011-05-03 01:20:08 +04:00
break ;
}
/* multiplier 0 == 1 but 2,3 normal */
if ( ! mult )
2013-10-14 12:53:40 +04:00
mult = 1 ;
2011-05-03 01:20:08 +04:00
if ( sr ) {
2011-05-17 03:35:03 +04:00
/* normalise to valid range */
if ( srvsel < 3 )
srvsel = 3 ;
if ( srvsel > vselmax )
srvsel = vselmax ;
2012-03-14 11:30:58 +04:00
return srvsel - 3 ;
2011-05-03 01:20:08 +04:00
} else {
2011-05-17 03:35:03 +04:00
/* normalise to valid range*/
if ( opvsel < 3 )
opvsel = 3 ;
if ( opvsel > vselmax )
opvsel = vselmax ;
2012-03-14 11:30:58 +04:00
return opvsel - 3 ;
2011-05-03 01:20:08 +04:00
}
2012-03-14 11:30:58 +04:00
return - EINVAL ;
2011-05-03 01:20:08 +04:00
}
2012-05-09 05:22:47 +04:00
static int tps65910_get_voltage_sel ( struct regulator_dev * dev )
2011-05-03 01:20:08 +04:00
{
struct tps65910_reg * pmic = rdev_get_drvdata ( dev ) ;
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
2012-07-11 15:44:13 +04:00
int ret , reg , value , id = rdev_get_id ( dev ) ;
2011-05-03 01:20:08 +04:00
2011-05-17 03:35:03 +04:00
reg = pmic - > get_ctrl_reg ( id ) ;
2011-05-03 01:20:08 +04:00
if ( reg < 0 )
return reg ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , reg , & value ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-03 01:20:08 +04:00
switch ( id ) {
case TPS65910_REG_VIO :
case TPS65910_REG_VDIG1 :
case TPS65910_REG_VDIG2 :
case TPS65910_REG_VPLL :
case TPS65910_REG_VDAC :
case TPS65910_REG_VAUX1 :
case TPS65910_REG_VAUX2 :
case TPS65910_REG_VAUX33 :
case TPS65910_REG_VMMC :
value & = LDO_SEL_MASK ;
value > > = LDO_SEL_SHIFT ;
break ;
2013-12-20 15:43:27 +04:00
case TPS65910_REG_VBB :
value & = BBCH_BBSEL_MASK ;
value > > = BBCH_BBSEL_SHIFT ;
break ;
2011-05-03 01:20:08 +04:00
default :
return - EINVAL ;
}
2012-05-09 05:22:47 +04:00
return value ;
2011-05-03 01:20:08 +04:00
}
static int tps65910_get_voltage_vdd3 ( struct regulator_dev * dev )
{
2012-06-21 14:48:00 +04:00
return dev - > desc - > volt_table [ 0 ] ;
2011-05-03 01:20:08 +04:00
}
2012-05-09 05:22:47 +04:00
static int tps65911_get_voltage_sel ( struct regulator_dev * dev )
2011-05-17 03:35:03 +04:00
{
struct tps65910_reg * pmic = rdev_get_drvdata ( dev ) ;
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
2012-07-11 15:44:13 +04:00
int ret , id = rdev_get_id ( dev ) ;
unsigned int value , reg ;
2011-05-17 03:35:03 +04:00
reg = pmic - > get_ctrl_reg ( id ) ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( regmap , reg , & value ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2011-05-17 03:35:03 +04:00
switch ( id ) {
case TPS65911_REG_LDO1 :
case TPS65911_REG_LDO2 :
case TPS65911_REG_LDO4 :
value & = LDO1_SEL_MASK ;
value > > = LDO_SEL_SHIFT ;
break ;
case TPS65911_REG_LDO3 :
case TPS65911_REG_LDO5 :
case TPS65911_REG_LDO6 :
case TPS65911_REG_LDO7 :
case TPS65911_REG_LDO8 :
value & = LDO3_SEL_MASK ;
value > > = LDO_SEL_SHIFT ;
break ;
case TPS65910_REG_VIO :
2012-02-17 17:26:11 +04:00
value & = LDO_SEL_MASK ;
value > > = LDO_SEL_SHIFT ;
2012-05-09 05:22:47 +04:00
break ;
2011-05-17 03:35:03 +04:00
default :
return - EINVAL ;
}
2012-05-09 05:22:47 +04:00
return value ;
2011-05-17 03:35:03 +04:00
}
2012-03-09 06:22:20 +04:00
static int tps65910_set_voltage_dcdc_sel ( struct regulator_dev * dev ,
unsigned selector )
2011-05-03 01:20:08 +04:00
{
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
2011-05-03 01:20:08 +04:00
int id = rdev_get_id ( dev ) , vsel ;
2011-05-17 03:35:03 +04:00
int dcdc_mult = 0 ;
2011-05-03 01:20:08 +04:00
2011-05-17 03:35:03 +04:00
switch ( id ) {
case TPS65910_REG_VDD1 :
2011-11-08 17:24:10 +04:00
dcdc_mult = ( selector / VDD1_2_NUM_VOLT_FINE ) + 1 ;
2011-05-17 03:35:03 +04:00
if ( dcdc_mult = = 1 )
dcdc_mult - - ;
2011-11-08 17:24:10 +04:00
vsel = ( selector % VDD1_2_NUM_VOLT_FINE ) + 3 ;
2011-05-03 01:20:08 +04:00
2020-09-27 02:59:15 +03:00
regmap_update_bits ( regmap , TPS65910_VDD1 , VDD1_VGAIN_SEL_MASK ,
dcdc_mult < < VDD1_VGAIN_SEL_SHIFT ) ;
regmap_write ( regmap , TPS65910_VDD1_OP , vsel ) ;
2011-05-17 03:35:03 +04:00
break ;
case TPS65910_REG_VDD2 :
2011-11-08 17:24:10 +04:00
dcdc_mult = ( selector / VDD1_2_NUM_VOLT_FINE ) + 1 ;
2011-05-17 03:35:03 +04:00
if ( dcdc_mult = = 1 )
dcdc_mult - - ;
2011-11-08 17:24:10 +04:00
vsel = ( selector % VDD1_2_NUM_VOLT_FINE ) + 3 ;
2011-05-17 03:35:03 +04:00
2020-09-27 02:59:15 +03:00
regmap_update_bits ( regmap , TPS65910_VDD2 , VDD1_VGAIN_SEL_MASK ,
dcdc_mult < < VDD2_VGAIN_SEL_SHIFT ) ;
regmap_write ( regmap , TPS65910_VDD2_OP , vsel ) ;
2011-05-17 03:35:03 +04:00
break ;
case TPS65911_REG_VDDCTRL :
2012-03-07 15:09:05 +04:00
vsel = selector + 3 ;
2020-09-27 02:59:15 +03:00
regmap_write ( regmap , TPS65911_VDDCTRL_OP , vsel ) ;
break ;
2011-05-03 01:20:08 +04:00
}
return 0 ;
}
2012-03-09 06:22:20 +04:00
static int tps65910_set_voltage_sel ( struct regulator_dev * dev ,
unsigned selector )
2011-05-03 01:20:08 +04:00
{
struct tps65910_reg * pmic = rdev_get_drvdata ( dev ) ;
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
2011-05-03 01:20:08 +04:00
int reg , id = rdev_get_id ( dev ) ;
2011-05-17 03:35:03 +04:00
reg = pmic - > get_ctrl_reg ( id ) ;
2011-05-03 01:20:08 +04:00
if ( reg < 0 )
return reg ;
switch ( id ) {
case TPS65910_REG_VIO :
case TPS65910_REG_VDIG1 :
case TPS65910_REG_VDIG2 :
case TPS65910_REG_VPLL :
case TPS65910_REG_VDAC :
case TPS65910_REG_VAUX1 :
case TPS65910_REG_VAUX2 :
case TPS65910_REG_VAUX33 :
case TPS65910_REG_VMMC :
2020-09-27 02:59:15 +03:00
return regmap_update_bits ( regmap , reg , LDO_SEL_MASK ,
selector < < LDO_SEL_SHIFT ) ;
2013-12-20 15:43:27 +04:00
case TPS65910_REG_VBB :
2020-09-27 02:59:15 +03:00
return regmap_update_bits ( regmap , reg , BBCH_BBSEL_MASK ,
selector < < BBCH_BBSEL_SHIFT ) ;
2011-05-03 01:20:08 +04:00
}
return - EINVAL ;
}
2012-03-09 06:22:20 +04:00
static int tps65911_set_voltage_sel ( struct regulator_dev * dev ,
unsigned selector )
2011-05-17 03:35:03 +04:00
{
struct tps65910_reg * pmic = rdev_get_drvdata ( dev ) ;
2020-09-27 02:59:15 +03:00
struct regmap * regmap = rdev_get_regmap ( dev ) ;
2011-05-17 03:35:03 +04:00
int reg , id = rdev_get_id ( dev ) ;
reg = pmic - > get_ctrl_reg ( id ) ;
if ( reg < 0 )
return reg ;
switch ( id ) {
case TPS65911_REG_LDO1 :
case TPS65911_REG_LDO2 :
case TPS65911_REG_LDO4 :
2020-09-27 02:59:15 +03:00
return regmap_update_bits ( regmap , reg , LDO1_SEL_MASK ,
selector < < LDO_SEL_SHIFT ) ;
2011-05-17 03:35:03 +04:00
case TPS65911_REG_LDO3 :
case TPS65911_REG_LDO5 :
case TPS65911_REG_LDO6 :
case TPS65911_REG_LDO7 :
case TPS65911_REG_LDO8 :
2020-09-27 02:59:15 +03:00
return regmap_update_bits ( regmap , reg , LDO3_SEL_MASK ,
selector < < LDO_SEL_SHIFT ) ;
2012-02-17 17:26:11 +04:00
case TPS65910_REG_VIO :
2020-09-27 02:59:15 +03:00
return regmap_update_bits ( regmap , reg , LDO_SEL_MASK ,
selector < < LDO_SEL_SHIFT ) ;
2013-12-20 15:43:27 +04:00
case TPS65910_REG_VBB :
2020-09-27 02:59:15 +03:00
return regmap_update_bits ( regmap , reg , BBCH_BBSEL_MASK ,
selector < < BBCH_BBSEL_SHIFT ) ;
2011-05-17 03:35:03 +04:00
}
return - EINVAL ;
}
2011-05-03 01:20:08 +04:00
static int tps65910_list_voltage_dcdc ( struct regulator_dev * dev ,
unsigned selector )
{
2011-05-17 03:35:03 +04:00
int volt , mult = 1 , id = rdev_get_id ( dev ) ;
2011-05-03 01:20:08 +04:00
2011-05-17 03:35:03 +04:00
switch ( id ) {
case TPS65910_REG_VDD1 :
case TPS65910_REG_VDD2 :
2011-11-08 17:24:10 +04:00
mult = ( selector / VDD1_2_NUM_VOLT_FINE ) + 1 ;
2011-05-17 03:35:03 +04:00
volt = VDD1_2_MIN_VOLT +
2013-10-14 12:53:40 +04:00
( selector % VDD1_2_NUM_VOLT_FINE ) * VDD1_2_OFFSET ;
2011-07-10 17:44:09 +04:00
break ;
2011-05-17 03:35:03 +04:00
case TPS65911_REG_VDDCTRL :
volt = VDDCTRL_MIN_VOLT + ( selector * VDDCTRL_OFFSET ) ;
2011-07-10 17:44:09 +04:00
break ;
default :
BUG ( ) ;
return - EINVAL ;
2011-05-17 03:35:03 +04:00
}
2011-05-03 01:20:08 +04:00
return volt * 100 * mult ;
}
2011-05-17 03:35:03 +04:00
static int tps65911_list_voltage ( struct regulator_dev * dev , unsigned selector )
{
struct tps65910_reg * pmic = rdev_get_drvdata ( dev ) ;
int step_mv = 0 , id = rdev_get_id ( dev ) ;
2013-10-14 12:53:40 +04:00
switch ( id ) {
2011-05-17 03:35:03 +04:00
case TPS65911_REG_LDO1 :
case TPS65911_REG_LDO2 :
case TPS65911_REG_LDO4 :
/* The first 5 values of the selector correspond to 1V */
if ( selector < 5 )
selector = 0 ;
else
selector - = 4 ;
step_mv = 50 ;
break ;
case TPS65911_REG_LDO3 :
case TPS65911_REG_LDO5 :
case TPS65911_REG_LDO6 :
case TPS65911_REG_LDO7 :
case TPS65911_REG_LDO8 :
/* The first 3 values of the selector correspond to 1V */
if ( selector < 3 )
selector = 0 ;
else
selector - = 2 ;
step_mv = 100 ;
break ;
case TPS65910_REG_VIO :
2012-06-21 14:48:00 +04:00
return pmic - > info [ id ] - > voltage_table [ selector ] ;
2011-05-17 03:35:03 +04:00
default :
return - EINVAL ;
}
return ( LDO_MIN_VOLT + selector * step_mv ) * 1000 ;
}
2011-05-03 01:20:08 +04:00
/* Regulator ops (except VRTC) */
2020-08-30 01:11:04 +03:00
static const struct regulator_ops tps65910_ops_dcdc = {
2012-04-17 10:34:46 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
2011-05-03 01:20:08 +04:00
. set_mode = tps65910_set_mode ,
. get_mode = tps65910_get_mode ,
2012-03-14 11:30:58 +04:00
. get_voltage_sel = tps65910_get_voltage_dcdc_sel ,
2012-03-09 06:22:20 +04:00
. set_voltage_sel = tps65910_set_voltage_dcdc_sel ,
2012-06-20 18:40:10 +04:00
. set_voltage_time_sel = regulator_set_voltage_time_sel ,
2011-05-03 01:20:08 +04:00
. list_voltage = tps65910_list_voltage_dcdc ,
2013-04-20 06:30:17 +04:00
. map_voltage = regulator_map_voltage_ascend ,
2011-05-03 01:20:08 +04:00
} ;
2020-08-30 01:11:04 +03:00
static const struct regulator_ops tps65910_ops_vdd3 = {
2012-04-17 10:34:46 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
2011-05-03 01:20:08 +04:00
. set_mode = tps65910_set_mode ,
. get_mode = tps65910_get_mode ,
. get_voltage = tps65910_get_voltage_vdd3 ,
2012-06-21 14:48:00 +04:00
. list_voltage = regulator_list_voltage_table ,
2013-04-20 06:30:17 +04:00
. map_voltage = regulator_map_voltage_ascend ,
2011-05-03 01:20:08 +04:00
} ;
2020-08-30 01:11:04 +03:00
static const struct regulator_ops tps65910_ops_vbb = {
2013-12-20 15:43:27 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. set_mode = tps65910_set_mode ,
. get_mode = tps65910_get_mode ,
. get_voltage_sel = tps65910_get_voltage_sel ,
. set_voltage_sel = tps65910_set_voltage_sel ,
. list_voltage = regulator_list_voltage_table ,
. map_voltage = regulator_map_voltage_iterate ,
} ;
2020-08-30 01:11:04 +03:00
static const struct regulator_ops tps65910_ops = {
2012-04-17 10:34:46 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
2011-05-03 01:20:08 +04:00
. set_mode = tps65910_set_mode ,
. get_mode = tps65910_get_mode ,
2012-05-09 05:22:47 +04:00
. get_voltage_sel = tps65910_get_voltage_sel ,
2012-03-09 06:22:20 +04:00
. set_voltage_sel = tps65910_set_voltage_sel ,
2012-06-21 14:48:00 +04:00
. list_voltage = regulator_list_voltage_table ,
2013-04-20 06:30:17 +04:00
. map_voltage = regulator_map_voltage_ascend ,
2011-05-03 01:20:08 +04:00
} ;
2020-08-30 01:11:04 +03:00
static const struct regulator_ops tps65911_ops = {
2012-04-17 10:34:46 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
2011-05-17 03:35:03 +04:00
. set_mode = tps65910_set_mode ,
. get_mode = tps65910_get_mode ,
2012-05-09 05:22:47 +04:00
. get_voltage_sel = tps65911_get_voltage_sel ,
2012-03-09 06:22:20 +04:00
. set_voltage_sel = tps65911_set_voltage_sel ,
2011-05-17 03:35:03 +04:00
. list_voltage = tps65911_list_voltage ,
2013-04-20 06:30:17 +04:00
. map_voltage = regulator_map_voltage_ascend ,
2011-05-17 03:35:03 +04:00
} ;
2012-01-28 13:37:57 +04:00
static int tps65910_set_ext_sleep_config ( struct tps65910_reg * pmic ,
int id , int ext_sleep_config )
{
struct tps65910 * mfd = pmic - > mfd ;
u8 regoffs = ( pmic - > ext_sleep_control [ id ] > > 8 ) & 0xFF ;
u8 bit_pos = ( 1 < < pmic - > ext_sleep_control [ id ] & 0xFF ) ;
int ret ;
/*
* Regulator can not be control from multiple external input EN1 , EN2
* and EN3 together .
*/
if ( ext_sleep_config & EXT_SLEEP_CONTROL ) {
int en_count ;
en_count = ( ( ext_sleep_config &
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 ) ! = 0 ) ;
en_count + = ( ( ext_sleep_config &
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 ) ! = 0 ) ;
en_count + = ( ( ext_sleep_config &
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 ) ! = 0 ) ;
2012-03-07 16:51:49 +04:00
en_count + = ( ( ext_sleep_config &
TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP ) ! = 0 ) ;
2012-01-28 13:37:57 +04:00
if ( en_count > 1 ) {
dev_err ( mfd - > dev ,
" External sleep control flag is not proper \n " ) ;
return - EINVAL ;
}
}
pmic - > board_ext_control [ id ] = ext_sleep_config ;
/* External EN1 control */
if ( ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 )
2020-09-27 02:59:15 +03:00
ret = regmap_set_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_EN1_LDO_ASS + regoffs , bit_pos ) ;
else
2020-09-27 02:59:15 +03:00
ret = regmap_clear_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_EN1_LDO_ASS + regoffs , bit_pos ) ;
if ( ret < 0 ) {
dev_err ( mfd - > dev ,
" Error in configuring external control EN1 \n " ) ;
return ret ;
}
/* External EN2 control */
if ( ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 )
2020-09-27 02:59:15 +03:00
ret = regmap_set_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_EN2_LDO_ASS + regoffs , bit_pos ) ;
else
2020-09-27 02:59:15 +03:00
ret = regmap_clear_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_EN2_LDO_ASS + regoffs , bit_pos ) ;
if ( ret < 0 ) {
dev_err ( mfd - > dev ,
" Error in configuring external control EN2 \n " ) ;
return ret ;
}
/* External EN3 control for TPS65910 LDO only */
if ( ( tps65910_chip_id ( mfd ) = = TPS65910 ) & &
( id > = TPS65910_REG_VDIG1 ) ) {
if ( ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 )
2020-09-27 02:59:15 +03:00
ret = regmap_set_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_EN3_LDO_ASS + regoffs , bit_pos ) ;
else
2020-09-27 02:59:15 +03:00
ret = regmap_clear_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_EN3_LDO_ASS + regoffs , bit_pos ) ;
if ( ret < 0 ) {
dev_err ( mfd - > dev ,
" Error in configuring external control EN3 \n " ) ;
return ret ;
}
}
/* Return if no external control is selected */
if ( ! ( ext_sleep_config & EXT_SLEEP_CONTROL ) ) {
/* Clear all sleep controls */
2020-09-27 02:59:15 +03:00
ret = regmap_clear_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_SLEEP_KEEP_LDO_ON + regoffs , bit_pos ) ;
if ( ! ret )
2020-09-27 02:59:15 +03:00
ret = regmap_clear_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_SLEEP_SET_LDO_OFF + regoffs , bit_pos ) ;
if ( ret < 0 )
dev_err ( mfd - > dev ,
" Error in configuring SLEEP register \n " ) ;
return ret ;
}
/*
* For regulator that has separate operational and sleep register make
* sure that operational is used and clear sleep register to turn
* regulator off when external control is inactive
*/
if ( ( id = = TPS65910_REG_VDD1 ) | |
( id = = TPS65910_REG_VDD2 ) | |
( ( id = = TPS65911_REG_VDDCTRL ) & &
( tps65910_chip_id ( mfd ) = = TPS65911 ) ) ) {
int op_reg_add = pmic - > get_ctrl_reg ( id ) + 1 ;
int sr_reg_add = pmic - > get_ctrl_reg ( id ) + 2 ;
2012-07-11 15:44:13 +04:00
int opvsel , srvsel ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( mfd - > regmap , op_reg_add , & opvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2020-09-27 02:59:15 +03:00
ret = regmap_read ( mfd - > regmap , sr_reg_add , & srvsel ) ;
2012-07-11 15:44:13 +04:00
if ( ret < 0 )
return ret ;
2012-01-28 13:37:57 +04:00
if ( opvsel & VDD1_OP_CMD_MASK ) {
u8 reg_val = srvsel & VDD1_OP_SEL_MASK ;
2012-07-11 15:44:13 +04:00
2020-09-27 02:59:15 +03:00
ret = regmap_write ( mfd - > regmap , op_reg_add , reg_val ) ;
2012-01-28 13:37:57 +04:00
if ( ret < 0 ) {
dev_err ( mfd - > dev ,
" Error in configuring op register \n " ) ;
return ret ;
}
}
2020-09-27 02:59:15 +03:00
ret = regmap_write ( mfd - > regmap , sr_reg_add , 0 ) ;
2012-01-28 13:37:57 +04:00
if ( ret < 0 ) {
2013-09-30 18:19:09 +04:00
dev_err ( mfd - > dev , " Error in setting sr register \n " ) ;
2012-01-28 13:37:57 +04:00
return ret ;
}
}
2020-09-27 02:59:15 +03:00
ret = regmap_clear_bits ( mfd - > regmap ,
2012-01-28 13:37:57 +04:00
TPS65910_SLEEP_KEEP_LDO_ON + regoffs , bit_pos ) ;
2012-03-07 16:51:49 +04:00
if ( ! ret ) {
if ( ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP )
2020-09-27 02:59:15 +03:00
ret = regmap_set_bits ( mfd - > regmap ,
2012-03-07 16:51:49 +04:00
TPS65910_SLEEP_SET_LDO_OFF + regoffs , bit_pos ) ;
else
2020-09-27 02:59:15 +03:00
ret = regmap_clear_bits ( mfd - > regmap ,
2012-03-07 16:51:49 +04:00
TPS65910_SLEEP_SET_LDO_OFF + regoffs , bit_pos ) ;
}
2012-01-28 13:37:57 +04:00
if ( ret < 0 )
dev_err ( mfd - > dev ,
" Error in configuring SLEEP register \n " ) ;
2012-03-07 16:51:49 +04:00
2012-01-28 13:37:57 +04:00
return ret ;
}
2012-05-08 22:42:41 +04:00
# ifdef CONFIG_OF
static struct of_regulator_match tps65910_matches [ ] = {
2012-05-19 18:34:06 +04:00
{ . name = " vrtc " , . driver_data = ( void * ) & tps65910_regs [ 0 ] } ,
{ . name = " vio " , . driver_data = ( void * ) & tps65910_regs [ 1 ] } ,
{ . name = " vdd1 " , . driver_data = ( void * ) & tps65910_regs [ 2 ] } ,
{ . name = " vdd2 " , . driver_data = ( void * ) & tps65910_regs [ 3 ] } ,
{ . name = " vdd3 " , . driver_data = ( void * ) & tps65910_regs [ 4 ] } ,
{ . name = " vdig1 " , . driver_data = ( void * ) & tps65910_regs [ 5 ] } ,
{ . name = " vdig2 " , . driver_data = ( void * ) & tps65910_regs [ 6 ] } ,
{ . name = " vpll " , . driver_data = ( void * ) & tps65910_regs [ 7 ] } ,
{ . name = " vdac " , . driver_data = ( void * ) & tps65910_regs [ 8 ] } ,
{ . name = " vaux1 " , . driver_data = ( void * ) & tps65910_regs [ 9 ] } ,
{ . name = " vaux2 " , . driver_data = ( void * ) & tps65910_regs [ 10 ] } ,
{ . name = " vaux33 " , . driver_data = ( void * ) & tps65910_regs [ 11 ] } ,
{ . name = " vmmc " , . driver_data = ( void * ) & tps65910_regs [ 12 ] } ,
2013-12-20 15:43:27 +04:00
{ . name = " vbb " , . driver_data = ( void * ) & tps65910_regs [ 13 ] } ,
2012-05-08 22:42:41 +04:00
} ;
static struct of_regulator_match tps65911_matches [ ] = {
2012-05-19 18:34:06 +04:00
{ . name = " vrtc " , . driver_data = ( void * ) & tps65911_regs [ 0 ] } ,
{ . name = " vio " , . driver_data = ( void * ) & tps65911_regs [ 1 ] } ,
{ . name = " vdd1 " , . driver_data = ( void * ) & tps65911_regs [ 2 ] } ,
{ . name = " vdd2 " , . driver_data = ( void * ) & tps65911_regs [ 3 ] } ,
{ . name = " vddctrl " , . driver_data = ( void * ) & tps65911_regs [ 4 ] } ,
{ . name = " ldo1 " , . driver_data = ( void * ) & tps65911_regs [ 5 ] } ,
{ . name = " ldo2 " , . driver_data = ( void * ) & tps65911_regs [ 6 ] } ,
{ . name = " ldo3 " , . driver_data = ( void * ) & tps65911_regs [ 7 ] } ,
{ . name = " ldo4 " , . driver_data = ( void * ) & tps65911_regs [ 8 ] } ,
{ . name = " ldo5 " , . driver_data = ( void * ) & tps65911_regs [ 9 ] } ,
{ . name = " ldo6 " , . driver_data = ( void * ) & tps65911_regs [ 10 ] } ,
{ . name = " ldo7 " , . driver_data = ( void * ) & tps65911_regs [ 11 ] } ,
{ . name = " ldo8 " , . driver_data = ( void * ) & tps65911_regs [ 12 ] } ,
2012-05-08 22:42:41 +04:00
} ;
static struct tps65910_board * tps65910_parse_dt_reg_data (
2012-05-20 20:18:50 +04:00
struct platform_device * pdev ,
struct of_regulator_match * * tps65910_reg_matches )
2012-05-08 22:42:41 +04:00
{
struct tps65910_board * pmic_plat_data ;
struct tps65910 * tps65910 = dev_get_drvdata ( pdev - > dev . parent ) ;
2013-01-27 17:16:56 +04:00
struct device_node * np , * regulators ;
2012-05-08 22:42:41 +04:00
struct of_regulator_match * matches ;
unsigned int prop ;
int idx = 0 , ret , count ;
pmic_plat_data = devm_kzalloc ( & pdev - > dev , sizeof ( * pmic_plat_data ) ,
GFP_KERNEL ) ;
2014-02-20 12:53:18 +04:00
if ( ! pmic_plat_data )
2012-05-08 22:42:41 +04:00
return NULL ;
2014-09-10 07:50:39 +04:00
np = pdev - > dev . parent - > of_node ;
2013-10-08 18:01:04 +04:00
regulators = of_get_child_by_name ( np , " regulators " ) ;
2012-05-20 20:18:49 +04:00
if ( ! regulators ) {
dev_err ( & pdev - > dev , " regulator node not found \n " ) ;
return NULL ;
}
2012-05-08 22:42:41 +04:00
switch ( tps65910_chip_id ( tps65910 ) ) {
case TPS65910 :
count = ARRAY_SIZE ( tps65910_matches ) ;
matches = tps65910_matches ;
break ;
case TPS65911 :
count = ARRAY_SIZE ( tps65911_matches ) ;
matches = tps65911_matches ;
break ;
default :
2013-01-27 17:16:56 +04:00
of_node_put ( regulators ) ;
2012-05-20 20:18:48 +04:00
dev_err ( & pdev - > dev , " Invalid tps chip version \n " ) ;
2012-05-08 22:42:41 +04:00
return NULL ;
}
2013-01-24 06:31:45 +04:00
ret = of_regulator_match ( & pdev - > dev , regulators , matches , count ) ;
2013-01-27 17:16:56 +04:00
of_node_put ( regulators ) ;
2012-05-08 22:42:41 +04:00
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " Error parsing regulator init data: %d \n " ,
ret ) ;
return NULL ;
}
2012-05-20 20:18:50 +04:00
* tps65910_reg_matches = matches ;
2012-05-08 22:42:41 +04:00
for ( idx = 0 ; idx < count ; idx + + ) {
2014-02-18 17:11:48 +04:00
if ( ! matches [ idx ] . of_node )
2012-05-08 22:42:41 +04:00
continue ;
pmic_plat_data - > tps65910_pmic_init_data [ idx ] =
matches [ idx ] . init_data ;
ret = of_property_read_u32 ( matches [ idx ] . of_node ,
" ti,regulator-ext-sleep-control " , & prop ) ;
if ( ! ret )
pmic_plat_data - > regulator_ext_sleep_control [ idx ] = prop ;
2012-07-06 12:43:12 +04:00
2012-05-08 22:42:41 +04:00
}
return pmic_plat_data ;
}
# else
static inline struct tps65910_board * tps65910_parse_dt_reg_data (
2012-05-20 20:18:50 +04:00
struct platform_device * pdev ,
struct of_regulator_match * * tps65910_reg_matches )
2012-05-08 22:42:41 +04:00
{
2012-05-20 20:18:50 +04:00
* tps65910_reg_matches = NULL ;
2012-06-15 22:04:33 +04:00
return NULL ;
2012-05-08 22:42:41 +04:00
}
# endif
2012-11-19 22:22:22 +04:00
static int tps65910_probe ( struct platform_device * pdev )
2011-05-03 01:20:08 +04:00
{
struct tps65910 * tps65910 = dev_get_drvdata ( pdev - > dev . parent ) ;
2012-04-04 03:50:22 +04:00
struct regulator_config config = { } ;
2011-05-17 03:35:03 +04:00
struct tps_info * info ;
2011-05-03 01:20:08 +04:00
struct regulator_dev * rdev ;
struct tps65910_reg * pmic ;
struct tps65910_board * pmic_plat_data ;
2012-05-20 20:18:50 +04:00
struct of_regulator_match * tps65910_reg_matches = NULL ;
2011-05-03 01:20:08 +04:00
int i , err ;
pmic_plat_data = dev_get_platdata ( tps65910 - > dev ) ;
2012-05-08 22:42:41 +04:00
if ( ! pmic_plat_data & & tps65910 - > dev - > of_node )
2012-05-20 20:18:50 +04:00
pmic_plat_data = tps65910_parse_dt_reg_data ( pdev ,
& tps65910_reg_matches ) ;
2012-05-08 22:42:41 +04:00
2012-05-20 20:18:48 +04:00
if ( ! pmic_plat_data ) {
dev_err ( & pdev - > dev , " Platform data not found \n " ) ;
2011-05-03 01:20:08 +04:00
return - EINVAL ;
2012-05-20 20:18:48 +04:00
}
2011-05-03 01:20:08 +04:00
2012-04-11 10:40:18 +04:00
pmic = devm_kzalloc ( & pdev - > dev , sizeof ( * pmic ) , GFP_KERNEL ) ;
2014-02-20 12:53:18 +04:00
if ( ! pmic )
2011-05-03 01:20:08 +04:00
return - ENOMEM ;
pmic - > mfd = tps65910 ;
platform_set_drvdata ( pdev , pmic ) ;
/* Give control of all register to control port */
2020-09-27 02:59:15 +03:00
err = regmap_set_bits ( pmic - > mfd - > regmap , TPS65910_DEVCTRL ,
2011-05-03 01:20:08 +04:00
DEVCTRL_SR_CTL_I2C_SEL_MASK ) ;
2018-12-21 09:29:19 +03:00
if ( err < 0 )
return err ;
2011-05-03 01:20:08 +04:00
2013-10-14 12:53:40 +04:00
switch ( tps65910_chip_id ( tps65910 ) ) {
2011-05-17 03:35:03 +04:00
case TPS65910 :
2017-06-13 17:41:56 +03:00
BUILD_BUG_ON ( TPS65910_NUM_REGS < ARRAY_SIZE ( tps65910_regs ) ) ;
2011-05-17 03:35:03 +04:00
pmic - > get_ctrl_reg = & tps65910_get_ctrl_register ;
2011-07-11 05:57:43 +04:00
pmic - > num_regulators = ARRAY_SIZE ( tps65910_regs ) ;
2012-01-28 13:37:57 +04:00
pmic - > ext_sleep_control = tps65910_ext_sleep_control ;
2011-05-17 03:35:03 +04:00
info = tps65910_regs ;
2016-09-23 11:52:00 +03:00
/* Work around silicon erratum SWCZ010: output programmed
* voltage level can go higher than expected or crash
* Workaround : use no synchronization of DCDC clocks
*/
2020-09-27 02:59:15 +03:00
regmap_clear_bits ( pmic - > mfd - > regmap , TPS65910_DCDCCTRL ,
2016-09-23 11:52:00 +03:00
DCDCCTRL_DCDCCKSYNC_MASK ) ;
2011-07-10 17:44:09 +04:00
break ;
2011-05-17 03:35:03 +04:00
case TPS65911 :
2017-06-13 17:41:56 +03:00
BUILD_BUG_ON ( TPS65910_NUM_REGS < ARRAY_SIZE ( tps65911_regs ) ) ;
2011-05-17 03:35:03 +04:00
pmic - > get_ctrl_reg = & tps65911_get_ctrl_register ;
2011-07-11 05:57:43 +04:00
pmic - > num_regulators = ARRAY_SIZE ( tps65911_regs ) ;
2012-01-28 13:37:57 +04:00
pmic - > ext_sleep_control = tps65911_ext_sleep_control ;
2011-05-17 03:35:03 +04:00
info = tps65911_regs ;
2011-07-10 17:44:09 +04:00
break ;
2011-05-17 03:35:03 +04:00
default :
2012-05-20 20:18:48 +04:00
dev_err ( & pdev - > dev , " Invalid tps chip version \n " ) ;
2011-05-17 03:35:03 +04:00
return - ENODEV ;
}
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
pmic - > desc = devm_kcalloc ( & pdev - > dev ,
pmic - > num_regulators ,
sizeof ( struct regulator_desc ) ,
GFP_KERNEL ) ;
2014-02-20 12:53:18 +04:00
if ( ! pmic - > desc )
2012-05-19 18:34:09 +04:00
return - ENOMEM ;
2011-07-11 05:57:43 +04:00
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
pmic - > info = devm_kcalloc ( & pdev - > dev ,
pmic - > num_regulators ,
sizeof ( struct tps_info * ) ,
GFP_KERNEL ) ;
2014-02-20 12:53:18 +04:00
if ( ! pmic - > info )
2012-05-19 18:34:09 +04:00
return - ENOMEM ;
2011-07-11 05:57:43 +04:00
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
pmic - > rdev = devm_kcalloc ( & pdev - > dev ,
pmic - > num_regulators ,
sizeof ( struct regulator_dev * ) ,
GFP_KERNEL ) ;
2014-02-20 12:53:18 +04:00
if ( ! pmic - > rdev )
2012-05-19 18:34:09 +04:00
return - ENOMEM ;
2011-07-11 05:57:43 +04:00
2017-06-13 17:41:56 +03:00
for ( i = 0 ; i < pmic - > num_regulators ; i + + , info + + ) {
2011-05-03 01:20:08 +04:00
/* Register the regulators */
pmic - > info [ i ] = info ;
pmic - > desc [ i ] . name = info - > name ;
2012-07-17 10:04:06 +04:00
pmic - > desc [ i ] . supply_name = info - > vin_name ;
2011-05-12 09:47:50 +04:00
pmic - > desc [ i ] . id = i ;
2012-01-20 15:06:22 +04:00
pmic - > desc [ i ] . n_voltages = info - > n_voltages ;
2012-07-04 05:59:17 +04:00
pmic - > desc [ i ] . enable_time = info - > enable_time_us ;
2011-05-03 01:20:08 +04:00
2011-05-17 03:35:03 +04:00
if ( i = = TPS65910_REG_VDD1 | | i = = TPS65910_REG_VDD2 ) {
2011-05-03 01:20:08 +04:00
pmic - > desc [ i ] . ops = & tps65910_ops_dcdc ;
2011-11-08 17:24:10 +04:00
pmic - > desc [ i ] . n_voltages = VDD1_2_NUM_VOLT_FINE *
VDD1_2_NUM_VOLT_COARSE ;
2012-06-20 18:40:10 +04:00
pmic - > desc [ i ] . ramp_delay = 12500 ;
2011-05-17 03:35:03 +04:00
} else if ( i = = TPS65910_REG_VDD3 ) {
2012-06-20 18:40:10 +04:00
if ( tps65910_chip_id ( tps65910 ) = = TPS65910 ) {
2011-05-17 03:35:03 +04:00
pmic - > desc [ i ] . ops = & tps65910_ops_vdd3 ;
2012-06-21 14:48:00 +04:00
pmic - > desc [ i ] . volt_table = info - > voltage_table ;
2012-06-20 18:40:10 +04:00
} else {
2011-05-17 03:35:03 +04:00
pmic - > desc [ i ] . ops = & tps65910_ops_dcdc ;
2012-06-20 18:40:10 +04:00
pmic - > desc [ i ] . ramp_delay = 5000 ;
}
2013-12-20 15:43:27 +04:00
} else if ( i = = TPS65910_REG_VBB & &
tps65910_chip_id ( tps65910 ) = = TPS65910 ) {
pmic - > desc [ i ] . ops = & tps65910_ops_vbb ;
pmic - > desc [ i ] . volt_table = info - > voltage_table ;
2011-05-17 03:35:03 +04:00
} else {
2012-06-21 14:48:00 +04:00
if ( tps65910_chip_id ( tps65910 ) = = TPS65910 ) {
2011-05-17 03:35:03 +04:00
pmic - > desc [ i ] . ops = & tps65910_ops ;
2012-06-21 14:48:00 +04:00
pmic - > desc [ i ] . volt_table = info - > voltage_table ;
} else {
2011-05-17 03:35:03 +04:00
pmic - > desc [ i ] . ops = & tps65911_ops ;
2012-06-21 14:48:00 +04:00
}
2011-05-17 03:35:03 +04:00
}
2011-05-03 01:20:08 +04:00
2012-01-28 13:37:57 +04:00
err = tps65910_set_ext_sleep_config ( pmic , i ,
pmic_plat_data - > regulator_ext_sleep_control [ i ] ) ;
/*
* Failing on regulator for configuring externally control
* is not a serious issue , just throw warning .
*/
if ( err < 0 )
dev_warn ( tps65910 - > dev ,
" Failed to initialise ext control config \n " ) ;
2011-05-03 01:20:08 +04:00
pmic - > desc [ i ] . type = REGULATOR_VOLTAGE ;
pmic - > desc [ i ] . owner = THIS_MODULE ;
2012-04-17 10:34:46 +04:00
pmic - > desc [ i ] . enable_reg = pmic - > get_ctrl_reg ( i ) ;
2013-12-29 13:00:20 +04:00
pmic - > desc [ i ] . enable_mask = TPS65910_SUPPLY_STATE_ENABLED ;
2011-05-03 01:20:08 +04:00
2012-04-04 03:50:22 +04:00
config . dev = tps65910 - > dev ;
2014-02-18 17:11:48 +04:00
config . init_data = pmic_plat_data - > tps65910_pmic_init_data [ i ] ;
2012-04-04 03:50:22 +04:00
config . driver_data = pmic ;
2012-04-17 10:34:46 +04:00
config . regmap = tps65910 - > regmap ;
2012-04-04 03:50:22 +04:00
2012-05-20 20:18:50 +04:00
if ( tps65910_reg_matches )
config . of_node = tps65910_reg_matches [ i ] . of_node ;
2012-05-08 22:42:41 +04:00
2013-09-04 15:47:51 +04:00
rdev = devm_regulator_register ( & pdev - > dev , & pmic - > desc [ i ] ,
& config ) ;
2021-07-05 23:12:11 +03:00
if ( IS_ERR ( rdev ) )
return dev_err_probe ( tps65910 - > dev , PTR_ERR ( rdev ) ,
" failed to register %s regulator \n " ,
pdev - > name ) ;
2011-05-03 01:20:08 +04:00
/* Save regulator for cleanup */
pmic - > rdev [ i ] = rdev ;
}
return 0 ;
}
2012-01-28 13:37:57 +04:00
static void tps65910_shutdown ( struct platform_device * pdev )
{
struct tps65910_reg * pmic = platform_get_drvdata ( pdev ) ;
int i ;
/*
* Before bootloader jumps to kernel , it makes sure that required
* external control signals are in desired state so that given rails
* can be configure accordingly .
* If rails are configured to be controlled from external control
* then before shutting down / rebooting the system , the external
* control configuration need to be remove from the rails so that
* its output will be available as per register programming even
* if external controls are removed . This is require when the POR
* value of the control signals are not in active state and before
* bootloader initializes it , the system requires the rail output
* to be active for booting .
*/
for ( i = 0 ; i < pmic - > num_regulators ; i + + ) {
int err ;
if ( ! pmic - > rdev [ i ] )
continue ;
err = tps65910_set_ext_sleep_config ( pmic , i , 0 ) ;
if ( err < 0 )
dev_err ( & pdev - > dev ,
" Error in clearing external control \n " ) ;
}
}
2011-05-03 01:20:08 +04:00
static struct platform_driver tps65910_driver = {
. driver = {
. name = " tps65910-pmic " ,
} ,
. probe = tps65910_probe ,
2012-01-28 13:37:57 +04:00
. shutdown = tps65910_shutdown ,
2011-05-03 01:20:08 +04:00
} ;
static int __init tps65910_init ( void )
{
return platform_driver_register ( & tps65910_driver ) ;
}
subsys_initcall ( tps65910_init ) ;
static void __exit tps65910_cleanup ( void )
{
platform_driver_unregister ( & tps65910_driver ) ;
}
module_exit ( tps65910_cleanup ) ;
MODULE_AUTHOR ( " Graeme Gregory <gg@slimlogic.co.uk> " ) ;
2012-02-21 06:14:55 +04:00
MODULE_DESCRIPTION ( " TPS65910/TPS65911 voltage regulator driver " ) ;
2011-05-03 01:20:08 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_ALIAS ( " platform:tps65910-pmic " ) ;