All of lore.kernel.org
 help / color / mirror / Atom feed
From: Piotr Wilczek <p.wilczek@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH V2] drivers:power:max77693: add support for new multi function pmic max77693
Date: Tue, 24 Sep 2013 16:31:22 +0200	[thread overview]
Message-ID: <1380033082-29962-1-git-send-email-p.wilczek@samsung.com> (raw)
In-Reply-To: <1369141218-26557-1-git-send-email-p.wilczek@samsung.com>

This patch add support for new multi function pmic max77693.
The driver is split into three modules: pmic, muic and fuelgage.

Signed-off-by: Piotr Wilczek <p.wilczek@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
CC: Minkyu Kang <mk7.kang@samsung.com>
---

Changes for V2:
 - replaced GPL license with SPDX license GPL-2.0+;
 - added author to all new files;
 - fixed return values;

 Makefile                          |    1 +
 drivers/power/mfd/Makefile        |   33 +++++++++
 drivers/power/mfd/fg_max77693.c   |  139 +++++++++++++++++++++++++++++++++++++
 drivers/power/mfd/muic_max77693.c |   77 ++++++++++++++++++++
 drivers/power/mfd/pmic_max77693.c |   96 +++++++++++++++++++++++++
 include/power/max77693_fg.h       |   49 +++++++++++++
 include/power/max77693_muic.h     |   74 ++++++++++++++++++++
 include/power/max77693_pmic.h     |   43 ++++++++++++
 8 files changed, 512 insertions(+)
 create mode 100644 drivers/power/mfd/Makefile
 create mode 100644 drivers/power/mfd/fg_max77693.c
 create mode 100644 drivers/power/mfd/muic_max77693.c
 create mode 100644 drivers/power/mfd/pmic_max77693.c
 create mode 100644 include/power/max77693_fg.h
 create mode 100644 include/power/max77693_muic.h
 create mode 100644 include/power/max77693_pmic.h

diff --git a/Makefile b/Makefile
index 1365db6..7d62f38 100644
--- a/Makefile
+++ b/Makefile
@@ -284,6 +284,7 @@ LIBS-y += drivers/pci/libpci.o
 LIBS-y += drivers/pcmcia/libpcmcia.o
 LIBS-y += drivers/power/libpower.o \
 	drivers/power/fuel_gauge/libfuel_gauge.o \
+	drivers/power/mfd/libmfd.o \
 	drivers/power/pmic/libpmic.o \
 	drivers/power/battery/libbattery.o
 LIBS-y += drivers/spi/libspi.o
