linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] mfd: rt5033: Add Richtek RT5033 drivers
@ 2014-11-12 12:07 Beomho Seo
  2014-11-12 12:07 ` [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core Beomho Seo
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Beomho Seo @ 2014-11-12 12:07 UTC (permalink / raw)
  To: linux-kernel, linux-pm, devicetree
  Cc: sameo, lee.jone, lgirdwood, broonie, sre, dbaryshkov, dwmw2,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	cw00.choi, geunsik.lim, inki.dae, sw0312.kim, Beomho Seo

 This patchset adds driver for Richtek rt5033 chip The chip contains
switching charge mode Li-Ion/Li-Polymer battery charger, fuelgauge, regulators.
This patchset provides common support for accessing the device.
This patchset have been tested base on exynos board.

Changes in v3
- Correct sentence errors.
- Add author information the top of each drivers.
- Remove unnecessary pre-initialise, struct member(rt5033->i2c) and blink.
- Change some return check.
- Use bool and of_match_ptr().

Changes in v2:
- Remove volatile_reg callback. Because this driver not in use regmap cache.
- Remove unnecessary subnode of_compatible.
- Add definde for set high impedance mode of charger.
- Remove unnecessary device specific code.
- Fix wrong register name.
- Fix wrong error message.
- Fix return vallue at error case.
- Revise binding documentation.

Beomho Seo (5):
  mfd: rt5033: Add Richtek RT5033 driver core.
  regulator: rt5033: Add RT5033 Regulator device driver
  power: rt5033_battery: Add RT5033 Fuel gauge device driver
  power: rt5033_charger: Add RT5033 charger device driver
  Documentation: Add documentation for rt5033 multifunction device

 Documentation/devicetree/bindings/mfd/rt5033.txt   |  108 +++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 drivers/mfd/Kconfig                                |   12 +
 drivers/mfd/Makefile                               |    1 +
 drivers/mfd/rt5033.c                               |  141 ++++++
 drivers/power/Kconfig                              |   16 +
 drivers/power/Makefile                             |    2 +
 drivers/power/rt5033_battery.c                     |  177 +++++++
 drivers/power/rt5033_charger.c                     |  485 ++++++++++++++++++++
 drivers/regulator/Kconfig                          |    8 +
 drivers/regulator/Makefile                         |    1 +
 drivers/regulator/rt5033-regulator.c               |  123 +++++
 include/linux/mfd/rt5033-private.h                 |  260 +++++++++++
 include/linux/mfd/rt5033.h                         |   62 +++
 14 files changed, 1397 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/rt5033.txt
 create mode 100644 drivers/mfd/rt5033.c
 create mode 100644 drivers/power/rt5033_battery.c
 create mode 100644 drivers/power/rt5033_charger.c
 create mode 100644 drivers/regulator/rt5033-regulator.c
 create mode 100644 include/linux/mfd/rt5033-private.h
 create mode 100644 include/linux/mfd/rt5033.h

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core.
  2014-11-12 12:07 [PATCH v3 0/5] mfd: rt5033: Add Richtek RT5033 drivers Beomho Seo
@ 2014-11-12 12:07 ` Beomho Seo
  2014-11-18 16:25   ` Lee Jones
  2014-11-12 12:07 ` [PATCH v3 2/5] regulator: rt5033: Add RT5033 Regulator device driver Beomho Seo
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Beomho Seo @ 2014-11-12 12:07 UTC (permalink / raw)
  To: linux-kernel, linux-pm, devicetree
  Cc: sameo, lee.jone, lgirdwood, broonie, sre, dbaryshkov, dwmw2,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	cw00.choi, geunsik.lim, inki.dae, sw0312.kim, Beomho Seo

This patch adds a new driver for Richtek RT5033 driver.
RT5033 is a Multifunction device which includes battery charger, fuel gauge,
flash LED current source, LDO and synchronous Buck converter. It is interfaced
to host controller using I2C interface.

Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Lee Jones <lee.jone@linaro.org>
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes in v3
- Correct sentence errors.
- Add author information the top of each drivers.
- Remove unnecessary pre-initialise, struct member(rt5033->i2c) and blink.
- Change some return check.
- Use bool and of_match_ptr().

Changes in v2
- Remove volatile_reg callback. Because this driver not in use regmap cache.
- Revmoe unnecessary subnode of_compatible.
- Add define for set_high impedance mode of charger.
---

 drivers/mfd/Kconfig                |   12 ++
 drivers/mfd/Makefile               |    1 +
 drivers/mfd/rt5033.c               |  141 +++++++++++++++++++
 include/linux/mfd/rt5033-private.h |  260 ++++++++++++++++++++++++++++++++++++
 include/linux/mfd/rt5033.h         |   62 +++++++++
 5 files changed, 476 insertions(+)
 create mode 100644 drivers/mfd/rt5033.c
 create mode 100644 include/linux/mfd/rt5033-private.h
 create mode 100644 include/linux/mfd/rt5033.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 72d3808..55b6551 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -618,6 +618,18 @@ config MFD_RTSX_PCI
 	  types of memory cards, such as Memory Stick, Memory Stick Pro,
 	  Secure Digital and MultiMediaCard.
 
+config MFD_RT5033
+	bool "Richtek RT5033 Power Management IC"
+	depends on I2C=y
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  This driver provides for the Richtek RT5033 Power Management IC,
+	  which includes the I2C driver and the Core APIs. This driver provides
+	  common support for accessing the device. The device supports multiple
+	  sub-devices like charger, fuel gauge, flash LED, current source,
+	  LDO and Buck.
+
 config MFD_RTSX_USB
 	tristate "Realtek USB card reader"
 	depends on USB
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 53467e2..4059c24 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -176,6 +176,7 @@ obj-$(CONFIG_MFD_IPAQ_MICRO)	+= ipaq-micro.o
 obj-$(CONFIG_MFD_MENF21BMC)	+= menf21bmc.o
 obj-$(CONFIG_MFD_HI6421_PMIC)	+= hi6421-pmic-core.o
 obj-$(CONFIG_MFD_DLN2)		+= dln2.o
+obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
 
 intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c
