max77779_pmic: Splitting probe from i2c bus

Driver can work from two supported busses i2c/spmi.
Split driver into two steps: one for bus specifics, and one common

Bug: 308476363
Test: pmic sub-modules probed , probe
Change-Id: I705ba4169a49371ca8a621996707f50c72951553
Signed-off-by: Daniel Okazaki <[email protected]>
diff --git a/BUILD.bazel b/BUILD.bazel
index 83900db..0251570 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -41,6 +41,7 @@
         "pca9468.ko",
         "max77779_i2cm.ko",
         "max77779_pmic.ko",
+        "max77779_pmic_i2c.ko",
         "max77779_pmic_irq.ko",
         "max77779_pmic_pinctrl.ko",
         "max77779_pmic_sgpio.ko",
diff --git a/Kconfig b/Kconfig
index 2836beb..b69416c 100644
--- a/Kconfig
+++ b/Kconfig
@@ -163,6 +163,14 @@
 	depends on OF
 	help
 	  Handle IRQs for Sequoia
+choice
+	default MAX77779_PMIC_I2C
+	prompt "MAX77779 PMIC Bus module"
+config MAX77779_PMIC_I2C
+	bool "I2C"
+	depends on I2C
+	select REGMAP_I2C
+endchoice
 
 config MAX77779_PMIC_IRQ
 	tristate "Maxim 77779 PMIC IRQ"
diff --git a/Makefile b/Makefile
index 12787c9..ec215cc 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@
 		MAX20339 \
 		MAX77779_I2CM \
 		MAX77779_PMIC \
+		MAX77779_PMIC_I2C \
 		MAX77779_PMIC_IRQ \
 		MAX77779_PMIC_PINCTRL \
 		MAX77779_PMIC_SGPIO \
@@ -149,6 +150,8 @@
 obj-$(CONFIG_MAX77779_PMIC_PINCTRL) += max77779_pmic_pinctrl.o
 obj-$(CONFIG_MAX77779_PMIC_SGPIO) += max77779_pmic_sgpio.o
 
+obj-$(CONFIG_MAX77779_PMIC_I2C) += max77779_pmic_i2c.o
+
 # LN8411 DC Charge pump
 obj-$(CONFIG_LN8411)	+= ln8411.o
 ln8411-objs += ln8411_driver.o
diff --git a/max77779_pmic.c b/max77779_pmic.c
index 662fcee..3da09cd 100644
--- a/max77779_pmic.c
+++ b/max77779_pmic.c
@@ -6,26 +6,12 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": %s " fmt, __func__
 
-#include <linux/ctype.h>
-#include <linux/i2c.h>
-#include <linux/of.h>
-#include <linux/of_gpio.h>
-#include <linux/of_irq.h>
-#include <linux/gpio.h>
-#include <linux/gpio/driver.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
-#include <linux/interrupt.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/irqchip.h>
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
 # include <linux/debugfs.h>
-# include <linux/seq_file.h>
 #endif
 
 #include "google_bms.h"
@@ -33,16 +19,6 @@
 
 #define MAX77779_PMIC_ID_VAL	0x79
 
-struct max77779_pmic_info {
-	struct device		*dev;
-	struct regmap		*regmap;
-	struct i2c_client	*client;
-#if IS_ENABLED(CONFIG_DEBUG_FS)
-	struct dentry		*de;
-	unsigned int		addr;
-#endif
-};
-
 int max77779_pmic_reg_read(struct device *core_dev,
 		unsigned int reg, unsigned int *val)
 {
@@ -114,8 +90,7 @@
 
 	err = regmap_update_bits(info->regmap, reg, mask, val);
 	if (err)
-		dev_err(core_dev, "error updating %#02x err = %d\n",
-				reg, err);
+		dev_err(core_dev, "error updating %#02x err = %d\n", reg, err);
 	return err;
 }
 EXPORT_SYMBOL_GPL(max77779_pmic_reg_update);
@@ -201,11 +176,9 @@
 	if (!info->de)
 		return -EINVAL;
 
-	debugfs_create_file("addr", 0600, info->de,
-			info, &addr_fops);
+	debugfs_create_file("addr", 0600, info->de, info, &addr_fops);
 
-	debugfs_create_file("data", 0600, info->de,
-			info, &data_fops);
+	debugfs_create_file("data", 0600, info->de, info, &data_fops);
 
 	/* dump all registers */
 	debugfs_create_file("registers", 0444, info->de, info, &debug_all_reg_fops);
