[coreboot] Patch set updated for coreboot: facc0ef Add the maxim MAX66786 power controller.

Ronald G. Minnich (rminnich@gmail.com) gerrit at coreboot.org
Thu Nov 29 00:02:22 CET 2012


Ronald G. Minnich (rminnich at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1938

-gerrit

commit facc0efa1f45bc7e68ab9e90e0a27ce2a6d864f8
Author: Ronald G. Minnich <rminnich at gmail.com>
Date:   Wed Nov 28 10:44:12 2012 -0800

    Add the maxim MAX66786 power controller.
    
    Create a new directory in drivers for power controllers.
    Add the MAXIM MAX66786 power control support.
    
    Accessing this controller requires I2C support.
    Note that this will not build until the I2C usage is changed for
    coreboot. I'm putting it in mainly because we need it soon
    and I want to see if the new directory is acceptable.
    
    Change-Id: I6c2a6d2165f33b41d2c8e4813222b21d2385e879
    Signed-off-by: David Hendricks <dhendrix at chromium.org>
    SIgned-off-by: Hung-Te Lin <hungte at chromium.org>
    Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
---
 src/drivers/power/Kconfig      |   5 +
 src/drivers/power/Makefile.inc |  20 ++++
 src/drivers/power/max77686.c   | 257 +++++++++++++++++++++++++++++++++++++++++
 src/drivers/power/max77686.h   | 134 +++++++++++++++++++++
 4 files changed, 416 insertions(+)

diff --git a/src/drivers/power/Kconfig b/src/drivers/power/Kconfig
new file mode 100644
index 0000000..84ace13
--- /dev/null
+++ b/src/drivers/power/Kconfig
@@ -0,0 +1,5 @@
+config DRIVER_MAXIM_77686
+	bool "Maxim 77686"
+	default n
+	help
+	  Maxim 77686 power regulator
diff --git a/src/drivers/power/Makefile.inc b/src/drivers/power/Makefile.inc
new file mode 100644
index 0000000..3fc7104
--- /dev/null
+++ b/src/drivers/power/Makefile.inc
@@ -0,0 +1,20 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2012 The ChromiumOS Authors
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+##
+
+driver-$(CONFIG_DRIVER_MAXIM_77686) += max77686.c
diff --git a/src/drivers/power/max77686.c b/src/drivers/power/max77686.c
new file mode 100644
index 0000000..8fbcb8f
--- /dev/null
+++ b/src/drivers/power/max77686.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Alim Akhtar <alim.akhtar at samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <smbus.h>
+#include <max77686.h>
+
+/* Chip register numbers (not exported from this module) */
+enum {
+	REG_BBAT		= 0x7e,
+
+	/* Bits for BBAT */
+	BBAT_BBCHOSTEN_MASK	= 1 << 0,
+	BBAT_BBCVS_SHIFT	= 3,
+	BBAT_BBCVS_MASK		= 3 << BBAT_BBCVS_SHIFT,
+};
+
+/*
+ * Max77686 parameters values
+ * see max77686.h for parameters details
+ */
+struct max77686_para max77686_param[] = {/*{regnum, vol_addr, vol_bitpos,
+	vol_bitmask, reg_enaddr, reg_enbitpos, reg_enbitmask, reg_enbiton,
+	reg_enbitoff, vol_min, vol_div}*/
+	{PMIC_BUCK1, 0x11, 0x0, 0x3F, 0x10, 0x0, 0x3, 0x3, 0x0, 750, 50000},
+	{PMIC_BUCK2, 0x14, 0x0, 0xFF, 0x12, 0x4, 0x3, 0x1, 0x0, 600, 12500},
+	{PMIC_BUCK3, 0x1E, 0x0, 0xFF, 0x1C, 0x4, 0x3, 0x1, 0x0, 600, 12500},
+	{PMIC_BUCK4, 0x28, 0x0, 0xFF, 0x26, 0x4, 0x3, 0x1, 0x0, 600, 12500},
+	{PMIC_BUCK5, 0x31, 0x0, 0x3F, 0x30, 0x0, 0x3, 0x3, 0x0, 750, 50000},
+	{PMIC_BUCK6, 0x33, 0x0, 0x3F, 0x32, 0x0, 0x3, 0x3, 0x0, 750, 50000},
+	{PMIC_BUCK7, 0x35, 0x0, 0x3F, 0x34, 0x0, 0x3, 0x3, 0x0, 750, 50000},
+	{PMIC_BUCK8, 0x37, 0x0, 0x3F, 0x36, 0x0, 0x3, 0x3, 0x0, 750, 50000},
+	{PMIC_BUCK9, 0x39, 0x0, 0x3F, 0x38, 0x0, 0x3, 0x3, 0x0, 750, 50000},
+	{PMIC_LDO1,  0x40, 0x0, 0x3F, 0x40, 0x6, 0x3, 0x3, 0x0, 800, 25000},
+	{PMIC_LDO2,  0x41, 0x0, 0x3F, 0x41, 0x6, 0x3, 0x1, 0x0, 800, 25000},
+	{PMIC_LDO3,  0x42, 0x0, 0x3F, 0x42, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO4,  0x43, 0x0, 0x3F, 0x43, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO5,  0x44, 0x0, 0x3F, 0x44, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO6,  0x45, 0x0, 0x3F, 0x45, 0x6, 0x3, 0x1, 0x0, 800, 25000},
+	{PMIC_LDO7,  0x46, 0x0, 0x3F, 0x46, 0x6, 0x3, 0x1, 0x0, 800, 25000},
+	{PMIC_LDO8,  0x47, 0x0, 0x3F, 0x47, 0x6, 0x3, 0x1, 0x0, 800, 25000},
+	{PMIC_LDO9,  0x48, 0x0, 0x3F, 0x48, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO10, 0x49, 0x0, 0x3F, 0x49, 0x6, 0x3, 0x1, 0x0, 800, 50000},
+	{PMIC_LDO11, 0x4A, 0x0, 0x3F, 0x4A, 0x6, 0x3, 0x1, 0x0, 800, 50000},
+	{PMIC_LDO12, 0x4B, 0x0, 0x3F, 0x4B, 0x6, 0x3, 0x1, 0x0, 800, 50000},
+	{PMIC_LDO13, 0x4C, 0x0, 0x3F, 0x4C, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO14, 0x4D, 0x0, 0x3F, 0x4D, 0x6, 0x3, 0x1, 0x0, 800, 50000},
+	{PMIC_LDO15, 0x4E, 0x0, 0x3F, 0x4E, 0x6, 0x3, 0x1, 0x0, 800, 25000},
+	{PMIC_LDO16, 0x4F, 0x0, 0x3F, 0x4F, 0x6, 0x3, 0x1, 0x0, 800, 50000},
+	{PMIC_LDO17, 0x50, 0x0, 0x3F, 0x50, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO18, 0x51, 0x0, 0x3F, 0x51, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO19, 0x52, 0x0, 0x3F, 0x52, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO20, 0x53, 0x0, 0x3F, 0x53, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO21, 0x54, 0x0, 0x3F, 0x54, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO22, 0x55, 0x0, 0x3F, 0x55, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO23, 0x56, 0x0, 0x3F, 0x56, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO24, 0x57, 0x0, 0x3F, 0x57, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO25, 0x58, 0x0, 0x3F, 0x58, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_LDO26, 0x59, 0x0, 0x3F, 0x59, 0x6, 0x3, 0x3, 0x0, 800, 50000},
+	{PMIC_EN32KHZ_CP, 0x0, 0x0, 0x0, 0x7F, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0},
+};
+
+/*
+ * Write a value to a register
+ *
+ * @param chip_addr	i2c addr for max77686
+ * @param reg		reg number to write
+ * @param val		value to be written
+ *
+ */
+static inline int max77686_i2c_write(unsigned char chip_addr,
+					unsigned int reg, unsigned char val)
+{
+	return i2c_write(chip_addr, reg, 1, &val, 1);
+}
+
+/*
+ * Read a value from a register
+ *
+ * @param chip_addr	i2c addr for max77686
+ * @param reg		reg number to write
+ * @param val		value to be written
+ *
+ */
+static inline int max77686_i2c_read(unsigned char chip_addr,
+					unsigned int reg, unsigned char *val)
+{
+	return i2c_read(chip_addr, reg, 1, val, 1);
+}
+
+/*
+ * Enable the max77686 register
+ *
+ * @param reg		register number of buck/ldo to be enabled
+ * @param enable	enable or disable bit
+ *
+ *			REG_DISABLE = 0,
+			needed to set the buck/ldo enable bit OFF
+ * @return		Return 0 if ok, else -1
+ */
+static int max77686_enablereg(enum max77686_regnum reg, int enable)
+{
+	struct max77686_para *pmic;
+	unsigned char read_data;
+	int ret;
+
+	pmic = &max77686_param[reg];
+
+	ret = max77686_i2c_read(MAX77686_I2C_ADDR, pmic->reg_enaddr,
+				&read_data);
+	if (ret != 0) {
+		debug("max77686 i2c read failed.\n");
+		return -1;
+	}
+
+	if (enable == REG_DISABLE) {
+		clrbits_8(&read_data,
+				pmic->reg_enbitmask << pmic->reg_enbitpos);
+	} else {
+		clrsetbits_8(&read_data,
+				pmic->reg_enbitmask << pmic->reg_enbitpos,
+				pmic->reg_enbiton << pmic->reg_enbitpos);
+	}
+
+	ret = max77686_i2c_write(MAX77686_I2C_ADDR,
+				 pmic->reg_enaddr, read_data);
+	if (ret != 0) {
+		debug("max77686 i2c write failed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int max77686_do_volsetting(enum max77686_regnum reg, unsigned int volt,
+				  int enable, int volt_units)
+{
+	struct max77686_para *pmic;
+	unsigned char read_data;
+	int vol_level = 0;
+	int ret;
+
+	pmic = &max77686_param[reg];
+
+	if (pmic->vol_addr == 0) {
+		debug("not a voltage register.\n");
+		return -1;
+	}
+
+	ret = max77686_i2c_read(MAX77686_I2C_ADDR, pmic->vol_addr, &read_data);
+	if (ret != 0) {
+		debug("max77686 i2c read failed.\n");
+		return -1;
+	}
+
+	if (volt_units == MAX77686_UV)
+		vol_level = volt - pmic->vol_min * 1000;
+	else
+		vol_level = (volt - pmic->vol_min) * 1000;
+
+	if (vol_level < 0) {
+		debug("Not a valid voltage level to set\n");
+		return -1;
+	}
+	vol_level /= pmic->vol_div;
+
+	clrsetbits_8(&read_data, pmic->vol_bitmask << pmic->vol_bitpos,
+			vol_level << pmic->vol_bitpos);
+
+	ret = max77686_i2c_write(MAX77686_I2C_ADDR, pmic->vol_addr, read_data);
+	if (ret != 0) {
+		debug("max77686 i2c write failed.\n");
+		return -1;
+	}
+
+	ret = max77686_enablereg(reg, enable);
+	if (ret != 0) {
+		debug("Failed to enable buck/ldo.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int max77686_volsetting(enum max77686_regnum reg, unsigned int volt,
+			int enable, int volt_units)
+{
+	int old_bus = i2c_get_bus_num();
+	int ret;
+
+	i2c_set_bus_num(0);
+	ret = max77686_do_volsetting(reg, volt, enable, volt_units);
+	i2c_set_bus_num(old_bus);
+	return ret;
+}
+
+int max77686_enable_32khz_cp(void)
+{
+	i2c_set_bus_num(0);
+	return max77686_enablereg(PMIC_EN32KHZ_CP, REG_ENABLE);
+}
+
+int max77686_disable_backup_batt(void)
+{
+	unsigned char val;
+	int ret;
+
+	i2c_set_bus_num(0);
+	ret = max77686_i2c_read(MAX77686_I2C_ADDR, REG_BBAT, &val);
+	if (ret) {
+		debug("max77686 i2c read failed\n");
+		return ret;
+	}
+
+	/* If we already have the correct values, exit */
+	if ((val & (BBAT_BBCVS_MASK | BBAT_BBCHOSTEN_MASK)) ==
+			BBAT_BBCVS_MASK)
+		return 0;
+
+	/* First disable charging */
+	val &= ~BBAT_BBCHOSTEN_MASK;
+	ret = max77686_i2c_write(MAX77686_I2C_ADDR, REG_BBAT, val);
+	if (ret) {
+		debug("max77686 i2c write failed\n");
+		return -1;
+	}
+
+	/* Finally select 3.5V to minimize power consumption */
+	val |= BBAT_BBCVS_MASK;
+	ret = max77686_i2c_write(MAX77686_I2C_ADDR, REG_BBAT, val);
+	if (ret) {
+		debug("max77686 i2c write failed\n");
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/src/drivers/power/max77686.h b/src/drivers/power/max77686.h
new file mode 100644
index 0000000..345471e
--- /dev/null
+++ b/src/drivers/power/max77686.h
@@ -0,0 +1,134 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Alim Akhtar <alim.akhtar at samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MAX77686_H_
+#define __MAX77686_H_
+
+enum max77686_regnum {
+	PMIC_BUCK1 = 0,
+	PMIC_BUCK2,
+	PMIC_BUCK3,
+	PMIC_BUCK4,
+	PMIC_BUCK5,
+	PMIC_BUCK6,
+	PMIC_BUCK7,
+	PMIC_BUCK8,
+	PMIC_BUCK9,
+	PMIC_LDO1,
+	PMIC_LDO2,
+	PMIC_LDO3,
+	PMIC_LDO4,
+	PMIC_LDO5,
+	PMIC_LDO6,
+	PMIC_LDO7,
+	PMIC_LDO8,
+	PMIC_LDO9,
+	PMIC_LDO10,
+	PMIC_LDO11,
+	PMIC_LDO12,
+	PMIC_LDO13,
+	PMIC_LDO14,
+	PMIC_LDO15,
+	PMIC_LDO16,
+	PMIC_LDO17,
+	PMIC_LDO18,
+	PMIC_LDO19,
+	PMIC_LDO20,
+	PMIC_LDO21,
+	PMIC_LDO22,
+	PMIC_LDO23,
+	PMIC_LDO24,
+	PMIC_LDO25,
+	PMIC_LDO26,
+	PMIC_EN32KHZ_CP,
+};
+
+/**
+ * struct max77686_para - max77686 register parameters
+ * @param vol_addr	i2c address of the given buck/ldo register
+ * @param vol_bitpos	bit position to be set or clear within register
+ * @param vol_bitmask	bit mask value
+ * @param reg_enaddr	control register address, which enable the given
+ *			given buck/ldo.
+ * @param reg_enbitpos	bit position to be enabled
+ * @param reg_enbiton	value to be written to buck/ldo to make it ON
+ * @param reg_enbitoff	value to be written to buck/ldo to make it OFF
+ * @param vol_min	minimum voltage level supported by given buck/ldo
+ * @param vol_div	voltage division value of given buck/ldo
+ */
+struct max77686_para {
+	enum max77686_regnum regnum;
+	u8	vol_addr;
+	u8	vol_bitpos;
+	u8	vol_bitmask;
+	u8	reg_enaddr;
+	u8	reg_enbitpos;
+	u8	reg_enbitmask;
+	u8	reg_enbiton;
+	u8	reg_enbitoff;
+	u32	vol_min;
+	u32	vol_div;
+};
+
+/* I2C device address for pmic max77686 */
+#define MAX77686_I2C_ADDR (0x12 >> 1)
+
+enum {
+	REG_DISABLE = 0,
+	REG_ENABLE
+};
+
+enum {
+	MAX77686_MV = 0,	/* mili volt */
+	MAX77686_UV		/* micro volt */
+};
+
+/**
+ * This function enables the 32KHz coprocessor clock.
+ *
+ * Return 0 if ok, else -1
+ */
+int max77686_enable_32khz_cp(void);
+
+/**
+ * Set the required voltage level of pmic
+ *
+ * @param reg		register number of buck/ldo to be set
+ * @param volt		voltage level to be set
+ * @param enable	enable or disable bit
+ * @param volt_units	MAX77686_MV or MAX77686_UV, unit of the
+ *			voltage parameters
+ *
+ * @return		Return 0 if ok, else -1
+ */
+int max77686_volsetting(enum max77686_regnum reg, unsigned int volt,
+			int enable, int volt_units);
+
+/**
+ * Disable charging of the RTC backup battery
+ *
+ * @return		Return 0 if ok, else -1
+ */
+int max77686_disable_backup_batt(void);
+
+#endif /* __MAX77686_PMIC_H_ */




More information about the coreboot mailing list