new file mode 100644
index 0000000..e29c6d9
--- /dev/null
+++ b/drivers/mfd/rt5033.c
@@ -0,0 +1,141 @@
+/*
+ * MFD core driver for the Richtek RT5033.
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/of_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rt5033.h>
+#include <linux/mfd/rt5033-private.h>
+
+static const struct regmap_irq rt5033_irqs[] = {
+	{ .mask = RT5033_PMIC_IRQ_BUCKOCP, },
+	{ .mask = RT5033_PMIC_IRQ_BUCKLV, },
+	{ .mask = RT5033_PMIC_IRQ_SAFELDOLV, },
+	{ .mask = RT5033_PMIC_IRQ_LDOLV, },
+	{ .mask = RT5033_PMIC_IRQ_OT, },
+	{ .mask = RT5033_PMIC_IRQ_VDDA_UV, },
+};
+
+static const struct regmap_irq_chip rt5033_irq_chip = {
+	.name		= "rt5033",
+	.status_base	= RT5033_REG_PMIC_IRQ_STAT,
+	.mask_base	= RT5033_REG_PMIC_IRQ_CTRL,
+	.mask_invert	= true,
+	.num_regs	= 1,
+	.irqs		= rt5033_irqs,
+	.num_irqs	= ARRAY_SIZE(rt5033_irqs),
+};
+
+static const struct mfd_cell rt5033_devs[] = {
+	{
+		.name = "rt5033-regulator",
+	}, {
+		.name = "rt5033-charger",
+		.of_compatible = "richtek,rt5033-charger",
+	}, {
+		.name = "rt5033-battery",
+		.of_compatible = "richtek,rt5033-battery",
+	},
+};
+
+static const struct of_device_id rt5033_dt_match[] = {
+	{ .compatible = "richtek,rt5033", },
+	{ }
+};
+
+static const struct regmap_config rt5033_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.max_register	= RT5033_REG_END,
+};
+
+static int rt5033_i2c_probe(struct i2c_client *i2c,
+				const struct i2c_device_id *id)
+{
+	struct rt5033_dev *rt5033;
+	unsigned int data;
+	int ret;
+
+	rt5033 = devm_kzalloc(&i2c->dev, sizeof(*rt5033), GFP_KERNEL);
+	if (!rt5033)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, rt5033);
+	rt5033->dev = &i2c->dev;
+	rt5033->irq = i2c->irq;
+	rt5033->wakeup = true;
+
+	rt5033->regmap = devm_regmap_init_i2c(i2c, &rt5033_regmap_config);
+	if (IS_ERR(rt5033->regmap)) {
+		dev_err(&i2c->dev, "Failed to allocate register map.\n");
+		return PTR_ERR(rt5033->regmap);
+	}
+
+	ret = regmap_read(rt5033->regmap, RT5033_REG_DEVICE_ID, &data);
+	if (ret) {
+		dev_err(&i2c->dev, "Device not found\n");
+		return -ENODEV;
+	}
+	dev_info(&i2c->dev, "Device found Device ID: %04x\n", data);
+
+	ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
+			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			0, &rt5033_irq_chip, &rt5033->irq_data);
+	if (ret) {
+		dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+							rt5033->irq, ret);
+		return ret;
+	}
+
+	ret = mfd_add_devices(rt5033->dev, -1, rt5033_devs,
+			ARRAY_SIZE(rt5033_devs), NULL, 0,
+			regmap_irq_get_domain(rt5033->irq_data));
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to add RT5033 child device.\n");
+		return ret;
+	}
+
+	device_init_wakeup(rt5033->dev, rt5033->wakeup);
+
+	return 0;
+}
+
+static int rt5033_i2c_remove(struct i2c_client *i2c)
+{
+	struct rt5033_dev *rt5033 = i2c_get_clientdata(i2c);
+
+	mfd_remove_devices(rt5033->dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id rt5033_i2c_id[] = {
+	{ "rt5033", },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, rt5033_i2c_id);
+
+static struct i2c_driver rt5033_driver = {
+	.driver = {
+		.name = "rt5033",
+		.of_match_table = of_match_ptr(rt5033_dt_match),
+	},
+	.probe = rt5033_i2c_probe,
+	.remove = rt5033_i2c_remove,
+	.id_table = rt5033_i2c_id,
+};
+module_i2c_driver(rt5033_driver);
+
+MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver");
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/rt5033-private.h b/include/linux/mfd/rt5033-private.h
new file mode 100644
index 0000000..1b63fc2
--- /dev/null
+++ b/include/linux/mfd/rt5033-private.h
@@ -0,0 +1,260 @@
+/*
+ * MFD core driver for Richtek RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#ifndef __RT5033_PRIVATE_H__
+#define __RT5033_PRIVATE_H__
+
+enum rt5033_reg {
+	RT5033_REG_CHG_STAT		= 0x00,
+	RT5033_REG_CHG_CTRL1		= 0x01,
+	RT5033_REG_CHG_CTRL2		= 0x02,
+	RT5033_REG_DEVICE_ID		= 0x03,
+	RT5033_REG_CHG_CTRL3		= 0x04,
+	RT5033_REG_CHG_CTRL4		= 0x05,
+	RT5033_REG_CHG_CTRL5		= 0x06,
+	RT5033_REG_RT_CTRL0		= 0x07,
+	RT5033_REG_CHG_RESET		= 0x08,
+	/* Reserved 0x09~0x18 */
+	RT5033_REG_RT_CTRL1		= 0x19,
+	/* Reserved 0x1A~0x20 */
+	RT5033_REG_FLED_FUNCTION1	= 0x21,
+	RT5033_REG_FLED_FUNCTION2	= 0x22,
+	RT5033_REG_FLED_STROBE_CTRL1	= 0x23,
+	RT5033_REG_FLED_STROBE_CTRL2	= 0x24,
+	RT5033_REG_FLED_CTRL1		= 0x25,
+	RT5033_REG_FLED_CTRL2		= 0x26,
+	RT5033_REG_FLED_CTRL3		= 0x27,
+	RT5033_REG_FLED_CTRL4		= 0x28,
+	RT5033_REG_FLED_CTRL5		= 0x29,
+	/* Reserved 0x2A~0x40 */
+	RT5033_REG_CTRL			= 0x41,
+	RT5033_REG_BUCK_CTRL		= 0x42,
+	RT5033_REG_LDO_CTRL		= 0x43,
+	/* Reserved 0x44~0x46 */
+	RT5033_REG_MANUAL_RESET_CTRL	= 0x47,
+	/* Reserved 0x48~0x5F */
+	RT5033_REG_CHG_IRQ1		= 0x60,
+	RT5033_REG_CHG_IRQ2		= 0x61,
+	RT5033_REG_CHG_IRQ3		= 0x62,
+	RT5033_REG_CHG_IRQ1_CTRL	= 0x63,
+	RT5033_REG_CHG_IRQ2_CTRL	= 0x64,
+	RT5033_REG_CHG_IRQ3_CTRL	= 0x65,
+	RT5033_REG_LED_IRQ_STAT		= 0x66,
+	RT5033_REG_LED_IRQ_CTRL		= 0x67,
+	RT5033_REG_PMIC_IRQ_STAT	= 0x68,
+	RT5033_REG_PMIC_IRQ_CTRL	= 0x69,
+	RT5033_REG_SHDN_CTRL		= 0x6A,
+	RT5033_REG_OFF_EVENT		= 0x6B,
+
+	RT5033_REG_END,
+};
+
+/* RT5033 Charger state register */
+#define RT5033_CHG_STAT_MASK		0x20
+#define RT5033_CHG_STAT_DISCHARGING	0x00
+#define RT5033_CHG_STAT_FULL		0x10
+#define RT5033_CHG_STAT_CHARGING	0x20
+#define RT5033_CHG_STAT_NOT_CHARGING	0x30
+#define RT5033_CHG_STAT_TYPE_MASK	0x60
+#define RT5033_CHG_STAT_TYPE_PRE	0x20
+#define RT5033_CHG_STAT_TYPE_FAST	0x60
+
+/* RT5033 CHGCTRL1 register */
+#define RT5033_CHGCTRL1_IAICR_MASK	0xe0
+#define RT5033_CHGCTRL1_MODE_MASK	0x01
+
+/* RT5033 CHGCTRL2 register */
+#define RT5033_CHGCTRL2_CV_MASK		0xfc
+
+/* RT5033 CHGCTRL3 register */
+#define RT5033_CHGCTRL3_CFO_EN_MASK	0x40
+#define RT5033_CHGCTRL3_TIMER_MASK	0x38
+#define RT5033_CHGCTRL3_TIMER_EN_MASK	0x01
+
+/* RT5033 CHGCTRL4 register */
+#define RT5033_CHGCTRL4_EOC_MASK	0x07
+#define RT5033_CHGCTRL4_IPREC_MASK	0x18
+
+/* RT5033 CHGCTRL5 register */
+#define RT5033_CHGCTRL5_VPREC_MASK	0x0f
+#define RT5033_CHGCTRL5_ICHG_MASK	0xf0
+#define RT5033_CHGCTRL5_ICHG_SHIFT	0x04
+#define RT5033_CHG_MAX_CURRENT		0x0d
+
+/* RT5033 RT CTRL1 register */
+#define RT5033_RT_CTRL1_UUG_MASK	0x02
+#define RT5033_RT_HZ_MASK		0x01
+
+/* RT5033 control register */
+#define RT5033_CTRL_FCCM_BUCK_MASK		0x00
+#define RT5033_CTRL_BUCKOMS_MASK		0x01
+#define RT5033_CTRL_LDOOMS_MASK			0x02
+#define RT5033_CTRL_SLDOOMS_MASK		0x03
+#define RT5033_CTRL_EN_BUCK_MASK		0x04
+#define RT5033_CTRL_EN_LDO_MASK			0x05
+#define RT5033_CTRL_EN_SAFE_LDO_MASK		0x06
+#define RT5033_CTRL_LDO_SLEEP_MASK		0x07
+
+/* RT5033 BUCK control register */
+#define RT5033_BUCK_CTRL_MASK			0x1f
+
+/* RT5033 LDO control register */
+#define RT5033_LDO_CTRL_MASK			0x1f
+
+/* RT5033 charger property - model, manufacturer */
+
+#define RT5033_CHARGER_MODEL	"RT5033WSC Charger"
+#define RT5033_MANUFACTURER	"Richtek Technology Corporation"
+
+/*
+ * RT5033 charger fast-charge current lmits (as in CHGCTRL1 register),
+ * AICR mode limits the input current for example,
+ * the AIRC 100 mode limits the input current to 100 mA.
+ */
+#define RT5033_AICR_100_MODE			0x20
+#define RT5033_AICR_500_MODE			0x40
+#define RT5033_AICR_700_MODE			0x60
+#define RT5033_AICR_900_MODE			0x80
+#define RT5033_AICR_1500_MODE			0xc0
+#define RT5033_AICR_2000_MODE			0xe0
+#define RT5033_AICR_MODE_MASK			0xe0
+
+/* RT5033 use internal timer need to set time */
+#define RT5033_FAST_CHARGE_TIMER4		0x00
+#define RT5033_FAST_CHARGE_TIMER6		0x01
+#define RT5033_FAST_CHARGE_TIMER8		0x02
+#define RT5033_FAST_CHARGE_TIMER9		0x03
+#define RT5033_FAST_CHARGE_TIMER12		0x04
+#define RT5033_FAST_CHARGE_TIMER14		0x05
+#define RT5033_FAST_CHARGE_TIMER16		0x06
+
+#define RT5033_INT_TIMER_ENABLE			0x01
+
+/* RT5033 charger termination enable mask */
+#define RT5033_TE_ENABLE_MASK			0x08
+
+/*
+ * RT5033 charger opa mode. RT50300 have two opa mode charger mode
+ * and boost mode for OTG
+ */
+
+#define RT5033_CHARGER_MODE			0x00
+#define RT5033_BOOST_MODE			0x01
+
+/* RT5033 charger termination enable */
+#define RT5033_TE_ENABLE			0x08
+
+/* RT5033 charger CFO enable */
+#define RT5033_CFO_ENABLE			0x40
+
+/* RT5033 charger constant charge voltage (as in CHGCTRL2 register), uV */
+#define RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN	3650000U
+#define RT5033_CHARGER_CONST_VOLTAGE_STEP_NUM   25000U
+#define RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX	4400000U
+
+/* RT5033 charger pre-charge current limits (as in CHGCTRL4 register), uA */
+#define RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN	350000U
+#define RT5033_CHARGER_PRE_CURRENT_STEP_NUM	100000U
+#define RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX	650000U
+
+/* RT5033 charger fast-charge current (as in CHGCTRL5 register), uA */
+#define RT5033_CHARGER_FAST_CURRENT_MIN		700000U
+#define RT5033_CHARGER_FAST_CURRENT_STEP_NUM	100000U
+#define RT5033_CHARGER_FAST_CURRENT_MAX		2000000U
+
+/*
+ * RT5033 charger const-charge end of charger current (
+ * as in CHGCTRL4 register), uA
+ */
+#define RT5033_CHARGER_EOC_MIN			150000U
+#define RT5033_CHARGER_EOC_REF			300000U
+#define RT5033_CHARGER_EOC_STEP_NUM1		50000U
+#define RT5033_CHARGER_EOC_STEP_NUM2		100000U
+#define RT5033_CHARGER_EOC_MAX			600000U
+
+/*
+ * RT5033 charger pre-charge threshold volt limits
+ * (as in CHGCTRL5 register), uV
+ */
+
+#define RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN	2300000U
+#define RT5033_CHARGER_PRE_THRESHOLD_STEP_NUM	100000U
+#define RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX	3800000U
+
+/*
+ * RT5033 charger enable UUG, If UUG enable MOS auto control by H/W charger
+ * circuit.
+ */
+#define RT5033_CHARGER_UUG_ENABLE		0x02
+
+/* RT5033 charger High impedance mode */
+#define RT5033_CHARGER_HZ_DISABLE		0x00
+#define RT5033_CHARGER_HZ_ENABLE		0x01
+
+/* RT5033 regulator BUCK output voltage uV */
+#define RT5033_REGULATOR_BUCK_VOLTAGE_MIN		1000000U
+#define RT5033_REGULATOR_BUCK_VOLTAGE_MAX		3000000U
+#define RT5033_REGULATOR_BUCK_VOLTAGE_STEP		100000U
+#define RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM		32
+
+/* RT5033 regulator LDO output voltage uV */
+#define RT5033_REGULATOR_LDO_VOLTAGE_MIN		1200000U
+#define RT5033_REGULATOR_LDO_VOLTAGE_MAX		3000000U
+#define RT5033_REGULATOR_LDO_VOLTAGE_STEP		100000U
+#define RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM		32
+
+/* RT5033 regulator SAFE LDO output voltage uV */
+#define RT5033_REGULATOR_SAFE_LDO_VOLTAGE		4900000U
+
+enum rt5033_fuel_reg {
+	RT5033_FUEL_REG_OCV_H		= 0x00,
+	RT5033_FUEL_REG_OCV_L		= 0x01,
+	RT5033_FUEL_REG_VBAT_H		= 0x02,
+	RT5033_FUEL_REG_VBAT_L		= 0x03,
+	RT5033_FUEL_REG_SOC_H		= 0x04,
+	RT5033_FUEL_REG_SOC_L		= 0x05,
+	RT5033_FUEL_REG_CTRL_H		= 0x06,
+	RT5033_FUEL_REG_CTRL_L		= 0x07,
+	RT5033_FUEL_REG_CRATE		= 0x08,
+	RT5033_FUEL_REG_DEVICE_ID	= 0x09,
+	RT5033_FUEL_REG_AVG_VOLT_H	= 0x0A,
+	RT5033_FUEL_REG_AVG_VOLT_L	= 0x0B,
+	RT5033_FUEL_REG_CONFIG_H	= 0x0C,
+	RT5033_FUEL_REG_CONFIG_L	= 0x0D,
+	/* Reserved 0x0E~0x0F */
+	RT5033_FUEL_REG_IRQ_CTRL	= 0x10,
+	RT5033_FUEL_REG_IRQ_FLAG	= 0x11,
+	RT5033_FUEL_VMIN		= 0x12,
+	RT5033_FUEL_SMIN		= 0x13,
+	/* Reserved 0x14~0x1F */
+	RT5033_FUEL_VGCOMP1		= 0x20,
+	RT5033_FUEL_VGCOMP2		= 0x21,
+	RT5033_FUEL_VGCOMP3		= 0x22,
+	RT5033_FUEL_VGCOMP4		= 0x23,
+	/* Reserved 0x24~0xFD */
+	RT5033_FUEL_MFA_H		= 0xFE,
+	RT5033_FUEL_MFA_L		= 0xFF,
+
+	RT5033_FUEL_REG_END,
+};
+
+/* RT5033 fuel gauge battery present property */
+#define RT5033_FUEL_BAT_PRESENT		0x02
+
+/* RT5033 PMIC interrupts */
+#define RT5033_PMIC_IRQ_BUCKOCP		2
+#define RT5033_PMIC_IRQ_BUCKLV		3
+#define RT5033_PMIC_IRQ_SAFELDOLV	4
+#define RT5033_PMIC_IRQ_LDOLV		5
+#define RT5033_PMIC_IRQ_OT		6
+#define RT5033_PMIC_IRQ_VDDA_UV		7
+
+#endif /* __RT5033_PRIVATE_H__ */
diff --git a/include/linux/mfd/rt5033.h b/include/linux/mfd/rt5033.h
new file mode 100644
index 0000000..bd06415
--- /dev/null
+++ b/include/linux/mfd/rt5033.h
@@ -0,0 +1,62 @@
+/*
+ * MFD core driver for the RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#ifndef __RT5033_H__
+#define __RT5033_H__
+
+#include <linux/regulator/consumer.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/power_supply.h>
+
+/* RT5033 regulator IDs */
+enum rt5033_regulators {
+	RT5033_BUCK = 0,
+	RT5033_LDO,
+	RT5033_SAFE_LDO,
+
+	RT5033_REGULATOR_NUM,
+};
+
+struct rt5033_dev {
+	struct device *dev;
+
+	struct regmap *regmap;
+	struct regmap_irq_chip_data *irq_data;
+	int irq;
+	bool wakeup;
+};
+
+struct rt5033_battery {
+	struct i2c_client	*client;
+	struct rt5033_dev	*rt5033;
+	struct regmap		*regmap;
+	struct power_supply	psy;
+};
+
+/* RT5033 charger platform data */
+struct rt5033_charger_data {
+	unsigned int pre_uamp;
+	unsigned int pre_uvolt;
+	unsigned int const_uvolt;
+	unsigned int eoc_uamp;
+	unsigned int fast_uamp;
+};
+
+struct rt5033_charger {
+	struct device		*dev;
+	struct rt5033_dev	*rt5033;
+	struct power_supply	psy;
+
+	struct rt5033_charger_data	*data;
+};
+
+#endif /* __RT5033_H__ */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/5] regulator: rt5033: Add RT5033 Regulator device driver
  2014-11-12 12:07 [PATCH v3 0/5] mfd: rt5033: Add Richtek RT5033 drivers Beomho Seo
  2014-11-12 12:07 ` [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core Beomho Seo
@ 2014-11-12 12:07 ` Beomho Seo
  2014-11-14 17:55   ` Mark Brown
  2014-11-12 12:08 ` [PATCH v3 3/5] power: rt5033_battery: Add RT5033 Fuel gauge " Beomho Seo
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Beomho Seo @ 2014-11-12 12:07 UTC (permalink / raw)
  To: linux-kernel, linux-pm, devicetree
  Cc: sameo, lee.jone, lgirdwood, broonie, sre, dbaryshkov, dwmw2,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	cw00.choi, geunsik.lim, inki.dae, sw0312.kim, Beomho Seo