diff --git a/drivers/power/mfd/Makefile b/drivers/power/mfd/Makefile
new file mode 100644
index 0000000..76a05da
--- /dev/null
+++ b/drivers/power/mfd/Makefile
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2013 Samsung Electronics
+# Piotr Wilczek <p.wilczek@samsung.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)libmfd.o
+
+COBJS-$(CONFIG_POWER_PMIC_MAX77693) += pmic_max77693.o
+COBJS-$(CONFIG_POWER_MUIC_MAX77693) += muic_max77693.o
+COBJS-$(CONFIG_POWER_FG_MAX77693) += fg_max77693.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+########################################################################
diff --git a/drivers/power/mfd/fg_max77693.c b/drivers/power/mfd/fg_max77693.c
new file mode 100644
index 0000000..4519fed
--- /dev/null
+++ b/drivers/power/mfd/fg_max77693.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics
+ * Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/max77693_fg.h>
+#include <i2c.h>
+#include <power/power_chrg.h>
+#include <power/battery.h>
+#include <power/fg_battery_cell_params.h>
+#include <errno.h>
+
+static int max77693_get_vcell(u32 *vcell)
+{
+	u16 value;
+	u8 ret;
+
+	ret = i2c_read(MAX77693_FUEL_I2C_ADDR, MAX77693_VCELL, 1,
+		       (u8 *)&value, 2);
+	if (ret)
+		return ret;
+
+	*vcell = (u32)(value >> 3);
+	*vcell = *vcell * 625;
+
+	return 0;
+}
+
+static int max77693_get_soc(u32 *soc)
+{
+	u16 value;
+	u8 ret;
+
+	ret = i2c_read(MAX77693_FUEL_I2C_ADDR, MAX77693_VFSOC, 1,
+		       (u8 *)&value, 2);
+	if (ret)
+		return ret;
+
+	*soc = (u32)(value >> 8);
+
+	return 0;
+}
+
+static int power_update_battery(struct pmic *p, struct pmic *bat)
+{
+	struct power_battery *pb = bat->pbat;
+	int ret;
+
+	if (pmic_probe(p)) {
+		puts("Can't find max77693 fuel gauge\n");
+		return -1;
+	}
+
+	ret = max77693_get_soc(&pb->bat->state_of_chrg);
+	if (ret)
+		return ret;
+
+	max77693_get_vcell(&pb->bat->voltage_uV);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int power_check_battery(struct pmic *p, struct pmic *bat)
+{
+	struct power_battery *pb = bat->pbat;
+	unsigned int val;
+	int ret = 0;
+
+	if (pmic_probe(p)) {
+		puts("Can't find max77693 fuel gauge\n");
+		return -1;
+	}
+
+	ret = pmic_reg_read(p, MAX77693_STATUS, &val);
+	if (ret)
+		return ret;
+	debug("fg status: 0x%x\n", val);
+
+	ret = pmic_reg_read(p, MAX77693_VERSION, &pb->bat->version);
+	if (ret)
+		return ret;
+
+	ret = power_update_battery(p, bat);
+	if (ret)
+		return ret;
+	debug("fg ver: 0x%x\n", pb->bat->version);
+	printf("BAT: state_of_charge(SOC):%d%%\n",
+	       pb->bat->state_of_chrg);
+
+	printf("     voltage: %d.%6.6d [V] (expected to be %d [mAh])\n",
+	       pb->bat->voltage_uV / 1000000,
+	       pb->bat->voltage_uV % 1000000,
+	       pb->bat->capacity);
+
+	if (pb->bat->voltage_uV > 3850000)
+		pb->bat->state = EXT_SOURCE;
+	else if (pb->bat->voltage_uV < 3600000 || pb->bat->state_of_chrg < 5)
+		pb->bat->state = CHARGE;
+	else
+		pb->bat->state = NORMAL;
+
+	return 0;
+}
+
+static struct power_fg power_fg_ops = {
+	.fg_battery_check = power_check_battery,
+	.fg_battery_update = power_update_battery,
+};
+
+int power_fg_init(unsigned char bus)
+{
+	static const char name[] = "MAX77693_FG";
+	struct pmic *p = pmic_alloc();
+
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
+
+	debug("Board Fuel Gauge init\n");
+
+	p->name = name;
+	p->interface = PMIC_I2C;
+	p->number_of_regs = FG_NUM_OF_REGS;
+	p->hw.i2c.addr = MAX77693_FUEL_I2C_ADDR;
+	p->hw.i2c.tx_num = 2;
+	p->sensor_byte_order = PMIC_SENSOR_BYTE_ORDER_BIG;
+	p->bus = bus;
+
+	p->fg = &power_fg_ops;
+
+	return 0;
+}
diff --git a/drivers/power/mfd/muic_max77693.c b/drivers/power/mfd/muic_max77693.c
new file mode 100644
index 0000000..e71012d
--- /dev/null
+++ b/drivers/power/mfd/muic_max77693.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics
+ * Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/power_chrg.h>
+#include <power/max77693_muic.h>
+#include <i2c.h>
+#include <errno.h>
+
+static int power_chrg_get_type(struct pmic *p)
+{
+	unsigned int val;
+	unsigned int charge_type, charger;
+
+	/* if probe failed, return cable none */
+	if (pmic_probe(p))
+		return CHARGER_NO;
+
+	pmic_reg_read(p, MAX77693_MUIC_STATUS2, &val);
+
+	charge_type = val & MAX77693_MUIC_CHG_MASK;
+
+	switch (charge_type) {
+	case MAX77693_MUIC_CHG_NO:
+		charger = CHARGER_NO;
+		break;
+	case MAX77693_MUIC_CHG_USB:
+	case MAX77693_MUIC_CHG_USB_D:
+		charger = CHARGER_USB;
+		break;
+	case MAX77693_MUIC_CHG_TA:
+	case MAX77693_MUIC_CHG_TA_1A:
+		charger = CHARGER_TA;
+		break;
+	case MAX77693_MUIC_CHG_TA_500:
+		charger = CHARGER_TA_500;
+		break;
+	default:
+		charger = CHARGER_UNKNOWN;
+		break;
+	}
+
+	return charger;
+}
+
+static struct power_chrg power_chrg_muic_ops = {
+	.chrg_type = power_chrg_get_type,
+};
+
+int power_muic_init(unsigned int bus)
+{
+	static const char name[] = "MAX77693_MUIC";
+	struct pmic *p = pmic_alloc();
+
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
+
+	debug("Board Micro USB Interface Controller init\n");
+
+	p->name = name;
+	p->interface = PMIC_I2C;
+	p->number_of_regs = MUIC_NUM_OF_REGS;
+	p->hw.i2c.addr = MAX77693_MUIC_I2C_ADDR;
+	p->hw.i2c.tx_num = 1;
+	p->bus = bus;
+
+	p->chrg = &power_chrg_muic_ops;
+
+	return 0;
+}
diff --git a/drivers/power/mfd/pmic_max77693.c b/drivers/power/mfd/pmic_max77693.c
new file mode 100644
index 0000000..1a4416b
--- /dev/null
+++ b/drivers/power/mfd/pmic_max77693.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics
+ * Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <power/pmic.h>
+#include <power/max77693_pmic.h>
+#include <i2c.h>
+#include <errno.h>
+
+static int max77693_charger_state(struct pmic *p, int state, int current)
+{
+	unsigned int val;
+
+	if (pmic_probe(p))
+		return -1;
+
+	/* unlock write capability */
+	val = MAX77693_CHG_UNLOCK;
+	pmic_reg_write(p, MAX77693_CHG_CNFG_06, val);
+
+	if (state == CHARGER_DISABLE) {
+		puts("Disable the charger.\n");
+		pmic_reg_read(p, MAX77693_CHG_CNFG_00, &val);
+		val &= ~0x01;
+		pmic_reg_write(p, MAX77693_CHG_CNFG_00, val);
+		return -1;
+	}
+
+	if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) {
+		printf("%s: Wrong charge current: %d [mA]\n",
+		       __func__, current);
+		return -1;
+	}
+
+	/* set charging current */
+	pmic_reg_read(p, MAX77693_CHG_CNFG_02, &val);
+	val &= ~MAX77693_CHG_CC;
+	val |= current * 10 / 333;	/* 0.1A/3 steps */
+	pmic_reg_write(p, MAX77693_CHG_CNFG_02, val);
+
+	/* enable charging */
+	val = MAX77693_CHG_MODE_ON;
+	pmic_reg_write(p, MAX77693_CHG_CNFG_00, val);
+
+	/* check charging current */
+	pmic_reg_read(p, MAX77693_CHG_CNFG_02, &val);
+	val &= 0x3f;
+	printf("Enable the charger @ %d [mA]\n", val * 333 / 10);
+
+	return 0;
+}
+
+static int max77693_charger_bat_present(struct pmic *p)
+{
+	unsigned int val;
+
+	if (pmic_probe(p))
+		return -1;
+
+	pmic_reg_read(p, MAX77693_CHG_INT_OK, &val);
+
+	return !(val & MAX77693_CHG_DETBAT);
+}
+
+static struct power_chrg power_chrg_pmic_ops = {
+	.chrg_bat_present = max77693_charger_bat_present,
+	.chrg_state = max77693_charger_state,
+};
+
+int pmic_init_max77693(unsigned char bus)
+{
+	static const char name[] = "MAX77693_PMIC";
+	struct pmic *p = pmic_alloc();
+
+	if (!p) {
+		printf("%s: POWER allocation error!\n", __func__);
+		return -ENOMEM;
+	}
+
+	debug("Board PMIC init\n");
+
+	p->name = name;
+	p->interface = PMIC_I2C;
+	p->number_of_regs = PMIC_NUM_OF_REGS;
+	p->hw.i2c.addr = MAX77693_PMIC_I2C_ADDR;
+	p->hw.i2c.tx_num = 1;
+	p->bus = bus;
+
+	p->chrg = &power_chrg_pmic_ops;
+
+	return 0;
+}
diff --git a/include/power/max77693_fg.h b/include/power/max77693_fg.h
new file mode 100644
index 0000000..42626ed
--- /dev/null
+++ b/include/power/max77693_fg.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics
+ * Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MAX77693_FG_H_
+#define __MAX77693_FG_H_
+
+/* MAX 77693 registers */
+enum {
+	MAX77693_STATUS		= 0x00,
+	MAX77693_SOCREP		= 0x06,
+	MAX77693_VCELL		= 0x09,
+	MAX77693_CURRENT	= 0x0A,
+	MAX77693_AVG_CURRENT	= 0x0B,
+	MAX77693_SOCMIX		= 0x0D,
+	MAX77693_SOCAV		= 0x0E,
+	MAX77693_DESIGN_CAP	= 0x18,
+	MAX77693_AVG_VCELL	= 0x19,
+	MAX77693_CONFIG		= 0x1D,
+	MAX77693_VERSION	= 0x21,
+	MAX77693_LEARNCFG	= 0x28,
+	MAX77693_FILTERCFG	= 0x29,
+	MAX77693_RELAXCFG	= 0x2A,
+	MAX77693_MISCCFG	= 0x2B,
+	MAX77693_CGAIN		= 0x2E,
+	MAX77693_COFF		= 0x2F,
+	MAX77693_RCOMP0		= 0x38,
+	MAX77693_TEMPCO		= 0x39,
+	MAX77693_FSTAT		= 0x3D,
+	MAX77693_VFOCV		= 0xEE,
+	MAX77693_VFSOC		= 0xFF,
+
+	FG_NUM_OF_REGS		= 0x100,
+};
+
+#define MAX77693_POR (1 << 1)
+
+#define MODEL_UNLOCK1		0x0059
+#define MODEL_UNLOCK2		0x00c4
+#define MODEL_LOCK1		0x0000
+#define MODEL_LOCK2		0x0000
+
+#define MAX77693_FUEL_I2C_ADDR	(0x6C >> 1)
+
+int power_fg_init(unsigned char bus);
+#endif /* __MAX77693_FG_H_ */
diff --git a/include/power/max77693_muic.h b/include/power/max77693_muic.h
new file mode 100644
index 0000000..a2c29eb
--- /dev/null
+++ b/include/power/max77693_muic.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics
+ * Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MAX77693_MUIC_H_
+#define __MAX77693_MUIC_H_
+
+#include <power/power_chrg.h>
+
+/*
+ * MUIC REGISTER
+ */
+
+#define MAX77693_MUIC_PREFIX	"max77693-muic:"
+
+/* MAX77693_MUIC_STATUS1 */
+#define MAX77693_MUIC_ADC_MASK	0x1F
+
+/* MAX77693_MUIC_STATUS2 */
+#define MAX77693_MUIC_CHG_NO		0x00
+#define MAX77693_MUIC_CHG_USB		0x01
+#define MAX77693_MUIC_CHG_USB_D		0x02
+#define MAX77693_MUIC_CHG_TA		0x03
+#define MAX77693_MUIC_CHG_TA_500	0x04
+#define MAX77693_MUIC_CHG_TA_1A		0x05
+#define MAX77693_MUIC_CHG_MASK		0x07
+
+/* MAX77693_MUIC_CONTROL1 */
+#define MAX77693_MUIC_CTRL1_DN1DP2	((0x1 << 3) | 0x1)
+#define MAX77693_MUIC_CTRL1_UT1UR2	((0x3 << 3) | 0x3)
+#define MAX77693_MUIC_CTRL1_ADN1ADP2	((0x4 << 3) | 0x4)
+#define MAX77693_MUIC_CTRL1_AUT1AUR2	((0x5 << 3) | 0x5)
+#define MAX77693_MUIC_CTRL1_MASK	0xC0
+
+#define MUIC_PATH_USB	0
+#define MUIC_PATH_UART	1
+
+#define MUIC_PATH_CP	0
+#define MUIC_PATH_AP	1
+
+enum muic_path {
+	MUIC_PATH_USB_CP,
+	MUIC_PATH_USB_AP,
+	MUIC_PATH_UART_CP,
+	MUIC_PATH_UART_AP,
+};
+
+/* MAX 777693 MUIC registers */
+enum {
+	MAX77693_MUIC_ID	= 0x00,
+	MAX77693_MUIC_INT1	= 0x01,
+	MAX77693_MUIC_INT2	= 0x02,
+	MAX77693_MUIC_INT3	= 0x03,
+	MAX77693_MUIC_STATUS1	= 0x04,
+	MAX77693_MUIC_STATUS2	= 0x05,
+	MAX77693_MUIC_STATUS3	= 0x06,
+	MAX77693_MUIC_INTMASK1	= 0x07,
+	MAX77693_MUIC_INTMASK2	= 0x08,
+	MAX77693_MUIC_INTMASK3	= 0x09,
+	MAX77693_MUIC_CDETCTRL	= 0x0A,
+	MAX77693_MUIC_CONTROL1	= 0x0C,
+	MAX77693_MUIC_CONTROL2	= 0x0D,
+	MAX77693_MUIC_CONTROL3	= 0x0E,
+
+	MUIC_NUM_OF_REGS	= 0x0F,
+};
+
+#define MAX77693_MUIC_I2C_ADDR	(0x4A >> 1)
+
+int power_muic_init(unsigned int bus);
+#endif /* __MAX77693_MUIC_H_ */
diff --git a/include/power/max77693_pmic.h b/include/power/max77693_pmic.h
new file mode 100644
index 0000000..616d051
--- /dev/null
+++ b/include/power/max77693_pmic.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics
+ * Piotr Wilczek <p.wilczek@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MAX77693_PMIC_H_
+#define __MAX77693_PMIC_H_
+
+#include <power/power_chrg.h>
+
+enum {CHARGER_ENABLE, CHARGER_DISABLE};
+
+#define CHARGER_MIN_CURRENT 200
+#define CHARGER_MAX_CURRENT 2000
+
+#define MAX77693_CHG_PREFIX	"max77693-chg:"
+
+/* Registers */
+
+#define MAX77693_CHG_BASE	0xB0
+#define MAX77693_CHG_INT_OK	0xB2
+#define MAX77693_CHG_CNFG_00	0xB7
+#define MAX77693_CHG_CNFG_02	0xB9
+#define MAX77693_CHG_CNFG_06	0xBD
+#define MAX77693_SAFEOUT	0xC6
+
+#define PMIC_NUM_OF_REGS	0xC7
+
+#define MAX77693_CHG_DETBAT	(0x1 << 7)	/* MAX77693_CHG_INT_OK */
+#define MAX77693_CHG_MODE_ON	0x05		/* MAX77693_CHG_CNFG_00 */
+#define MAX77693_CHG_CC		0x3F		/* MAX77693_CHG_CNFG_02	*/
+#define MAX77693_CHG_LOCK	(0x0 << 2)	/* MAX77693_CHG_CNFG_06	*/
+#define MAX77693_CHG_UNLOCK	(0x3 << 2)	/* MAX77693_CHG_CNFG_06	*/
+
+#define MAX77693_ENSAFEOUT1	(1 << 6)
+#define MAX77693_ENSAFEOUT2	(1 << 7)
+
+#define MAX77693_PMIC_I2C_ADDR	(0xCC >> 1)
+
+int pmic_init_max77693(unsigned char bus);
+#endif /* __MAX77693_PMIC_H_ */
-- 
1.7.9.5

  parent reply	other threads:[~2013-09-24 14:31 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-21 13:00 [U-Boot] [PATCH] drivers:power:max77693: add support for new multi function pmic max77693 Piotr Wilczek
2013-08-13 12:47 ` Piotr Wilczek
2013-09-24  2:43 ` Minkyu Kang
2013-09-24 14:31 ` Piotr Wilczek [this message]
2013-09-25  2:15   ` [U-Boot] [PATCH V2] " Minkyu Kang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1380033082-29962-1-git-send-email-p.wilczek@samsung.com \
    --to=p.wilczek@samsung.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.