@@ -225,7 +198,7 @@
 static inline void dbg_remove_fs(struct max77779_pmic_info *info) {}
 #endif
 
-static bool max77779_pmic_is_readable(struct device *dev, unsigned int reg)
+bool max77779_pmic_is_readable(struct device *dev, unsigned int reg)
 {
 	switch(reg) {
 	case MAX77779_PMIC_ID ... MAX77779_PMIC_OTP_REVISION:
@@ -243,16 +216,7 @@
 		return false;
 	}
 }
-
-static const struct regmap_config max77779_pmic_regmap_cfg = {
-	.name = "max77779_pmic",
-	.reg_bits = 8,
-	.val_bits = 8,
-	.val_format_endian = REGMAP_ENDIAN_NATIVE,
-	.max_register = MAX77779_VGPI_CNFG,
-	.readable_reg = max77779_pmic_is_readable,
-	.volatile_reg = max77779_pmic_is_readable,
-};
+EXPORT_SYMBOL_GPL(max77779_pmic_is_readable);
 
 static const struct mfd_cell max77779_pmic_devs[] = {
 	{
@@ -269,77 +233,41 @@
 	},
 };
 
-static int max77779_pmic_probe(struct i2c_client *client,
-			       const struct i2c_device_id *id)
+/*
+ * Initialization requirements
+ * struct max77779_pmic_info *info
+ * - dev
+ * - regmap
+ */
+int max77779_pmic_init(struct max77779_pmic_info *info)
 {
-	struct device *dev = &client->dev;
-	struct max77779_pmic_info *info;
 	unsigned int pmic_id;
 	int err = 0;
 
-	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	info->dev = dev;
-	i2c_set_clientdata(client, info);
-	info->client = client;
-
-	info->regmap = devm_regmap_init_i2c(client, &max77779_pmic_regmap_cfg);
-	if (IS_ERR(info->regmap)) {
-		dev_err(dev, "Failed to initialize regmap\n");
-		return -EINVAL;
-	}
-
 	err = regmap_read(info->regmap, MAX77779_PMIC_ID, &pmic_id);
 	if (err) {
-		dev_err(dev, "Unable to read Device ID (%d)\n", err);
+		dev_err(info->dev, "Unable to read Device ID (%d)\n", err);
 		return err;
 	} else if (MAX77779_PMIC_ID_VAL != pmic_id) {
-		dev_err(dev, "Unsupported Device ID (%#02x)\n", pmic_id);
+		dev_err(info->dev, "Unsupported Device ID (%#02x)\n", pmic_id);
 		return -ENODEV;
 	}
 
-	mfd_add_devices(dev, PLATFORM_DEVID_AUTO, max77779_pmic_devs,
+	mfd_add_devices(info->dev, PLATFORM_DEVID_AUTO, max77779_pmic_devs,
 			ARRAY_SIZE(max77779_pmic_devs), NULL, 0, NULL);
 
 	dbg_init_fs(info);
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(max77779_pmic_init);
 
-static void max77779_pmic_remove(struct i2c_client *client)
+void max77779_pmic_remove(struct max77779_pmic_info *info)
 {
-	struct max77779_pmic_info *info = i2c_get_clientdata(client);
-
 	dbg_remove_fs(info);
 }
+EXPORT_SYMBOL_GPL(max77779_pmic_remove);
 
-static const struct of_device_id max77779_pmic_of_match_table[] = {
-	{ .compatible = "maxim,max77779_pmic" },
-	{ .compatible = "max77779_pmic" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, max77779_pmic_of_match_table);
-
-static const struct i2c_device_id max77779_pmic_id[] = {
-	{"max77779_pmic", 0},
-	{}
-};
-MODULE_DEVICE_TABLE(i2c, max77779_pmic_id);
-
-static struct i2c_driver max77779_pmic_i2c_driver = {
-	.driver = {
-		.name = "max77779-pmic",
-		.owner = THIS_MODULE,
-		.of_match_table = max77779_pmic_of_match_table,
-	},
-	.id_table = max77779_pmic_id,
-	.probe = max77779_pmic_probe,
-	.remove = max77779_pmic_remove,
-};
-
-module_i2c_driver(max77779_pmic_i2c_driver);
 MODULE_DESCRIPTION("Maxim 77779 PMIC driver");
 MODULE_AUTHOR("James Wylder <[email protected]>");
 MODULE_LICENSE("GPL");
diff --git a/max77779_pmic.h b/max77779_pmic.h
index d334559..610603d 100644
--- a/max77779_pmic.h
+++ b/max77779_pmic.h
@@ -8,8 +8,18 @@
 #define MAX77779_PMIC
 
 #include <linux/device.h>
-#include "max77779_regs.h"
-#include "max777x9_bcl.h"
+
+#include "max77779.h"
+
+struct max77779_pmic_info {
+	struct device		*dev;
+	struct regmap		*regmap;
+	struct i2c_client	*client;
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+	struct dentry		*de;
+	unsigned int		addr;
+#endif
+};
 
 extern int max77779_pmic_reg_read(struct device *core_dev,
 		unsigned int reg, unsigned int *val);
@@ -20,4 +30,7 @@
 extern int max77779_pmic_reg_update(struct device *core_dev,
 		unsigned int reg, unsigned int mask, unsigned int val);
 
+bool max77779_pmic_is_readable(struct device *dev, unsigned int reg);
+int max77779_pmic_init(struct max77779_pmic_info *info);
+void max77779_pmic_remove(struct max77779_pmic_info *info);
 #endif
diff --git a/max77779_pmic_i2c.c b/max77779_pmic_i2c.c
new file mode 100644
index 0000000..84de209
--- /dev/null
+++ b/max77779_pmic_i2c.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2023 Google LLC
+ */
+
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include "max77779_pmic.h"
+
+static const struct regmap_config max77779_pmic_regmap_cfg = {
+	.name = "max77779_pmic",
+	.reg_bits = 8,
+	.val_bits = 8,
+	.val_format_endian = REGMAP_ENDIAN_NATIVE,
+	.max_register = MAX77779_VGPI_CNFG,
+	.readable_reg = max77779_pmic_is_readable,
+	.volatile_reg = max77779_pmic_is_readable,
+};
+
+static const struct i2c_device_id max77779_pmic_id[] = {
+	{"max77779_pmic", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, max77779_pmic_id);
+
+static int max77779_pmic_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct max77779_pmic_info *info;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = dev;
+	info->client = client;
+	i2c_set_clientdata(client, info);
+
+	info->regmap = devm_regmap_init_i2c(client, &max77779_pmic_regmap_cfg);
+	if (IS_ERR(info->regmap)) {
+		dev_err(dev, "Failed to initialize regmap\n");
+		return -EINVAL;
+	}
+
+	return max77779_pmic_init(info);
+}
+
+static void max77779_pmic_i2c_remove(struct i2c_client *client)
+{
+	struct max77779_pmic_info *info = i2c_get_clientdata(client);
+
+	max77779_pmic_remove(info);
+}
+
+static const struct of_device_id max77779_pmic_of_match_table[] = {
+	{ .compatible = "maxim,max77779pmic_i2c" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, max77779_pmic_of_match_table);
+
+static struct i2c_driver max77779_pmic_i2c_driver = {
+	.driver = {
+		.name = "max77779-pmic",
+		.owner = THIS_MODULE,
+		.of_match_table = max77779_pmic_of_match_table,
+	},
+	.id_table = max77779_pmic_id,
+	.probe = max77779_pmic_i2c_probe,
+	.remove = max77779_pmic_i2c_remove,
+};
+
+module_i2c_driver(max77779_pmic_i2c_driver);
+MODULE_DESCRIPTION("Maxim 77779 PMIC I2C Driver");
+MODULE_AUTHOR("Daniel Okazaki <[email protected]>");
+MODULE_LICENSE("GPL");
diff --git a/max777x9_bcl.h b/max777x9_bcl.h
index b9cab5d..4924ffe 100644
--- a/max777x9_bcl.h
+++ b/max777x9_bcl.h
@@ -12,8 +12,4 @@
 int max77759_external_reg_read(struct i2c_client *client, uint8_t reg, uint8_t *val);
 int max77759_external_reg_write(struct i2c_client *client, uint8_t reg, uint8_t val);
 
-
-int max77779_external_pmic_reg_read(struct i2c_client *client, unsigned int reg, unsigned int *val);
-int max77779_external_pmic_reg_write(struct i2c_client *client, unsigned int reg, unsigned int val);
-
 #endif