This patch add device driver of Richtek RT5033 PMIC.
The driver support multiple regulator like LDO and synchronous Buck.
The integrated synchronous buck converter is designed to provide 0.6 A
application with high efficiency. Two LDOs are integrated. One safe LDO is
for 60mA and the other one LDO is for 150 mA.

Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes in v3:
- Add author information the top of driver.

Changes in v2:
- Remove unnecessary device specific code.
---
 drivers/regulator/Kconfig            |    8 +++
 drivers/regulator/Makefile           |    1 +
 drivers/regulator/rt5033-regulator.c |  123 ++++++++++++++++++++++++++++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 drivers/regulator/rt5033-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 55d7b7b..8558e1b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -521,6 +521,14 @@ config REGULATOR_RN5T618
 	help
 	  Say y here to support the regulators found on Ricoh RN5T618 PMIC.
 
+config REGULATOR_RT5033
+	tristate "Richtek RT5033 Regulators"
+	depends on MFD_RT5033
+	help
+	  This adds support for voltage and current regulators in Richtek
+	  RT5033 PMIC. The device supports multiple regulators like
+	  current source, LDO and Buck.
+
 config REGULATOR_S2MPA01
 	tristate "Samsung S2MPA01 voltage regulator"
 	depends on MFD_SEC_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 1029ed3..1f28ebf 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
