diff mbox series

[06/18] mfd: adp5585: add support for adp5589

Message ID 20250313-dev-adp5589-fw-v1-6-20e80d4bd4ea@analog.com
State New
Headers show
Series mfd: adp5585: support keymap events and drop legacy Input driver | expand

Commit Message

Nuno Sá via B4 Relay March 13, 2025, 2:19 p.m. UTC
From: Nuno Sá <nuno.sa@analog.com>

The ADP5589 is a 19 I/O port expander with built-in keypad matrix decoder,
programmable logic, reset generator, and PWM generator.

This patch adds the foundation to add support for the adp5589 gpio and pwm
drivers. Most importantly, we need to differentiate between some
registers addresses. It also hints to future keymap support.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
 drivers/mfd/adp5585.c       | 215 ++++++++++++++++++++++++++++++++++++++++++--
 include/linux/mfd/adp5585.h |  57 +++++++++++-
 2 files changed, 264 insertions(+), 8 deletions(-)

Comments

kernel test robot March 14, 2025, 9:12 a.m. UTC | #1
Hi Nuno,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 4d395cb071a343196ca524d3694790f06978fe91]

url:    https://github.com/intel-lab-lkp/linux/commits/Nuno-S-via-B4-Relay/dt-bindings-mfd-adp5585-ease-on-the-required-properties/20250313-222511
base:   4d395cb071a343196ca524d3694790f06978fe91
patch link:    https://lore.kernel.org/r/20250313-dev-adp5589-fw-v1-6-20e80d4bd4ea%40analog.com
patch subject: [PATCH 06/18] mfd: adp5585: add support for adp5589
config: riscv-randconfig-001-20250314 (https://download.01.org/0day-ci/archive/20250314/202503141607.g4arza1A-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250314/202503141607.g4arza1A-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503141607.g4arza1A-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/mfd/adp5585.c:48:41: warning: unused variable 'adp5589_volatile_regs' [-Wunused-const-variable]
      48 | static const struct regmap_access_table adp5589_volatile_regs = {
         |                                         ^~~~~~~~~~~~~~~~~~~~~
>> drivers/mfd/adp5585.c:229:34: warning: unused variable 'adp5585_info' [-Wunused-const-variable]
     229 | static const struct adp5585_info adp5585_info = {
         |                                  ^~~~~~~~~~~~
>> drivers/mfd/adp5585.c:239:34: warning: unused variable 'adp5585_01_info' [-Wunused-const-variable]
     239 | static const struct adp5585_info adp5585_01_info = {
         |                                  ^~~~~~~~~~~~~~~
>> drivers/mfd/adp5585.c:249:34: warning: unused variable 'adp5585_02_info' [-Wunused-const-variable]
     249 | static const struct adp5585_info adp5585_02_info = {
         |                                  ^~~~~~~~~~~~~~~
   4 warnings generated.


vim +/adp5589_volatile_regs +48 drivers/mfd/adp5585.c

    47	
  > 48	static const struct regmap_access_table adp5589_volatile_regs = {
    49		.yes_ranges = adp5589_volatile_ranges,
    50		.n_yes_ranges = ARRAY_SIZE(adp5589_volatile_ranges),
    51	};
    52	
    53	/*
    54	 * Chip variants differ in the default configuration of pull-up and pull-down
    55	 * resistors, and therefore have different default register values:
    56	 *
    57	 * - The -00, -01 and -03 variants (collectively referred to as
    58	 *   ADP5585_REGMAP_00) have pull-up on all GPIO pins by default.
    59	 * - The -02 variant has no default pull-up or pull-down resistors.
    60	 * - The -04 variant has default pull-down resistors on all GPIO pins.
    61	 */
    62	
    63	static const u8 adp5585_regmap_defaults_00[ADP5585_MAX_REG + 1] = {
    64		/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    65		/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    66		/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    67		/* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    68		/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    69		/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    70		/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    71		/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00,
    72	};
    73	
    74	static const u8 adp5585_regmap_defaults_02[ADP5585_MAX_REG + 1] = {
    75		/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    76		/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    77		/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3,
    78		/* 0x18 */ 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
    79		/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    80		/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    81		/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    82		/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00,
    83	};
    84	
    85	static const u8 adp5585_regmap_defaults_04[ADP5585_MAX_REG + 1] = {
    86		/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    87		/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    88		/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
    89		/* 0x18 */ 0x05, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    90		/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    91		/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    92		/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    93		/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00,
    94	};
    95	
    96	static const u8 adp5589_regmap_defaults_00[ADP5589_MAX_REG + 1] = {
    97		/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    98		/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    99		/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   100		/* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   101		/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   102		/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   103		/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   104		/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   105		/* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   106		/* 0x48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   107	};
   108	
   109	static const u8 adp5589_regmap_defaults_01[ADP5589_MAX_REG + 1] = {
   110		/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   111		/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   112		/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   113		/* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   114		/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   115		/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   116		/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   117		/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
   118		/* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   119		/* 0x48 */ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
   120	};
   121	
   122	static const u8 adp5589_regmap_defaults_02[ADP5589_MAX_REG + 1] = {
   123		/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   124		/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   125		/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   126		/* 0x18 */ 0x00, 0x41, 0x01, 0x00, 0x11, 0x04, 0x00, 0x00,
   127		/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   128		/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   129		/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   130		/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   131		/* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   132		/* 0x48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   133	};
   134	
   135	enum adp5585_regmap_type {
   136		ADP5585_REGMAP_00,
   137		ADP5585_REGMAP_02,
   138		ADP5585_REGMAP_04,
   139		ADP5589_REGMAP_00,
   140		ADP5589_REGMAP_01,
   141		ADP5589_REGMAP_02,
   142	};
   143	
   144	static const struct regmap_config adp5585_regmap_configs[] = {
   145		[ADP5585_REGMAP_00] = {
   146			.reg_bits = 8,
   147			.val_bits = 8,
   148			.max_register = ADP5585_MAX_REG,
   149			.volatile_table = &adp5585_volatile_regs,
   150			.cache_type = REGCACHE_MAPLE,
   151			.reg_defaults_raw = adp5585_regmap_defaults_00,
   152			.num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_00),
   153		},
   154		[ADP5585_REGMAP_02] = {
   155			.reg_bits = 8,
   156			.val_bits = 8,
   157			.max_register = ADP5585_MAX_REG,
   158			.volatile_table = &adp5585_volatile_regs,
   159			.cache_type = REGCACHE_MAPLE,
   160			.reg_defaults_raw = adp5585_regmap_defaults_02,
   161			.num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_02),
   162		},
   163		[ADP5585_REGMAP_04] = {
   164			.reg_bits = 8,
   165			.val_bits = 8,
   166			.max_register = ADP5585_MAX_REG,
   167			.volatile_table = &adp5585_volatile_regs,
   168			.cache_type = REGCACHE_MAPLE,
   169			.reg_defaults_raw = adp5585_regmap_defaults_04,
   170			.num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_04),
   171		},
   172		[ADP5589_REGMAP_00] = {
   173			.reg_bits = 8,
   174			.val_bits = 8,
   175			.max_register = ADP5589_MAX_REG,
   176			.volatile_table = &adp5585_volatile_regs,
   177			.cache_type = REGCACHE_MAPLE,
   178			.reg_defaults_raw = adp5589_regmap_defaults_00,
   179			.num_reg_defaults_raw = sizeof(adp5589_regmap_defaults_00),
   180		},
   181		[ADP5589_REGMAP_01] = {
   182			.reg_bits = 8,
   183			.val_bits = 8,
   184			.max_register = ADP5589_MAX_REG,
   185			.volatile_table = &adp5585_volatile_regs,
   186			.cache_type = REGCACHE_MAPLE,
   187			.reg_defaults_raw = adp5589_regmap_defaults_01,
   188			.num_reg_defaults_raw = sizeof(adp5589_regmap_defaults_01),
   189		},
   190		[ADP5589_REGMAP_02] = {
   191			.reg_bits = 8,
   192			.val_bits = 8,
   193			.max_register = ADP5589_MAX_REG,
   194			.volatile_table = &adp5585_volatile_regs,
   195			.cache_type = REGCACHE_MAPLE,
   196			.reg_defaults_raw = adp5589_regmap_defaults_02,
   197			.num_reg_defaults_raw = sizeof(adp5589_regmap_defaults_02),
   198		},
   199	};
   200	
   201	static const struct adp5585_regs adp5585_regs = {
   202		.debounce_dis_a = ADP5585_DEBOUNCE_DIS_A,
   203		.rpull_cfg_a = ADP5585_RPULL_CONFIG_A,
   204		.gpo_data_a = ADP5585_GPO_DATA_OUT_A,
   205		.gpo_out_a = ADP5585_GPO_OUT_MODE_A,
   206		.gpio_dir_a = ADP5585_GPIO_DIRECTION_A,
   207		.gpi_stat_a = ADP5585_GPI_STATUS_A,
   208		.pwm_cfg = ADP5585_PWM_CFG,
   209		.pwm_offt_low = ADP5585_PWM_OFFT_LOW,
   210		.pwm_ont_low = ADP5585_PWM_ONT_LOW,
   211		.gen_cfg = ADP5585_GENERAL_CFG,
   212		.ext_cfg = ADP5585_PIN_CONFIG_C,
   213	};
   214	
   215	static const struct adp5585_regs adp5589_regs = {
   216		.debounce_dis_a = ADP5589_DEBOUNCE_DIS_A,
   217		.rpull_cfg_a = ADP5589_RPULL_CONFIG_A,
   218		.gpo_data_a = ADP5589_GPO_DATA_OUT_A,
   219		.gpo_out_a = ADP5589_GPO_OUT_MODE_A,
   220		.gpio_dir_a = ADP5589_GPIO_DIRECTION_A,
   221		.gpi_stat_a = ADP5589_GPI_STATUS_A,
   222		.pwm_cfg = ADP5589_PWM_CFG,
   223		.pwm_offt_low = ADP5589_PWM_OFFT_LOW,
   224		.pwm_ont_low = ADP5589_PWM_ONT_LOW,
   225		.gen_cfg = ADP5589_GENERAL_CFG,
   226		.ext_cfg = ADP5589_PIN_CONFIG_D,
   227	};
   228	
 > 229	static const struct adp5585_info adp5585_info = {
   230		.adp5585_devs = adp5585_devs,
   231		.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_00],
   232		.n_devs = ARRAY_SIZE(adp5585_devs),
   233		.id = ADP5585_MAN_ID_VALUE,
   234		.regs = &adp5585_regs,
   235		.max_rows = ADP5585_MAX_ROW_NUM,
   236		.max_cols = ADP5585_MAX_COL_NUM,
   237	};
   238	
 > 239	static const struct adp5585_info adp5585_01_info = {
   240		.adp5585_devs = adp5585_devs,
   241		.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_00],
   242		.n_devs = ARRAY_SIZE(adp5585_devs),
   243		.id = ADP5585_MAN_ID_VALUE,
   244		.regs = &adp5585_regs,
   245		.max_rows = ADP5585_MAX_ROW_NUM,
   246		.max_cols = ADP5585_MAX_COL_NUM,
   247	};
   248
kernel test robot March 14, 2025, 9:23 a.m. UTC | #2
Hi Nuno,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 4d395cb071a343196ca524d3694790f06978fe91]

url:    https://github.com/intel-lab-lkp/linux/commits/Nuno-S-via-B4-Relay/dt-bindings-mfd-adp5585-ease-on-the-required-properties/20250313-222511
base:   4d395cb071a343196ca524d3694790f06978fe91
patch link:    https://lore.kernel.org/r/20250313-dev-adp5589-fw-v1-6-20e80d4bd4ea%40analog.com
patch subject: [PATCH 06/18] mfd: adp5585: add support for adp5589
config: s390-randconfig-001-20250314 (https://download.01.org/0day-ci/archive/20250314/202503141715.1e4xyKyq-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250314/202503141715.1e4xyKyq-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503141715.1e4xyKyq-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/mfd/adp5585.c:249:34: warning: 'adp5585_02_info' defined but not used [-Wunused-const-variable=]
     249 | static const struct adp5585_info adp5585_02_info = {
         |                                  ^~~~~~~~~~~~~~~
>> drivers/mfd/adp5585.c:239:34: warning: 'adp5585_01_info' defined but not used [-Wunused-const-variable=]
     239 | static const struct adp5585_info adp5585_01_info = {
         |                                  ^~~~~~~~~~~~~~~
>> drivers/mfd/adp5585.c:229:34: warning: 'adp5585_info' defined but not used [-Wunused-const-variable=]
     229 | static const struct adp5585_info adp5585_info = {
         |                                  ^~~~~~~~~~~~
>> drivers/mfd/adp5585.c:48:41: warning: 'adp5589_volatile_regs' defined but not used [-Wunused-const-variable=]
      48 | static const struct regmap_access_table adp5589_volatile_regs = {
         |                                         ^~~~~~~~~~~~~~~~~~~~~


vim +/adp5585_02_info +249 drivers/mfd/adp5585.c

   228	
 > 229	static const struct adp5585_info adp5585_info = {
   230		.adp5585_devs = adp5585_devs,
   231		.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_00],
   232		.n_devs = ARRAY_SIZE(adp5585_devs),
   233		.id = ADP5585_MAN_ID_VALUE,
   234		.regs = &adp5585_regs,
   235		.max_rows = ADP5585_MAX_ROW_NUM,
   236		.max_cols = ADP5585_MAX_COL_NUM,
   237	};
   238	
 > 239	static const struct adp5585_info adp5585_01_info = {
   240		.adp5585_devs = adp5585_devs,
   241		.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_00],
   242		.n_devs = ARRAY_SIZE(adp5585_devs),
   243		.id = ADP5585_MAN_ID_VALUE,
   244		.regs = &adp5585_regs,
   245		.max_rows = ADP5585_MAX_ROW_NUM,
   246		.max_cols = ADP5585_MAX_COL_NUM,
   247	};
   248	
 > 249	static const struct adp5585_info adp5585_02_info = {
   250		.adp5585_devs = adp5585_devs,
   251		.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_02],
   252		.n_devs = ARRAY_SIZE(adp5585_devs),
   253		.id = ADP5585_MAN_ID_VALUE,
   254		.regs = &adp5585_regs,
   255		.max_rows = ADP5585_MAX_ROW_NUM,
   256		.max_cols = ADP5585_MAX_COL_NUM,
   257	};
   258
diff mbox series

Patch

diff --git a/drivers/mfd/adp5585.c b/drivers/mfd/adp5585.c
index fafe3ad93ea196e1eb8e79fecba58f36f12167eb..2fedc1c7cd08a7b3a8c7188d3e7cdfdf3122a214 100644
--- a/drivers/mfd/adp5585.c
+++ b/drivers/mfd/adp5585.c
@@ -25,6 +25,13 @@  static const struct mfd_cell adp5585_devs[] = {
 
 };
 
+static const struct mfd_cell adp5589_devs[] = {
+	MFD_CELL_NAME("adp5589-keys"),
+	MFD_CELL_NAME("adp5589-gpio"),
+	MFD_CELL_NAME("adp5589-pwm"),
+
+};
+
 static const struct regmap_range adp5585_volatile_ranges[] = {
 	regmap_reg_range(ADP5585_ID, ADP5585_GPI_STATUS_B),
 };
@@ -34,6 +41,15 @@  static const struct regmap_access_table adp5585_volatile_regs = {
 	.n_yes_ranges = ARRAY_SIZE(adp5585_volatile_ranges),
 };
 
+static const struct regmap_range adp5589_volatile_ranges[] = {
+	regmap_reg_range(ADP5585_ID, ADP5589_GPI_STATUS_C),
+};
+
+static const struct regmap_access_table adp5589_volatile_regs = {
+	.yes_ranges = adp5589_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(adp5589_volatile_ranges),
+};
+
 /*
  * Chip variants differ in the default configuration of pull-up and pull-down
  * resistors, and therefore have different default register values:
@@ -77,10 +93,52 @@  static const u8 adp5585_regmap_defaults_04[ADP5585_MAX_REG + 1] = {
 	/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+static const u8 adp5589_regmap_defaults_00[ADP5589_MAX_REG + 1] = {
+	/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const u8 adp5589_regmap_defaults_01[ADP5589_MAX_REG + 1] = {
+	/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+	/* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x48 */ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+};
+
+static const u8 adp5589_regmap_defaults_02[ADP5589_MAX_REG + 1] = {
+	/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x18 */ 0x00, 0x41, 0x01, 0x00, 0x11, 0x04, 0x00, 0x00,
+	/* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x38 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* 0x48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 enum adp5585_regmap_type {
 	ADP5585_REGMAP_00,
 	ADP5585_REGMAP_02,
 	ADP5585_REGMAP_04,
+	ADP5589_REGMAP_00,
+	ADP5589_REGMAP_01,
+	ADP5589_REGMAP_02,
 };
 
 static const struct regmap_config adp5585_regmap_configs[] = {
@@ -111,6 +169,131 @@  static const struct regmap_config adp5585_regmap_configs[] = {
 		.reg_defaults_raw = adp5585_regmap_defaults_04,
 		.num_reg_defaults_raw = sizeof(adp5585_regmap_defaults_04),
 	},
+	[ADP5589_REGMAP_00] = {
+		.reg_bits = 8,
+		.val_bits = 8,
+		.max_register = ADP5589_MAX_REG,
+		.volatile_table = &adp5585_volatile_regs,
+		.cache_type = REGCACHE_MAPLE,
+		.reg_defaults_raw = adp5589_regmap_defaults_00,
+		.num_reg_defaults_raw = sizeof(adp5589_regmap_defaults_00),
+	},
+	[ADP5589_REGMAP_01] = {
+		.reg_bits = 8,
+		.val_bits = 8,
+		.max_register = ADP5589_MAX_REG,
+		.volatile_table = &adp5585_volatile_regs,
+		.cache_type = REGCACHE_MAPLE,
+		.reg_defaults_raw = adp5589_regmap_defaults_01,
+		.num_reg_defaults_raw = sizeof(adp5589_regmap_defaults_01),
+	},
+	[ADP5589_REGMAP_02] = {
+		.reg_bits = 8,
+		.val_bits = 8,
+		.max_register = ADP5589_MAX_REG,
+		.volatile_table = &adp5585_volatile_regs,
+		.cache_type = REGCACHE_MAPLE,
+		.reg_defaults_raw = adp5589_regmap_defaults_02,
+		.num_reg_defaults_raw = sizeof(adp5589_regmap_defaults_02),
+	},
+};
+
+static const struct adp5585_regs adp5585_regs = {
+	.debounce_dis_a = ADP5585_DEBOUNCE_DIS_A,
+	.rpull_cfg_a = ADP5585_RPULL_CONFIG_A,
+	.gpo_data_a = ADP5585_GPO_DATA_OUT_A,
+	.gpo_out_a = ADP5585_GPO_OUT_MODE_A,
+	.gpio_dir_a = ADP5585_GPIO_DIRECTION_A,
+	.gpi_stat_a = ADP5585_GPI_STATUS_A,
+	.pwm_cfg = ADP5585_PWM_CFG,
+	.pwm_offt_low = ADP5585_PWM_OFFT_LOW,
+	.pwm_ont_low = ADP5585_PWM_ONT_LOW,
+	.gen_cfg = ADP5585_GENERAL_CFG,
+	.ext_cfg = ADP5585_PIN_CONFIG_C,
+};
+
+static const struct adp5585_regs adp5589_regs = {
+	.debounce_dis_a = ADP5589_DEBOUNCE_DIS_A,
+	.rpull_cfg_a = ADP5589_RPULL_CONFIG_A,
+	.gpo_data_a = ADP5589_GPO_DATA_OUT_A,
+	.gpo_out_a = ADP5589_GPO_OUT_MODE_A,
+	.gpio_dir_a = ADP5589_GPIO_DIRECTION_A,
+	.gpi_stat_a = ADP5589_GPI_STATUS_A,
+	.pwm_cfg = ADP5589_PWM_CFG,
+	.pwm_offt_low = ADP5589_PWM_OFFT_LOW,
+	.pwm_ont_low = ADP5589_PWM_ONT_LOW,
+	.gen_cfg = ADP5589_GENERAL_CFG,
+	.ext_cfg = ADP5589_PIN_CONFIG_D,
+};
+
+static const struct adp5585_info adp5585_info = {
+	.adp5585_devs = adp5585_devs,
+	.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_00],
+	.n_devs = ARRAY_SIZE(adp5585_devs),
+	.id = ADP5585_MAN_ID_VALUE,
+	.regs = &adp5585_regs,
+	.max_rows = ADP5585_MAX_ROW_NUM,
+	.max_cols = ADP5585_MAX_COL_NUM,
+};
+
+static const struct adp5585_info adp5585_01_info = {
+	.adp5585_devs = adp5585_devs,
+	.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_00],
+	.n_devs = ARRAY_SIZE(adp5585_devs),
+	.id = ADP5585_MAN_ID_VALUE,
+	.regs = &adp5585_regs,
+	.max_rows = ADP5585_MAX_ROW_NUM,
+	.max_cols = ADP5585_MAX_COL_NUM,
+};
+
+static const struct adp5585_info adp5585_02_info = {
+	.adp5585_devs = adp5585_devs,
+	.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_02],
+	.n_devs = ARRAY_SIZE(adp5585_devs),
+	.id = ADP5585_MAN_ID_VALUE,
+	.regs = &adp5585_regs,
+	.max_rows = ADP5585_MAX_ROW_NUM,
+	.max_cols = ADP5585_MAX_COL_NUM,
+};
+
+static const struct adp5585_info adp5585_04_info = {
+	.adp5585_devs = adp5585_devs,
+	.regmap_config = &adp5585_regmap_configs[ADP5585_REGMAP_04],
+	.n_devs = ARRAY_SIZE(adp5585_devs),
+	.id = ADP5585_MAN_ID_VALUE,
+	.regs = &adp5585_regs,
+	.max_rows = ADP5585_MAX_ROW_NUM,
+	.max_cols = ADP5585_MAX_COL_NUM,
+};
+
+static const struct adp5585_info adp5589_info = {
+	.adp5585_devs = adp5589_devs,
+	.regmap_config = &adp5585_regmap_configs[ADP5589_REGMAP_00],
+	.n_devs = ARRAY_SIZE(adp5589_devs),
+	.id = ADP5589_MAN_ID_VALUE,
+	.regs = &adp5589_regs,
+	.max_rows = ADP5589_MAX_ROW_NUM,
+	.max_cols = ADP5589_MAX_COL_NUM,
+};
+
+static const struct adp5585_info adp5589_01_info = {
+	.adp5585_devs = adp5589_devs,
+	.regmap_config = &adp5585_regmap_configs[ADP5589_REGMAP_01],
+	.n_devs = ARRAY_SIZE(adp5589_devs),
+	.id = ADP5589_MAN_ID_VALUE,
+	.regs = &adp5589_regs,
+	.max_rows = ADP5589_MAX_ROW_NUM,
+	.max_cols = ADP5589_MAX_COL_NUM,
+};
+
+static const struct adp5585_info adp5589_02_info = {
+	.adp5585_devs = adp5589_devs,
+	.regmap_config = &adp5585_regmap_configs[ADP5589_REGMAP_02],
+	.n_devs = ARRAY_SIZE(adp5589_devs),
+	.id = ADP5589_MAN_ID_VALUE,
+	.regs = &adp5589_regs,
+	.max_rows = ADP5589_MAX_ROW_NUM,
+	.max_cols = ADP5589_MAX_COL_NUM,
 };
 
 static void adp5585_osc_disable(void *data)
@@ -122,7 +305,7 @@  static void adp5585_osc_disable(void *data)
 
 static int adp5585_i2c_probe(struct i2c_client *i2c)
 {
-	const struct regmap_config *regmap_config;
+	const struct adp5585_info *info;
 	struct adp5585_dev *adp5585;
 	unsigned int id;
 	int ret;
@@ -133,8 +316,13 @@  static int adp5585_i2c_probe(struct i2c_client *i2c)
 
 	i2c_set_clientdata(i2c, adp5585);
 
-	regmap_config = i2c_get_match_data(i2c);
-	adp5585->regmap = devm_regmap_init_i2c(i2c, regmap_config);
+	info = i2c_get_match_data(i2c);
+	if (!info)
+		return -ENODEV;
+
+	adp5585->info = info;
+
+	adp5585->regmap = devm_regmap_init_i2c(i2c, info->regmap_config);
 	if (IS_ERR(adp5585->regmap))
 		return dev_err_probe(&i2c->dev, PTR_ERR(adp5585->regmap),
 				     "Failed to initialize register map\n");
@@ -144,7 +332,8 @@  static int adp5585_i2c_probe(struct i2c_client *i2c)
 		return dev_err_probe(&i2c->dev, ret,
 				     "Failed to read device ID\n");
 
-	if ((id & ADP5585_MAN_ID_MASK) != ADP5585_MAN_ID_VALUE)
+	id &= ADP5585_MAN_ID_MASK;
+	if (id != adp5585->info->id)
 		return dev_err_probe(&i2c->dev, -ENODEV,
 				     "Invalid device ID 0x%02x\n", id);
 
@@ -158,8 +347,8 @@  static int adp5585_i2c_probe(struct i2c_client *i2c)
 		return ret;
 
 	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
-				   adp5585_devs, ARRAY_SIZE(adp5585_devs),
-				   NULL, 0, NULL);
+				   adp5585->info->adp5585_devs,
+				   adp5585->info->n_devs, NULL, 0, NULL);
 	if (ret)
 		return dev_err_probe(&i2c->dev, ret,
 				     "Failed to add child devices\n");
@@ -203,7 +392,19 @@  static const struct of_device_id adp5585_of_match[] = {
 		.data = &adp5585_regmap_configs[ADP5585_REGMAP_00],
 	}, {
 		.compatible = "adi,adp5585-04",
-		.data = &adp5585_regmap_configs[ADP5585_REGMAP_04],
+		.data = &adp5585_04_info,
+	}, {
+		.compatible = "adi,adp5589-00",
+		.data = &adp5589_info,
+	}, {
+		.compatible = "adi,adp5589-01",
+		.data = &adp5589_01_info,
+	}, {
+		.compatible = "adi,adp5589-02",
+		.data = &adp5589_02_info,
+	}, {
+		.compatible = "adi,adp5589",
+		.data = &adp5589_info,
 	},
 	{ /* sentinel */ }
 };
diff --git a/include/linux/mfd/adp5585.h b/include/linux/mfd/adp5585.h
index 016033cd68e46757aca86d21dd37025fd354b801..dffe1449de01dacf8fe78cf0e87d1f176d11f620 100644
--- a/include/linux/mfd/adp5585.h
+++ b/include/linux/mfd/adp5585.h
@@ -104,9 +104,11 @@ 
 #define		ADP5585_INT_CFG			BIT(1)
 #define		ADP5585_RST_CFG			BIT(0)
 #define ADP5585_INT_EN			0x3c
-
 #define ADP5585_MAX_REG			ADP5585_INT_EN
 
+#define ADP5585_MAX_ROW_NUM		6
+#define ADP5585_MAX_COL_NUM		5
+
 /*
  * Bank 0 covers pins "GPIO 1/R0" to "GPIO 6/R5", numbered 0 to 5 by the
  * driver, and bank 1 covers pins "GPIO 7/C0" to "GPIO 11/C4", numbered 6 to
@@ -117,10 +119,63 @@ 
 #define ADP5585_BANK(n)			((n) >= 6 ? 1 : 0)
 #define ADP5585_BIT(n)			((n) >= 6 ? BIT((n) - 6) : BIT(n))
 
+/* ADP5589 */
+#define		ADP5589_MAN_ID_VALUE		0x10
+#define ADP5589_GPI_STATUS_A		0x16
+#define ADP5589_GPI_STATUS_C		0x18
+#define ADP5589_RPULL_CONFIG_A		0x19
+#define ADP5589_DEBOUNCE_DIS_A		0x27
+#define ADP5589_GPO_DATA_OUT_A		0x2a
+#define ADP5589_GPO_OUT_MODE_A		0x2d
+#define	ADP5589_GPIO_DIRECTION_A	0x30
+#define ADP5589_PWM_OFFT_LOW		0x3e
+#define ADP5589_PWM_ONT_LOW		0x40
+#define ADP5589_PWM_CFG			0x42
+#define ADP5589_PIN_CONFIG_D		0x4C
+#define ADP5589_GENERAL_CFG		0x4d
+#define ADP5589_INT_EN			0x4e
+#define ADP5589_MAX_REG			ADP5589_INT_EN
+
+#define ADP5589_MAX_ROW_NUM		8
+#define ADP5589_MAX_COL_NUM		11
+
+/*
+ * Bank 0 covers pins "GPIO 1/R0" to "GPIO 8/R7", numbered 0 to 7 by the
+ * driver, bank 1 covers pins "GPIO 9/C0" to "GPIO 16/C7", numbered 8 to
+ * 15 and bank 3 covers pins "GPIO 17/C8" to "GPIO 19/C10", numbered 16 to 18.
+ */
+#define ADP5589_BANK(n)			((n) >> 3)
+#define ADP5589_BIT(n)			BIT((n) & 0x7)
+
+struct adp5585_regs {
+	unsigned int debounce_dis_a;
+	unsigned int rpull_cfg_a;
+	unsigned int gpo_data_a;
+	unsigned int gpo_out_a;
+	unsigned int gpio_dir_a;
+	unsigned int gpi_stat_a;
+	unsigned int pwm_cfg;
+	unsigned int pwm_offt_low;
+	unsigned int pwm_ont_low;
+	unsigned int gen_cfg;
+	unsigned int ext_cfg;
+};
+
+struct adp5585_info {
+	const struct mfd_cell *adp5585_devs;
+	const struct regmap_config *regmap_config;
+	const struct adp5585_regs *regs;
+	unsigned int n_devs;
+	unsigned int id;
+	u8 max_rows;
+	u8 max_cols;
+};
+
 struct regmap;
 
 struct adp5585_dev {
 	struct regmap *regmap;
+	const struct adp5585_info *info;
 };
 
 #endif