+obj-$(CONFIG_REGULATOR_RT5033)	+= rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
diff --git a/drivers/regulator/rt5033-regulator.c b/drivers/regulator/rt5033-regulator.c
new file mode 100644
index 0000000..870cc49
--- /dev/null
+++ b/drivers/regulator/rt5033-regulator.c
@@ -0,0 +1,123 @@
+/*
+ * Regulator driver for the Richtek RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/rt5033.h>
+#include <linux/mfd/rt5033-private.h>
+#include <linux/regulator/of_regulator.h>
+
+static struct regulator_ops rt5033_safe_ldo_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.list_voltage		= regulator_list_voltage_linear,
+};
+
+static struct regulator_ops rt5033_buck_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.list_voltage		= regulator_list_voltage_linear,
+	.map_voltage		= regulator_map_voltage_linear,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+};
+
+static const struct regulator_desc rt5033_supported_regulators[] = {
+	[RT5033_BUCK] = {
+		.name		= "BUCK",
+		.id		= RT5033_BUCK,
+		.ops		= &rt5033_buck_ops,
+		.type		= REGULATOR_VOLTAGE,
+		.owner		= THIS_MODULE,
+		.n_voltages	= RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM,
+		.min_uV		= RT5033_REGULATOR_BUCK_VOLTAGE_MIN,
+		.uV_step	= RT5033_REGULATOR_BUCK_VOLTAGE_STEP,
+		.enable_reg	= RT5033_REG_CTRL,
+		.enable_mask	= RT5033_CTRL_EN_BUCK_MASK,
+		.vsel_reg	= RT5033_REG_BUCK_CTRL,
+		.vsel_mask	= RT5033_BUCK_CTRL_MASK,
+	},
+	[RT5033_LDO] = {
+		.name		= "LDO",
+		.id		= RT5033_LDO,
+		.ops		= &rt5033_buck_ops,
+		.type		= REGULATOR_VOLTAGE,
+		.owner		= THIS_MODULE,
+		.n_voltages	= RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM,
+		.min_uV		= RT5033_REGULATOR_LDO_VOLTAGE_MIN,
+		.uV_step	= RT5033_REGULATOR_LDO_VOLTAGE_STEP,
+		.enable_reg	= RT5033_REG_CTRL,
+		.enable_mask	= RT5033_CTRL_EN_LDO_MASK,
+		.vsel_reg	= RT5033_REG_LDO_CTRL,
+		.vsel_mask	= RT5033_LDO_CTRL_MASK,
+	},
+	[RT5033_SAFE_LDO] = {
+		.name		= "SAFE_LDO",
+		.id		= RT5033_SAFE_LDO,
+		.ops		= &rt5033_safe_ldo_ops,
+		.type		= REGULATOR_VOLTAGE,
+		.owner		= THIS_MODULE,
+		.n_voltages	= 1,
+		.min_uV		= RT5033_REGULATOR_SAFE_LDO_VOLTAGE,
+		.enable_reg	= RT5033_REG_CTRL,
+		.enable_mask	= RT5033_CTRL_EN_SAFE_LDO_MASK,
+	},
+};
+
+static int rt5033_regulator_probe(struct platform_device *pdev)
+{
+	struct rt5033_dev *rt5033 = dev_get_drvdata(pdev->dev.parent);
+	int ret, i;
+	struct regulator_config config = {};
+
+	config.dev = &pdev->dev;
+	config.driver_data = rt5033;
+
+	for (i = 0; i < ARRAY_SIZE(rt5033_supported_regulators); i++) {
+		struct regulator_dev *regulator;
+
+		config.regmap = rt5033->regmap;
+
+		regulator = devm_regulator_register(&pdev->dev,
+				&rt5033_supported_regulators[i], &config);
+		if (IS_ERR(regulator)) {
+			ret = PTR_ERR(regulator);
+			dev_err(&pdev->dev,
+				"Regulator init failed %d: with error: %d\n",
+				i, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct platform_device_id rt5033_regulator_id[] = {
+	{ "rt5033-regulator", },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, rt5033_regulator_id);
+
+static struct platform_driver rt5033_regulator_driver = {
+	.driver = {
+		.name = "rt5033-regulator",
+	},
+	.probe		= rt5033_regulator_probe,
+	.id_table	= rt5033_regulator_id,
+};
+module_platform_driver(rt5033_regulator_driver);
+
+MODULE_DESCRIPTION("Richtek RT5033 Regulator driver");
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/5] power: rt5033_battery: Add RT5033 Fuel gauge device driver
  2014-11-12 12:07 [PATCH v3 0/5] mfd: rt5033: Add Richtek RT5033 drivers Beomho Seo
  2014-11-12 12:07 ` [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core Beomho Seo
  2014-11-12 12:07 ` [PATCH v3 2/5] regulator: rt5033: Add RT5033 Regulator device driver Beomho Seo
@ 2014-11-12 12:08 ` Beomho Seo
  2014-11-12 12:08 ` [PATCH v3 4/5] power: rt5033_charger: Add RT5033 charger " Beomho Seo
  2014-11-12 12:08 ` [PATCH v3 5/5] Documentation: Add documentation for rt5033 multifunction device Beomho Seo
  4 siblings, 0 replies; 9+ messages in thread
From: Beomho Seo @ 2014-11-12 12:08 UTC (permalink / raw)
  To: linux-kernel, linux-pm, devicetree
  Cc: sameo, lee.jone, lgirdwood, broonie, sre, dbaryshkov, dwmw2,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	cw00.choi, geunsik.lim, inki.dae, sw0312.kim, Beomho Seo

This patch adds device driver of Richtek PMIC.
The driver support battery fuel gange. Fuel gauge calculates and determines the
battery state of charge(SOC) according to battery open circuit voltage(OCV).
Also, this driver provides battery average voltage, voltage and bettery present
property.

Cc: Sebastian Reichel <sre@kernel.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes in v3:
- Add author information the top of driver.

Changes in v2:
- Remove volatile_reg callback. Because this driver not in use regmap cache.
- Fix wrong register name.
---
 drivers/power/Kconfig          |    8 ++
 drivers/power/Makefile         |    1 +
 drivers/power/rt5033_battery.c |  177 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 186 insertions(+)
 create mode 100644 drivers/power/rt5033_battery.c

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 0108c2a..da6981f 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -397,6 +397,14 @@ config BATTERY_GOLDFISH
 	  Say Y to enable support for the battery and AC power in the
 	  Goldfish emulator.
 
+config BATTERY_RT5033
+	tristate "RT5033 fuel gauge support"
+	depends on MFD_RT5033
+	help
+	  This adds support for battery fuel gauge in Richtek RT5033 PMIC.
+	  The fuelgauge calculates and determines the battery state of charge
+	  according to battery open circuit voltage.
+
 source "drivers/power/reset/Kconfig"
 
 endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index dfa8942..b83a0c7 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_BATTERY_DA9052)	+= da9052-battery.o
 obj-$(CONFIG_BATTERY_MAX17040)	+= max17040_battery.o
 obj-$(CONFIG_BATTERY_MAX17042)	+= max17042_battery.o
 obj-$(CONFIG_BATTERY_Z2)	+= z2_battery.o
+obj-$(CONFIG_BATTERY_RT5033)	+= rt5033_battery.o
 obj-$(CONFIG_BATTERY_S3C_ADC)	+= s3c_adc_battery.o
 obj-$(CONFIG_BATTERY_TWL4030_MADC)	+= twl4030_madc_battery.o
 obj-$(CONFIG_CHARGER_88PM860X)	+= 88pm860x_charger.o
diff --git a/drivers/power/rt5033_battery.c b/drivers/power/rt5033_battery.c
new file mode 100644
index 0000000..7b898f4
--- /dev/null
+++ b/drivers/power/rt5033_battery.c
@@ -0,0 +1,177 @@
+/*
+ * Fuel gauge driver for Richtek RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/rt5033-private.h>
+#include <linux/mfd/rt5033.h>
+
+static int rt5033_battery_get_capacity(struct i2c_client *client)
+{
+	struct rt5033_battery *battery = i2c_get_clientdata(client);
+	u32 msb;
+
+	regmap_read(battery->regmap, RT5033_FUEL_REG_SOC_H, &msb);
+
+	return msb;
+}
+
+static int rt5033_battery_get_present(struct i2c_client *client)
+{
+	struct rt5033_battery *battery = i2c_get_clientdata(client);
+	u32 val;
+
+	regmap_read(battery->regmap, RT5033_FUEL_REG_CONFIG_L, &val);
+
+	return (val & RT5033_FUEL_BAT_PRESENT) ? true : false;
+}
+
+static int rt5033_battery_get_watt_prop(struct i2c_client *client,
+		enum power_supply_property psp)
+{
+	struct rt5033_battery *battery = i2c_get_clientdata(client);
+	unsigned int regh, regl;
+	int ret;
+	u32 msb, lsb;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		regh = RT5033_FUEL_REG_VBAT_H;
+		regl = RT5033_FUEL_REG_VBAT_L;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+		regh = RT5033_FUEL_REG_AVG_VOLT_H;
+		regl = RT5033_FUEL_REG_AVG_VOLT_L;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_OCV:
+		regh = RT5033_FUEL_REG_OCV_H;
+		regl = RT5033_FUEL_REG_OCV_L;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_read(battery->regmap, regh, &msb);
+	regmap_read(battery->regmap, regl, &lsb);
+
+	ret = ((msb << 4) + (lsb >> 4)) * 1250 / 1000;
+
+	return ret;
+}
+
+static int rt5033_battery_get_property(struct power_supply *psy,
+		enum power_supply_property psp,
+		union power_supply_propval *val)
+{
+	struct rt5033_battery *battery = container_of(psy,
+				struct rt5033_battery, psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+	case POWER_SUPPLY_PROP_VOLTAGE_OCV:
+		val->intval = rt5033_battery_get_watt_prop(battery->client,
+									psp);
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = rt5033_battery_get_present(battery->client);
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = rt5033_battery_get_capacity(battery->client);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static enum power_supply_property rt5033_battery_props[] = {
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_VOLTAGE_AVG,
+	POWER_SUPPLY_PROP_VOLTAGE_OCV,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_CAPACITY,
+};
+
+static struct regmap_config rt5033_battery_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.max_register	= RT5033_FUEL_REG_END,
+};
+
+static int rt5033_battery_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct rt5033_battery *battery;
+	u32 ret;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+		return -EIO;
+
+	battery = devm_kzalloc(&client->dev, sizeof(*battery), GFP_KERNEL);
+	if (!battery)
+		return -EINVAL;
+
+	battery->client = client;
+	battery->regmap = devm_regmap_init_i2c(client,
+			&rt5033_battery_regmap_config);
+	if (IS_ERR(battery->regmap)) {
+		dev_err(&client->dev, "Failed to initialize regmap\n");
+		return -EINVAL;
+	}
+
+	i2c_set_clientdata(client, battery);
+
+	battery->psy.name		= "rt5033-battery";
+	battery->psy.type		= POWER_SUPPLY_TYPE_BATTERY;
+	battery->psy.get_property	= rt5033_battery_get_property;
+	battery->psy.properties		= rt5033_battery_props;
+	battery->psy.num_properties	= ARRAY_SIZE(rt5033_battery_props);
+
+	ret = power_supply_register(&client->dev, &battery->psy);
+	if (ret) {
+		dev_err(&client->dev, "Failed to register power supply\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rt5033_battery_remove(struct i2c_client *client)
+{
+	struct rt5033_battery *battery = i2c_get_clientdata(client);
+
+	power_supply_unregister(&battery->psy);
+
+	return 0;
+}
+
+static const struct i2c_device_id rt5033_battery_id[] = {
+	{ "rt5033-battery", },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, rt5033_battery_id);
+
+static struct i2c_driver rt5033_battery_driver = {
+	.driver = {
+		.name = "rt5033-battery",
+	},
+	.probe = rt5033_battery_probe,
+	.remove = rt5033_battery_remove,
+	.id_table = rt5033_battery_id,
+};
+module_i2c_driver(rt5033_battery_driver);
+
+MODULE_DESCRIPTION("Richtek RT5033 fuel gauge driver");
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 4/5] power: rt5033_charger: Add RT5033 charger device driver
  2014-11-12 12:07 [PATCH v3 0/5] mfd: rt5033: Add Richtek RT5033 drivers Beomho Seo
                   ` (2 preceding siblings ...)
  2014-11-12 12:08 ` [PATCH v3 3/5] power: rt5033_battery: Add RT5033 Fuel gauge " Beomho Seo
@ 2014-11-12 12:08 ` Beomho Seo
  2014-11-12 12:08 ` [PATCH v3 5/5] Documentation: Add documentation for rt5033 multifunction device Beomho Seo
  4 siblings, 0 replies; 9+ messages in thread
From: Beomho Seo @ 2014-11-12 12:08 UTC (permalink / raw)
  To: linux-kernel, linux-pm, devicetree
  Cc: sameo, lee.jone, lgirdwood, broonie, sre, dbaryshkov, dwmw2,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	cw00.choi, geunsik.lim, inki.dae, sw0312.kim, Beomho Seo

This patch add device driver of Richtek RT5033 PMIC. The driver support
switching charger. rt5033 charger provide three charging mode.
Three charging mode are pre charge mode, fast cahrge mode and constant voltage
mode. They are have vary charge rate, charge parameters. The charge parameters
can be controlled by i2c interface.

Cc: Sebastian Reichel <sre@kernel.org>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes in v3:
- Add author information the top of driver.

Changes in v2:
- Fix wrong error message.
- Fix return value at error case. Because  charger->data null, probe function
return zero.
- Use define for set control register.
---
 drivers/power/Kconfig          |    8 +
 drivers/power/Makefile         |    1 +
 drivers/power/rt5033_charger.c |  485 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 494 insertions(+)
 create mode 100644 drivers/power/rt5033_charger.c

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index da6981f..629b101 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -405,6 +405,14 @@ config BATTERY_RT5033
 	  The fuelgauge calculates and determines the battery state of charge
 	  according to battery open circuit voltage.
 
+config CHARGER_RT5033
+	tristate "RT5033 battery charger support"
+	depends on MFD_RT5033
+	help
+	  This adds support for battery charger in Richtek RT5033 PMIC.
+	  The device supports pre-charge mode, fast charge mode and
+	  constant voltage mode.
+
 source "drivers/power/reset/Kconfig"
 
 endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b83a0c7..bb8cce3 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_CHARGER_BQ2415X)	+= bq2415x_charger.o
 obj-$(CONFIG_CHARGER_BQ24190)	+= bq24190_charger.o
 obj-$(CONFIG_CHARGER_BQ24735)	+= bq24735-charger.o
 obj-$(CONFIG_POWER_AVS)		+= avs/
+obj-$(CONFIG_POWER_RT5033)	+= rt5033_charger.o
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
 obj-$(CONFIG_CHARGER_TPS65090)	+= tps65090-charger.o
 obj-$(CONFIG_POWER_RESET)	+= reset/
diff --git a/drivers/power/rt5033_charger.c b/drivers/power/rt5033_charger.c
new file mode 100644
index 0000000..634f2f1
--- /dev/null
+++ b/drivers/power/rt5033_charger.c
@@ -0,0 +1,485 @@
+/*
+ * Battery charger driver for RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/rt5033-private.h>
+#include <linux/mfd/rt5033.h>
+
+static int rt5033_get_charger_state(struct rt5033_charger *charger)
+{
+	struct regmap *regmap = charger->rt5033->regmap;
+	int state = POWER_SUPPLY_STATUS_UNKNOWN;
+	u32 reg_data;
+
+	if (!regmap)
+		return state;
+
+	regmap_read(regmap, RT5033_REG_CHG_STAT, &reg_data);
+
+	switch (reg_data & RT5033_CHG_STAT_MASK) {
+	case RT5033_CHG_STAT_DISCHARGING:
+		state = POWER_SUPPLY_STATUS_DISCHARGING;
+		break;
+	case RT5033_CHG_STAT_CHARGING:
+		state = POWER_SUPPLY_STATUS_CHARGING;
+		break;
+	case RT5033_CHG_STAT_FULL:
+		state = POWER_SUPPLY_STATUS_FULL;
+		break;
+	case RT5033_CHG_STAT_NOT_CHARGING:
+		state = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		break;
+	}
+
+	return state;
+}
+
+static int rt5033_get_charger_type(struct rt5033_charger *charger)
+{
+	struct regmap *regmap = charger->rt5033->regmap;
+	int state = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+	u32 reg_data;
+
+	regmap_read(regmap, RT5033_REG_CHG_STAT, &reg_data);
+
+	switch (reg_data & RT5033_CHG_STAT_TYPE_MASK) {
+	case RT5033_CHG_STAT_TYPE_FAST:
+		state = POWER_SUPPLY_CHARGE_TYPE_FAST;
+		break;
+	case RT5033_CHG_STAT_TYPE_PRE:
+		state = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+		break;
+	}
+
+	return state;
+}
+
+static int rt5033_get_charger_current(struct rt5033_charger *charger,
+		enum power_supply_property psp)
+{
+	struct regmap *regmap = charger->rt5033->regmap;
+	unsigned int state, reg_data, data;
+
+	if (psp == POWER_SUPPLY_PROP_CURRENT_MAX)
+		return RT5033_CHG_MAX_CURRENT;
+
+	regmap_read(regmap, RT5033_REG_CHG_CTRL5, &reg_data);
+
+	state = (reg_data >> RT5033_CHGCTRL5_ICHG_SHIFT) & 0xf;
+
+	if (state > RT5033_CHG_MAX_CURRENT)
+		state = RT5033_CHG_MAX_CURRENT;
+
+	data = state * 100 + 700;
+
+	return data;
+}
+
+static int rt5033_get_charge_voltage(struct rt5033_charger *charger,
+		enum power_supply_property psp)
+{
+	struct regmap *regmap = charger->rt5033->regmap;
+	unsigned int state, reg_data, data;
+
+	if (psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX)
+		return RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX;
+
+	regmap_read(regmap, RT5033_REG_CHG_CTRL2, &reg_data);
+
+	state = reg_data >> 2;
+
+	data = RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN +
+		RT5033_CHARGER_CONST_VOLTAGE_STEP_NUM * state;
+
+	if (data > RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX)
+		data = RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX;
+
+	return data;
+}
+
+static inline int rt5033_init_const_charge(struct rt5033_charger *psy)
+{
+	struct rt5033_charger_data *data = psy->data;
+	unsigned val;
+	int ret;
+	u8 reg_data;
+
+	/* Set Constant voltage mode */
+	if (data->const_uvolt < RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN ||
+		data->const_uvolt > RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX)
+		return -EINVAL;
+
+	if (data->const_uvolt == RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN)
+		reg_data = 0x0;
+	else if (data->const_uvolt == RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX)
+		reg_data = 0xfc;
+	else {
+		val = data->const_uvolt;
+		val -= RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN;
+		val /= RT5033_CHARGER_CONST_VOLTAGE_STEP_NUM;
+		reg_data = val;
+	}
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL2,
+			RT5033_CHGCTRL2_CV_MASK, reg_data << 2);
+	if (ret) {
+		dev_err(psy->dev, "Failed regmap update\n");
+		return -EINVAL;
+	}
+
+	/* Set end of charge current */
+	if (data->eoc_uamp < RT5033_CHARGER_EOC_MIN ||
+		data->eoc_uamp > RT5033_CHARGER_EOC_MAX)
+		return -EINVAL;
+
+	if (data->eoc_uamp == RT5033_CHARGER_EOC_MIN)
+		reg_data = 0x1;
+	else if (data->eoc_uamp == RT5033_CHARGER_EOC_MAX)
+		reg_data = 0x7;
+	else {
+		val = data->eoc_uamp;
+		if (val < RT5033_CHARGER_EOC_REF) {
+			val -= RT5033_CHARGER_EOC_MIN;
+			val /= RT5033_CHARGER_EOC_STEP_NUM1;
+			reg_data = 0x01 + val;
+		} else if (val > RT5033_CHARGER_EOC_REF) {
+			val -= RT5033_CHARGER_EOC_REF;
+			val /= RT5033_CHARGER_EOC_STEP_NUM2;
+			reg_data = 0x04 + val;
+		} else {
+			reg_data = 0x04;
+		}
+	}
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL4,
+			RT5033_CHGCTRL4_EOC_MASK, reg_data);
+	if (ret) {
+		dev_err(psy->dev, "Failed regmap update\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline int rt5033_init_fast_charge(struct rt5033_charger *psy)
+{
+	struct rt5033_charger_data *data = psy->data;
+	int ret;
+	u8 reg_data;
+
+	/* Set limit input current */
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL1,
+			RT5033_AICR_MODE_MASK, RT5033_AICR_2000_MODE);
+	if (ret) {
+		dev_err(psy->dev, "Failed regmap update\n");
+		return -EINVAL;
+	}
+
+	/* Set internal timer */
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL3,
+		RT5033_CHGCTRL3_TIMER_MASK | RT5033_CHGCTRL3_TIMER_EN_MASK,
+		RT5033_FAST_CHARGE_TIMER4 | RT5033_INT_TIMER_ENABLE);
+	if (ret) {
+		dev_err(psy->dev, "Failed regmap update\n");
+		return -EINVAL;
+	}
+
+	/* Set fast-charge mode Carging current */
+	if (data->fast_uamp < RT5033_CHARGER_FAST_CURRENT_MIN ||
+			data->fast_uamp > RT5033_CHARGER_FAST_CURRENT_MAX)
+		return -EINVAL;
+
+	if (data->fast_uamp == RT5033_CHARGER_FAST_CURRENT_MIN)
+		reg_data = 0x0;
+	else if (data->fast_uamp == RT5033_CHARGER_FAST_CURRENT_MAX)
+		reg_data = 0xd0;
+	else {
+		unsigned int val = data->fast_uamp;
+
+		val -= RT5033_CHARGER_FAST_CURRENT_MIN;
+		val /= RT5033_CHARGER_FAST_CURRENT_STEP_NUM;
+		reg_data = 0x10 + val;
+	}
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL5,
+			RT5033_CHGCTRL5_ICHG_MASK, reg_data);
+	if (ret) {
+		dev_err(psy->dev, "Failed regmap update\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline int rt5033_init_pre_charge(struct rt5033_charger *psy)
+{
+	struct rt5033_charger_data *data = psy->data;
+	int ret;
+	u8 reg_data;
+
+	/* Set pre-charge threshold voltage */
+	if (data->pre_uvolt < RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN ||
+		data->pre_uvolt > RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX)
+		return -EINVAL;
+
+	if (data->pre_uvolt == RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN)
+		reg_data = 0x00;
+	else if (data->pre_uvolt == RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX)
+		reg_data = 0x0f;
+	else {
+		unsigned int val = data->pre_uvolt;
+
+		val -= RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN;
+		val /= RT5033_CHARGER_PRE_THRESHOLD_STEP_NUM;
+		reg_data = 0x00 + val;
+	}
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL5,
+			RT5033_CHGCTRL5_VPREC_MASK, reg_data);
+	if (ret) {
+		dev_err(psy->dev, "Failed regmap update\n");
+		return -EINVAL;
+	}
+
+	/* Set pre-charge mode charging current */
+	if (data->pre_uamp < RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN ||
+		data->pre_uamp > RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX)
+		return -EINVAL;
+
+	if (data->pre_uamp == RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN)
+		reg_data = 0x00;
+	else if (data->pre_uamp == RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX)
+		reg_data = 0x18;
+	else {
+		unsigned int val = data->pre_uamp;
+
+		val -= RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN;
+		val /= RT5033_CHARGER_PRE_CURRENT_STEP_NUM;
+		reg_data = 0x08 + val;
+	}
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL4,
+			RT5033_CHGCTRL4_IPREC_MASK, reg_data);
+	if (ret) {
+		dev_err(psy->dev, "Failed regmap update\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rt5033_charger_reg_init(struct rt5033_charger *psy)
+{
+	int ret = 0;
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL1,
+			RT5033_CHGCTRL1_MODE_MASK, RT5033_CHARGER_MODE);
+	if (ret) {
+		dev_err(psy->dev, "Failed to update charger mode.\n");
+		return -EINVAL;
+	}
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_RT_CTRL1,
+			RT5033_RT_CTRL1_UUG_MASK, RT5033_CHARGER_UUG_ENABLE);
+	if (ret) {
+		dev_err(psy->dev, "Failed to update rt ctrl register.\n");
+		return -EINVAL;
+	}
+
+	ret = rt5033_init_pre_charge(psy);
+	if (ret)
+		return ret;
+
+	ret = rt5033_init_fast_charge(psy);
+	if (ret)
+		return ret;
+
+	ret = rt5033_init_const_charge(psy);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL3,
+			RT5033_CHGCTRL3_CFO_EN_MASK, RT5033_CFO_ENABLE);
+	if (ret) {
+		dev_err(psy->dev, "Failed to set enable.\n");
+		return -EINVAL;
+	}
+
+	ret = regmap_update_bits(psy->rt5033->regmap, RT5033_REG_CHG_CTRL1,
+			RT5033_RT_HZ_MASK, RT5033_CHARGER_HZ_DISABLE);
+	if (ret) {
+		dev_err(psy->dev, "Failed to set high impedance mode.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum power_supply_property rt5033_charger_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_CHARGE_TYPE,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
+	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
+	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static int rt5033_charger_get_property(struct power_supply *psy,
+			enum power_supply_property psp,
+			union power_supply_propval *val)
+{
+	struct rt5033_charger *charger = container_of(psy,
+			struct rt5033_charger, psy);
+	int ret = 0;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = rt5033_get_charger_state(charger);
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_TYPE:
+		val->intval = rt5033_get_charger_type(charger);
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		val->intval = rt5033_get_charger_current(charger, psp);
+		break;
+	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
+	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+		val->intval = rt5033_get_charge_voltage(charger, psp);
+		break;
+	case POWER_SUPPLY_PROP_MODEL_NAME:
+		val->strval = RT5033_CHARGER_MODEL;
+		break;
+	case POWER_SUPPLY_PROP_MANUFACTURER:
+		val->strval = RT5033_MANUFACTURER;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static struct rt5033_charger_data *rt5033_charger_dt_init(
+						struct platform_device *pdev)
+{
+	struct rt5033_charger_data *data;
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	if (!np) {
+		dev_err(&pdev->dev, "No charger of_node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return ERR_PTR(-ENOMEM);
+
+	ret = of_property_read_u32(np, "richtek,pre-uamp", &data->pre_uamp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(np, "richtek,pre-threshold-uvolt",
+			&data->pre_uvolt);
+	if (ret)
+		return ERR_PTR(ret);
+
+	/*
+	 * Charging current is decided by external sensing register and
+	 * regulated voltage. In this driver, external sensing regster value
+	 * is 10 mili ohm
+	 */
+	ret = of_property_read_u32(np, "richtek,fast-uamp", &data->fast_uamp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(np, "richtek,const-uvolt",
+			&data->const_uvolt);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = of_property_read_u32(np, "richtek,eoc-uamp", &data->eoc_uamp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return data;
+}
+
+static int rt5033_charger_probe(struct platform_device *pdev)
+{
+	struct rt5033_charger *charger;
+	struct rt5033_dev *rt5033 = dev_get_drvdata(pdev->dev.parent);
+	int ret;
+
+	charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
+	if (!charger)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, charger);
+	charger->dev = &pdev->dev;
+	charger->rt5033 = rt5033;
+
+	charger->data = rt5033_charger_dt_init(pdev);
+	if (IS_ERR_OR_NULL(charger->data))
+		return -ENODEV;
+
+	ret = rt5033_charger_reg_init(charger);
+	if (ret)
+		return ret;
+
+	charger->psy.name = "rt5033-charger",
+	charger->psy.type = POWER_SUPPLY_TYPE_BATTERY,
+	charger->psy.properties = rt5033_charger_props,
+	charger->psy.num_properties = ARRAY_SIZE(rt5033_charger_props),
+	charger->psy.get_property = rt5033_charger_get_property,
+
+	ret = power_supply_register(&pdev->dev, &charger->psy);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register power supply\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rt5033_charger_remove(struct platform_device *pdev)
+{
+	struct rt5033_charger *charger = platform_get_drvdata(pdev);
+
+	power_supply_unregister(&charger->psy);
+
+	return 0;
+}
+
+static const struct platform_device_id rt5033_charger_id[] = {
+	{ "rt5033-charger", },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, rt5033_charger_id);
+
+static struct platform_driver rt5033_charger_driver = {
+	.driver = {
+		.name = "rt5033-charger",
+	},
+	.probe = rt5033_charger_probe,
+	.remove = rt5033_charger_remove,
+	.id_table = rt5033_charger_id,
+};
+module_platform_driver(rt5033_charger_driver);
+
+MODULE_DESCRIPTION("Richtek RT5033 charger driver");
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 5/5] Documentation: Add documentation for rt5033 multifunction device
  2014-11-12 12:07 [PATCH v3 0/5] mfd: rt5033: Add Richtek RT5033 drivers Beomho Seo
                   ` (3 preceding siblings ...)
  2014-11-12 12:08 ` [PATCH v3 4/5] power: rt5033_charger: Add RT5033 charger " Beomho Seo
@ 2014-11-12 12:08 ` Beomho Seo
  4 siblings, 0 replies; 9+ messages in thread
From: Beomho Seo @ 2014-11-12 12:08 UTC (permalink / raw)
  To: linux-kernel, linux-pm, devicetree
  Cc: sameo, lee.jone, lgirdwood, broonie, sre, dbaryshkov, dwmw2,
	robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	cw00.choi, geunsik.lim, inki.dae, sw0312.kim, Beomho Seo

This patch device tree binding documentation for rt5033 multifunction device.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes in v3:
- none.

Changes in v2:
- Revise binding documentation.
---
 Documentation/devicetree/bindings/mfd/rt5033.txt   |  108 ++++++++++++++++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/rt5033.txt

diff --git a/Documentation/devicetree/bindings/mfd/rt5033.txt b/Documentation/devicetree/bindings/mfd/rt5033.txt
new file mode 100644
index 0000000..52a6d33
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/rt5033.txt
@@ -0,0 +1,108 @@
+Richtek RT5033 Power management Integrated Circuit
+
+RT5033 is a Multifunction device which includes battery charger, fuel gauge,
+flash LED current source, LDO and synchronous Buck converter for portable
+applications. It is interfaced to host controller using i2c interface.
+
+Required properties:
+- compatible : Must be "richtek,rt5033"
+- reg : Specifies the i2c slave address of general part.
+- interrupts : This i2c devices has an IRQ line connected to the main SoC.
+- interrupt-parent : The parent interrupt controller.
+
+Optional node:
+Regulators: The regulators of RT5033 have to be instantiated under sub-node
+named "regulators" usinge the following format.
+
+	regulators {
+		regulator-name {
+			regulator-name = LDO/BUCK
+			regulator subnodes called X, Y and Z
+		};
+	};
+	refer Documentation/devicetree/bindings/regulator/regulator.txt
+
+
+Battery charger: There battery charger of RT5033 have to be instantiated under
+sub-node named "charger" using the following format.
+
+Required properties:
+- compatible : Must be "richtek,rt5033-charger".
+- richtek,pre-uamp : Current of pre-charge mode. The pre-charge current levels
+  are 350 mA to 650 mA programmed by I2C per 100 mA.
+- richtek,pre-threshold-uvolt : Voltage of threshold pre-charge mode. Battery
+  voltage is below pre-charge threshold voltage, the charger is in pre-charge
+  mode with pre-charge current. Its levels are 2.3 V  to 3.8 V programmed
+  by I2C per 0.1 V.
+- richtek,fast-uamp : Current of fast-charge mode. The fast-charge current
+  levels are 700 mA to 2000 mA programmed by I2C per 100 mA.
+- richtek,const-uvolt :  Battery regulation voltage of constant voltage mode.
+  This voltage level 3.65 V to 4.4 V bye I2C per 0.025 V.
+- richtek,eoc-uamp : This property is end of charge current. Its level 150 mA
+  to 200 mA.
+
+	charger {
+		compatible = "richtek,rt5033-charger";
+		richtek,pre-uamp = <350000>;
+		richtek,pre-threshold-uvolt = <3400000>;
+		richtek,fast-uamp = <2000000>;
+		richtek,const-uvolt = <4350000>;
+		richtek,eoc-uamp = <250000>;
+	};
+
+
+Fuelgauge: There fuelgauge of RT5033 to be instantiated node named "fuelgauge"
+using the following format.
+
+Required properties:
+- compatible = Must be "richtek,rt5033-battery".
+
+	i2c_fuel: i2c@1 {
+		compatible = "i2c-gpio";
+		standard i2c-gpio constraints...
+		fuelgauge {
+			compatible = "richtek,rt5033-battery".
+		};
+	};
+
+
+Example:
+
+		rt5033@34 {
+			compatible = "richtek,rt5033";
+			reg = <0x34>;
+			interrupt-parent = <&gpx1>;
+			interrupts = <5 0>;
+
+			regulators {
+				buck_reg: BUCK {
+					regulator-name = "BUCK";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-always-on;
+				};
+			};
+
+			charger {
+				compatible = "richtek,rt5033-charger";
+				richtek,pre-uamp = <350000>;
+				richtek,pre-threshold-uvolt = <3400000>;
+				richtek,fast-uamp = <2000000>;
+				richtek,const-uvolt = <4350000>;
+				richtek,eoc-uamp = <250000>;
+			};
+
+		};
+
+		i2c_fuel: i2c@10 {
+			compatible = "i2c-gpio";
+			gpios = <&gpm3 1 0
+				&gpm3 0 0>;
+
+			fuel: rt5033-battery@35 {
+				compatible = "richtek,rt5033-battery";
+				interrupt-parent = <&gpx2>;
+				interrupts = <3 0>;
+				reg = <0x35>;
+			};
+		};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 723999d..611b543 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -124,6 +124,7 @@ ralink	Mediatek/Ralink Technology Corp.
 ramtron	Ramtron International
 realtek Realtek Semiconductor Corp.
 renesas	Renesas Electronics Corporation
+richtek	Richtek Technology Corporation
 ricoh	Ricoh Co. Ltd.
 rockchip	Fuzhou Rockchip Electronics Co., Ltd
 samsung	Samsung Semiconductor
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/5] regulator: rt5033: Add RT5033 Regulator device driver
  2014-11-12 12:07 ` [PATCH v3 2/5] regulator: rt5033: Add RT5033 Regulator device driver Beomho Seo
@ 2014-11-14 17:55   ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2014-11-14 17:55 UTC (permalink / raw)
  To: Beomho Seo
  Cc: linux-kernel, linux-pm, devicetree, sameo, lee.jone, lgirdwood,
	sre, dbaryshkov, dwmw2, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, cw00.choi, geunsik.lim, inki.dae,
	sw0312.kim

[-- Attachment #1: Type: text/plain, Size: 204 bytes --]

On Wed, Nov 12, 2014 at 09:07:59PM +0900, Beomho Seo wrote:
> This patch add device driver of Richtek RT5033 PMIC.
> The driver support multiple regulator like LDO and synchronous Buck.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core.
  2014-11-12 12:07 ` [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core Beomho Seo
@ 2014-11-18 16:25   ` Lee Jones
  2014-11-19  0:39     ` Beomho Seo
  0 siblings, 1 reply; 9+ messages in thread
From: Lee Jones @ 2014-11-18 16:25 UTC (permalink / raw)
  To: Beomho Seo
  Cc: linux-kernel, linux-pm, devicetree, sameo, lee.jone, lgirdwood,
	broonie, sre, dbaryshkov, dwmw2, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, cw00.choi, geunsik.lim,
	inki.dae, sw0312.kim

On Wed, 12 Nov 2014, Beomho Seo wrote:

> This patch adds a new driver for Richtek RT5033 driver.
> RT5033 is a Multifunction device which includes battery charger, fuel gauge,
> flash LED current source, LDO and synchronous Buck converter. It is interfaced
> to host controller using I2C interface.
> 
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jone@linaro.org>
> Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
> Changes in v3
> - Correct sentence errors.
> - Add author information the top of each drivers.
> - Remove unnecessary pre-initialise, struct member(rt5033->i2c) and blink.
> - Change some return check.
> - Use bool and of_match_ptr().
> 
> Changes in v2
> - Remove volatile_reg callback. Because this driver not in use regmap cache.
> - Revmoe unnecessary subnode of_compatible.
> - Add define for set_high impedance mode of charger.
> ---
> 
>  drivers/mfd/Kconfig                |   12 ++
>  drivers/mfd/Makefile               |    1 +
>  drivers/mfd/rt5033.c               |  141 +++++++++++++++++++
>  include/linux/mfd/rt5033-private.h |  260 ++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/rt5033.h         |   62 +++++++++
>  5 files changed, 476 insertions(+)
>  create mode 100644 drivers/mfd/rt5033.c
>  create mode 100644 include/linux/mfd/rt5033-private.h
>  create mode 100644 include/linux/mfd/rt5033.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 72d3808..55b6551 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -618,6 +618,18 @@ config MFD_RTSX_PCI
>  	  types of memory cards, such as Memory Stick, Memory Stick Pro,
>  	  Secure Digital and MultiMediaCard.
>  
> +config MFD_RT5033
> +	bool "Richtek RT5033 Power Management IC"
> +	depends on I2C=y
> +	select MFD_CORE
> +	select REGMAP_I2C
> +	help
> +	  This driver provides for the Richtek RT5033 Power Management IC,
> +	  which includes the I2C driver and the Core APIs. This driver provides
> +	  common support for accessing the device. The device supports multiple
> +	  sub-devices like charger, fuel gauge, flash LED, current source,
> +	  LDO and Buck.

What's stopping this from being built as a module?

>  config MFD_RTSX_USB
>  	tristate "Realtek USB card reader"
>  	depends on USB
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 53467e2..4059c24 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -176,6 +176,7 @@ obj-$(CONFIG_MFD_IPAQ_MICRO)	+= ipaq-micro.o
>  obj-$(CONFIG_MFD_MENF21BMC)	+= menf21bmc.o
>  obj-$(CONFIG_MFD_HI6421_PMIC)	+= hi6421-pmic-core.o
>  obj-$(CONFIG_MFD_DLN2)		+= dln2.o
> +obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
>  
>  intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
>  obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
> diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c
> new file mode 100644
> index 0000000..e29c6d9
> --- /dev/null
> +++ b/drivers/mfd/rt5033.c
> @@ -0,0 +1,141 @@
> +/*
> + * MFD core driver for the Richtek RT5033.
> + *
> + * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
> + * Author: Beomho Seo <beomho.seo@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published bythe Free Software Foundation.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/module.h>

Why have you included this if you can't build as a module?

> +#include <linux/interrupt.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/rt5033.h>
> +#include <linux/mfd/rt5033-private.h>
> +
> +static const struct regmap_irq rt5033_irqs[] = {
> +	{ .mask = RT5033_PMIC_IRQ_BUCKOCP, },
> +	{ .mask = RT5033_PMIC_IRQ_BUCKLV, },
> +	{ .mask = RT5033_PMIC_IRQ_SAFELDOLV, },
> +	{ .mask = RT5033_PMIC_IRQ_LDOLV, },
> +	{ .mask = RT5033_PMIC_IRQ_OT, },
> +	{ .mask = RT5033_PMIC_IRQ_VDDA_UV, },
> +};
> +
> +static const struct regmap_irq_chip rt5033_irq_chip = {
> +	.name		= "rt5033",
> +	.status_base	= RT5033_REG_PMIC_IRQ_STAT,
> +	.mask_base	= RT5033_REG_PMIC_IRQ_CTRL,
> +	.mask_invert	= true,
> +	.num_regs	= 1,
> +	.irqs		= rt5033_irqs,
> +	.num_irqs	= ARRAY_SIZE(rt5033_irqs),
> +};
> +
> +static const struct mfd_cell rt5033_devs[] = {
> +	{
> +		.name = "rt5033-regulator",
> +	}, {

Place this entry on one line.  Like you did in rt5033_irqs.

> +		.name = "rt5033-charger",
> +		.of_compatible = "richtek,rt5033-charger",
> +	}, {
> +		.name = "rt5033-battery",
> +		.of_compatible = "richtek,rt5033-battery",
> +	},
> +};
> +
> +static const struct of_device_id rt5033_dt_match[] = {
> +	{ .compatible = "richtek,rt5033", },
> +	{ }
> +};
> +
> +static const struct regmap_config rt5033_regmap_config = {
> +	.reg_bits	= 8,
> +	.val_bits	= 8,
> +	.max_register	= RT5033_REG_END,
> +};
> +
> +static int rt5033_i2c_probe(struct i2c_client *i2c,
> +				const struct i2c_device_id *id)
> +{
> +	struct rt5033_dev *rt5033;
> +	unsigned int data;
> +	int ret;
> +
> +	rt5033 = devm_kzalloc(&i2c->dev, sizeof(*rt5033), GFP_KERNEL);
> +	if (!rt5033)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(i2c, rt5033);
> +	rt5033->dev = &i2c->dev;
> +	rt5033->irq = i2c->irq;
> +	rt5033->wakeup = true;
> +
> +	rt5033->regmap = devm_regmap_init_i2c(i2c, &rt5033_regmap_config);
> +	if (IS_ERR(rt5033->regmap)) {
> +		dev_err(&i2c->dev, "Failed to allocate register map.\n");
> +		return PTR_ERR(rt5033->regmap);
> +	}
> +
> +	ret = regmap_read(rt5033->regmap, RT5033_REG_DEVICE_ID, &data);
> +	if (ret) {
> +		dev_err(&i2c->dev, "Device not found\n");
> +		return -ENODEV;
> +	}
> +	dev_info(&i2c->dev, "Device found Device ID: %04x\n", data);
> +
> +	ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
> +			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
> +			0, &rt5033_irq_chip, &rt5033->irq_data);
> +	if (ret) {
> +		dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
> +							rt5033->irq, ret);
> +		return ret;
> +	}
> +
> +	ret = mfd_add_devices(rt5033->dev, -1, rt5033_devs,
> +			ARRAY_SIZE(rt5033_devs), NULL, 0,
> +			regmap_irq_get_domain(rt5033->irq_data));
> +	if (ret < 0) {
> +		dev_err(&i2c->dev, "Failed to add RT5033 child device.\n");

s/device/devices/

> +		return ret;
> +	}
> +
> +	device_init_wakeup(rt5033->dev, rt5033->wakeup);
> +
> +	return 0;
> +}
> +
> +static int rt5033_i2c_remove(struct i2c_client *i2c)
> +{
> +	struct rt5033_dev *rt5033 = i2c_get_clientdata(i2c);
> +
> +	mfd_remove_devices(rt5033->dev);
> +
> +	return 0;
> +}
> +
> +static const struct i2c_device_id rt5033_i2c_id[] = {
> +	{ "rt5033", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, rt5033_i2c_id);

Why do you need to export this if you're not building as a module?

> +static struct i2c_driver rt5033_driver = {
> +	.driver = {
> +		.name = "rt5033",
> +		.of_match_table = of_match_ptr(rt5033_dt_match),
> +	},
> +	.probe = rt5033_i2c_probe,
> +	.remove = rt5033_i2c_remove,
> +	.id_table = rt5033_i2c_id,
> +};
> +module_i2c_driver(rt5033_driver);
>
> +MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver");
> +MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
> +MODULE_LICENSE("GPL");

More module stuff?

[...]

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core.
  2014-11-18 16:25   ` Lee Jones
@ 2014-11-19  0:39     ` Beomho Seo
  0 siblings, 0 replies; 9+ messages in thread
From: Beomho Seo @ 2014-11-19  0:39 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-kernel, linux-pm, devicetree, sameo, lee.jone, lgirdwood,
	broonie, sre, dbaryshkov, dwmw2, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, cw00.choi, geunsik.lim,
	inki.dae, sw0312.kim, beomho.seo

Thank you for review.

On 11/19/2014 01:25 AM, Lee Jones wrote:
> On Wed, 12 Nov 2014, Beomho Seo wrote:
> 
>> This patch adds a new driver for Richtek RT5033 driver.
>> RT5033 is a Multifunction device which includes battery charger, fuel gauge,
>> flash LED current source, LDO and synchronous Buck converter. It is interfaced
>> to host controller using I2C interface.
>>
>> Cc: Samuel Ortiz <sameo@linux.intel.com>
>> Cc: Lee Jones <lee.jone@linaro.org>
>> Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
>> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
>> ---
>> Changes in v3
>> - Correct sentence errors.
>> - Add author information the top of each drivers.
>> - Remove unnecessary pre-initialise, struct member(rt5033->i2c) and blink.
>> - Change some return check.
>> - Use bool and of_match_ptr().
>>
>> Changes in v2
>> - Remove volatile_reg callback. Because this driver not in use regmap cache.
>> - Revmoe unnecessary subnode of_compatible.
>> - Add define for set_high impedance mode of charger.
>> ---
>>
>>  drivers/mfd/Kconfig                |   12 ++
>>  drivers/mfd/Makefile               |    1 +
>>  drivers/mfd/rt5033.c               |  141 +++++++++++++++++++
>>  include/linux/mfd/rt5033-private.h |  260 ++++++++++++++++++++++++++++++++++++
>>  include/linux/mfd/rt5033.h         |   62 +++++++++
>>  5 files changed, 476 insertions(+)
>>  create mode 100644 drivers/mfd/rt5033.c
>>  create mode 100644 include/linux/mfd/rt5033-private.h
>>  create mode 100644 include/linux/mfd/rt5033.h
>>
>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>> index 72d3808..55b6551 100644
>> --- a/drivers/mfd/Kconfig
>> +++ b/drivers/mfd/Kconfig
>> @@ -618,6 +618,18 @@ config MFD_RTSX_PCI
>>  	  types of memory cards, such as Memory Stick, Memory Stick Pro,
>>  	  Secure Digital and MultiMediaCard.
>>  
>> +config MFD_RT5033
>> +	bool "Richtek RT5033 Power Management IC"
>> +	depends on I2C=y
>> +	select MFD_CORE
>> +	select REGMAP_I2C
>> +	help
>> +	  This driver provides for the Richtek RT5033 Power Management IC,
>> +	  which includes the I2C driver and the Core APIs. This driver provides
>> +	  common support for accessing the device. The device supports multiple
>> +	  sub-devices like charger, fuel gauge, flash LED, current source,
>> +	  LDO and Buck.
> 
> What's stopping this from being built as a module?
> 

I will change to possible building as a module.

>>  config MFD_RTSX_USB
>>  	tristate "Realtek USB card reader"
>>  	depends on USB
>> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
>> index 53467e2..4059c24 100644
>> --- a/drivers/mfd/Makefile
>> +++ b/drivers/mfd/Makefile
>> @@ -176,6 +176,7 @@ obj-$(CONFIG_MFD_IPAQ_MICRO)	+= ipaq-micro.o
>>  obj-$(CONFIG_MFD_MENF21BMC)	+= menf21bmc.o
>>  obj-$(CONFIG_MFD_HI6421_PMIC)	+= hi6421-pmic-core.o
>>  obj-$(CONFIG_MFD_DLN2)		+= dln2.o
>> +obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
>>  
>>  intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
>>  obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
>> diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c
>> new file mode 100644
>> index 0000000..e29c6d9
>> --- /dev/null
>> +++ b/drivers/mfd/rt5033.c
>> @@ -0,0 +1,141 @@
>> +/*
>> + * MFD core driver for the Richtek RT5033.
>> + *
>> + * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
>> + * Author: Beomho Seo <beomho.seo@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published bythe Free Software Foundation.
>> + */
>> +
>> +#include <linux/err.h>
>> +#include <linux/module.h>
> 
> Why have you included this if you can't build as a module?
> 

I will change that driver can build as a module.

>> +#include <linux/interrupt.h>
>> +#include <linux/of_device.h>
>> +#include <linux/mfd/core.h>
>> +#include <linux/mfd/rt5033.h>
>> +#include <linux/mfd/rt5033-private.h>
>> +
>> +static const struct regmap_irq rt5033_irqs[] = {
>> +	{ .mask = RT5033_PMIC_IRQ_BUCKOCP, },
>> +	{ .mask = RT5033_PMIC_IRQ_BUCKLV, },
>> +	{ .mask = RT5033_PMIC_IRQ_SAFELDOLV, },
>> +	{ .mask = RT5033_PMIC_IRQ_LDOLV, },
>> +	{ .mask = RT5033_PMIC_IRQ_OT, },
>> +	{ .mask = RT5033_PMIC_IRQ_VDDA_UV, },
>> +};
>> +
>> +static const struct regmap_irq_chip rt5033_irq_chip = {
>> +	.name		= "rt5033",
>> +	.status_base	= RT5033_REG_PMIC_IRQ_STAT,
>> +	.mask_base	= RT5033_REG_PMIC_IRQ_CTRL,
>> +	.mask_invert	= true,
>> +	.num_regs	= 1,
>> +	.irqs		= rt5033_irqs,
>> +	.num_irqs	= ARRAY_SIZE(rt5033_irqs),
>> +};
>> +
>> +static const struct mfd_cell rt5033_devs[] = {
>> +	{
>> +		.name = "rt5033-regulator",
>> +	}, {
> 
> Place this entry on one line.  Like you did in rt5033_irqs.
>

OK, I will fix it like rt5033_irqs style.

>> +		.name = "rt5033-charger",
>> +		.of_compatible = "richtek,rt5033-charger",
>> +	}, {
>> +		.name = "rt5033-battery",
>> +		.of_compatible = "richtek,rt5033-battery",
>> +	},
>> +};
>> +
>> +static const struct of_device_id rt5033_dt_match[] = {
>> +	{ .compatible = "richtek,rt5033", },
>> +	{ }
>> +};
>> +
>> +static const struct regmap_config rt5033_regmap_config = {
>> +	.reg_bits	= 8,
>> +	.val_bits	= 8,
>> +	.max_register	= RT5033_REG_END,
>> +};
>> +
>> +static int rt5033_i2c_probe(struct i2c_client *i2c,
>> +				const struct i2c_device_id *id)
>> +{
>> +	struct rt5033_dev *rt5033;
>> +	unsigned int data;
>> +	int ret;
>> +
>> +	rt5033 = devm_kzalloc(&i2c->dev, sizeof(*rt5033), GFP_KERNEL);
>> +	if (!rt5033)
>> +		return -ENOMEM;
>> +
>> +	i2c_set_clientdata(i2c, rt5033);
>> +	rt5033->dev = &i2c->dev;
>> +	rt5033->irq = i2c->irq;
>> +	rt5033->wakeup = true;
>> +
>> +	rt5033->regmap = devm_regmap_init_i2c(i2c, &rt5033_regmap_config);
>> +	if (IS_ERR(rt5033->regmap)) {
>> +		dev_err(&i2c->dev, "Failed to allocate register map.\n");
>> +		return PTR_ERR(rt5033->regmap);
>> +	}
>> +
>> +	ret = regmap_read(rt5033->regmap, RT5033_REG_DEVICE_ID, &data);
>> +	if (ret) {
>> +		dev_err(&i2c->dev, "Device not found\n");
>> +		return -ENODEV;
>> +	}
>> +	dev_info(&i2c->dev, "Device found Device ID: %04x\n", data);
>> +
>> +	ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
>> +			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
>> +			0, &rt5033_irq_chip, &rt5033->irq_data);
>> +	if (ret) {
>> +		dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
>> +							rt5033->irq, ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = mfd_add_devices(rt5033->dev, -1, rt5033_devs,
>> +			ARRAY_SIZE(rt5033_devs), NULL, 0,
>> +			regmap_irq_get_domain(rt5033->irq_data));
>> +	if (ret < 0) {
>> +		dev_err(&i2c->dev, "Failed to add RT5033 child device.\n");
> 
> s/device/devices/
> 

OK. I will fix it.

>> +		return ret;
>> +	}
>> +
>> +	device_init_wakeup(rt5033->dev, rt5033->wakeup);
>> +
>> +	return 0;
>> +}
>> +
>> +static int rt5033_i2c_remove(struct i2c_client *i2c)
>> +{
>> +	struct rt5033_dev *rt5033 = i2c_get_clientdata(i2c);
>> +
>> +	mfd_remove_devices(rt5033->dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct i2c_device_id rt5033_i2c_id[] = {
>> +	{ "rt5033", },
>> +	{ }
>> +};
>> +MODULE_DEVICE_TABLE(i2c, rt5033_i2c_id);
> 
> Why do you need to export this if you're not building as a module?
> 

I will change possible building as a module.

>> +static struct i2c_driver rt5033_driver = {
>> +	.driver = {
>> +		.name = "rt5033",
>> +		.of_match_table = of_match_ptr(rt5033_dt_match),
>> +	},
>> +	.probe = rt5033_i2c_probe,
>> +	.remove = rt5033_i2c_remove,
>> +	.id_table = rt5033_i2c_id,
>> +};
>> +module_i2c_driver(rt5033_driver);
>>
>> +MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver");
>> +MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
>> +MODULE_LICENSE("GPL");
> 
> More module stuff?
> 
> [...]
> 
OK. I will revise this patch on your advice.

Again Thank you for your advice.
I will submit next revision patch set.

Regards,
Beomho Seo

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-11-19  0:39 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-12 12:07 [PATCH v3 0/5] mfd: rt5033: Add Richtek RT5033 drivers Beomho Seo
2014-11-12 12:07 ` [PATCH v3 1/5] mfd: rt5033: Add Richtek RT5033 driver core Beomho Seo
2014-11-18 16:25   ` Lee Jones
2014-11-19  0:39     ` Beomho Seo
2014-11-12 12:07 ` [PATCH v3 2/5] regulator: rt5033: Add RT5033 Regulator device driver Beomho Seo
2014-11-14 17:55   ` Mark Brown
2014-11-12 12:08 ` [PATCH v3 3/5] power: rt5033_battery: Add RT5033 Fuel gauge " Beomho Seo
2014-11-12 12:08 ` [PATCH v3 4/5] power: rt5033_charger: Add RT5033 charger " Beomho Seo
2014-11-12 12:08 ` [PATCH v3 5/5] Documentation: Add documentation for rt5033 multifunction device Beomho Seo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).