diff options
23 files changed, 287 insertions, 105 deletions
| diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c index c41f11d60..a3079dbca 100644 --- a/board/davedenx/qong/qong.c +++ b/board/davedenx/qong/qong.c @@ -28,11 +28,12 @@  #include <asm/arch/sys_proto.h>  #include <asm/io.h>  #include <nand.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h>  #include <asm/gpio.h>  #include "qong_fpga.h"  #include <watchdog.h> +#include <errno.h>  DECLARE_GLOBAL_DATA_PTR; @@ -172,10 +173,15 @@ int board_late_init(void)  {  	u32 val;  	struct pmic *p; +	int ret; -	pmic_init(); -	p = get_pmic(); +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return ret; +	p = pmic_get("FSL_PMIC"); +	if (!p) +		return -ENODEV;  	/* Enable RTC battery */  	pmic_reg_read(p, REG_POWER_CTL0, &val);  	pmic_reg_write(p, REG_POWER_CTL0, val | COINCHEN); diff --git a/board/freescale/mx31pdk/mx31pdk.c b/board/freescale/mx31pdk/mx31pdk.c index 9f8bc53e7..bc60632aa 100644 --- a/board/freescale/mx31pdk/mx31pdk.c +++ b/board/freescale/mx31pdk/mx31pdk.c @@ -30,8 +30,9 @@  #include <asm/arch/imx-regs.h>  #include <asm/arch/sys_proto.h>  #include <watchdog.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h> +#include <errno.h>  DECLARE_GLOBAL_DATA_PTR; @@ -83,10 +84,15 @@ int board_late_init(void)  {  	u32 val;  	struct pmic *p; +	int ret; -	pmic_init(); -	p = get_pmic(); +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return ret; +	p = pmic_get("FSL_PMIC"); +	if (!p) +		return -ENODEV;  	/* Enable RTC battery */  	pmic_reg_read(p, REG_POWER_CTL0, &val);  	pmic_reg_write(p, REG_POWER_CTL0, val | COINCHEN); diff --git a/board/freescale/mx35pdk/mx35pdk.c b/board/freescale/mx35pdk/mx35pdk.c index a12531fb8..c835b0ede 100644 --- a/board/freescale/mx35pdk/mx35pdk.c +++ b/board/freescale/mx35pdk/mx35pdk.c @@ -31,7 +31,7 @@  #include <asm/arch/mx35_pins.h>  #include <asm/arch/iomux.h>  #include <i2c.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h>  #include <mmc.h>  #include <fsl_esdhc.h> @@ -207,7 +207,9 @@ int board_init(void)  static inline int pmic_detect(void)  {  	unsigned int id; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("FSL_PMIC"); +	if (!p) +		return -ENODEV;  	pmic_reg_read(p, REG_IDENTIFICATION, &id); @@ -231,10 +233,14 @@ int board_late_init(void)  	u8 val;  	u32 pmic_val;  	struct pmic *p; +	int ret; + +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return ret; -	pmic_init();  	if (pmic_detect()) { -		p = get_pmic(); +		p = pmic_get("FSL_PMIC");  		mxc_request_iomux(MX35_PIN_WATCHDOG_RST, MUX_CONFIG_SION |  					MUX_CONFIG_ALT1); diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c index 421d8c224..5504636dd 100644 --- a/board/freescale/mx51evk/mx51evk.c +++ b/board/freescale/mx51evk/mx51evk.c @@ -33,7 +33,7 @@  #include <i2c.h>  #include <mmc.h>  #include <fsl_esdhc.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h>  #include <mc13892.h>  #include <usb/ehci-fsl.h> @@ -252,9 +252,15 @@ static void power_init(void)  	unsigned int val;  	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;  	struct pmic *p; +	int ret; + +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return; -	pmic_init(); -	p = get_pmic(); +	p = pmic_get("FSL_PMIC"); +	if (!p) +		return;  	/* Write needed to Power Gate 2 register */  	pmic_reg_read(p, REG_POWER_MISC, &val); diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c index bb4621d62..127350147 100644 --- a/board/freescale/mx53evk/mx53evk.c +++ b/board/freescale/mx53evk/mx53evk.c @@ -34,7 +34,7 @@  #include <i2c.h>  #include <mmc.h>  #include <fsl_esdhc.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h>  #include <asm/gpio.h>  #include <mc13892.h> @@ -123,9 +123,15 @@ void power_init(void)  {  	unsigned int val;  	struct pmic *p; +	int ret; + +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return; -	pmic_init(); -	p = get_pmic(); +	p = pmic_get("FSL_PMIC"); +	if (!p) +		return;  	/* Set VDDA to 1.25V */  	pmic_reg_read(p, REG_SW_2, &val); diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c index a11e88318..f4a9b0842 100644 --- a/board/freescale/mx53loco/mx53loco.c +++ b/board/freescale/mx53loco/mx53loco.c @@ -36,7 +36,7 @@  #include <mmc.h>  #include <fsl_esdhc.h>  #include <asm/gpio.h> -#include <pmic.h> +#include <power/pmic.h>  #include <dialog_pmic.h>  #include <fsl_pmic.h>  #include <linux/fb.h> @@ -344,10 +344,16 @@ static int power_init(void)  	unsigned int val;  	int ret = -1;  	struct pmic *p; +	int retval;  	if (!i2c_probe(CONFIG_SYS_DIALOG_PMIC_I2C_ADDR)) { -		pmic_dialog_init(); -		p = get_pmic(); +		retval = pmic_dialog_init(I2C_PMIC); +		if (retval) +			return retval; + +		p = pmic_get("DIALOG_PMIC"); +		if (!p) +			return -ENODEV;  		/* Set VDDA to 1.25V */  		val = DA9052_BUCKCORE_BCOREEN | DA_BUCKCORE_VBCORE_1_250V; @@ -363,8 +369,13 @@ static int power_init(void)  	}  	if (!i2c_probe(CONFIG_SYS_FSL_PMIC_I2C_ADDR)) { -		pmic_init(); -		p = get_pmic(); +		retval = pmic_init(I2C_PMIC); +		if (retval) +			return retval; + +		p = pmic_get("DIALOG_PMIC"); +		if (!p) +			return -ENODEV;  		/* Set VDDGP to 1.25V for 1GHz on SW1 */  		pmic_reg_read(p, REG_SW_0, &val); diff --git a/board/genesi/mx51_efikamx/efikamx.c b/board/genesi/mx51_efikamx/efikamx.c index c2b2823ef..69d41db53 100644 --- a/board/genesi/mx51_efikamx/efikamx.c +++ b/board/genesi/mx51_efikamx/efikamx.c @@ -33,7 +33,7 @@  #include <i2c.h>  #include <mmc.h>  #include <fsl_esdhc.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h>  #include <mc13892.h> @@ -173,9 +173,15 @@ static void power_init(void)  	unsigned int val;  	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;  	struct pmic *p; +	int ret; + +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return; -	pmic_init(); -	p = get_pmic(); +	p = pmic_get("FSL_PMIC"); +	if (!p) +		return;  	/* Write needed to Power Gate 2 register */  	pmic_reg_read(p, REG_POWER_MISC, &val); diff --git a/board/hale/tt01/tt01.c b/board/hale/tt01/tt01.c index 143fcefed..0c2cb795d 100644 --- a/board/hale/tt01/tt01.c +++ b/board/hale/tt01/tt01.c @@ -25,12 +25,13 @@  #include <common.h>  #include <netdev.h>  #include <command.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h>  #include <mc13783.h>  #include <asm/arch/clock.h>  #include <asm/arch/sys_proto.h>  #include <asm/io.h> +#include <errno.h>  DECLARE_GLOBAL_DATA_PTR; @@ -195,14 +196,21 @@ int board_mmc_init(bd_t *bis)  {  	u32 val;  	struct pmic *p; +	int ret;  	/*  	* this is the first driver to use the pmic, so call  	* pmic_init() here. board_late_init() is too late for  	* the MMC driver.  	*/ -	pmic_init(); -	p = get_pmic(); + +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return ret; + +	p = pmic_get("FSL_PMIC"); +	if (!p) +		return -ENODEV;  	/* configure pins for SDHC1 only */  	mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SD1_CLK, MUX_CTL_FUNC)); diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c index e8fb1ea41..71ed618c6 100644 --- a/board/samsung/goni/goni.c +++ b/board/samsung/goni/goni.c @@ -25,10 +25,10 @@  #include <common.h>  #include <asm/arch/gpio.h>  #include <asm/arch/mmc.h> -#include <pmic.h> +#include <power/pmic.h>  #include <usb/s3c_udc.h>  #include <asm/arch/cpu.h> -#include <max8998_pmic.h> +#include <power/max8998_pmic.h>  DECLARE_GLOBAL_DATA_PTR;  static struct s5pc110_gpio *s5pc110_gpio; @@ -42,8 +42,9 @@ int board_init(void)  	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;  #if defined(CONFIG_PMIC) -	pmic_init(); +	pmic_init(I2C_5);  #endif +  	return 0;  } @@ -108,7 +109,9 @@ static int s5pc1xx_phy_control(int on)  {  	int ret;  	static int status; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("MAX8998_PMIC"); +	if (!p) +		return -ENODEV;  	if (pmic_probe(p))  		return -1; diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index e11a8922f..e0a98901f 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -34,9 +34,9 @@  #include <asm/arch/mipi_dsim.h>  #include <asm/arch/watchdog.h>  #include <asm/arch/power.h> -#include <pmic.h> +#include <power/pmic.h>  #include <usb/s3c_udc.h> -#include <max8997_pmic.h> +#include <power/max8997_pmic.h>  #include <libtizen.h>  #include "setup.h" @@ -69,7 +69,7 @@ int board_init(void)  	printf("HW Revision:\t0x%x\n", board_rev);  #if defined(CONFIG_PMIC) -	pmic_init(); +	pmic_init(I2C_5);  #endif  	return 0; @@ -238,7 +238,9 @@ static int s5pc210_phy_control(int on)  {  	int ret = 0;  	u32 val = 0; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("MAX8997_PMIC"); +	if (!p) +		return -ENODEV;  	if (pmic_probe(p))  		return -1; @@ -413,7 +415,9 @@ static void lcd_reset(void)  static int lcd_power(void)  {  	int ret = 0; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("MAX8997_PMIC"); +	if (!p) +		return -ENODEV;  	if (pmic_probe(p))  		return 0; @@ -473,7 +477,9 @@ static struct mipi_dsim_lcd_device mipi_lcd_device = {  static int mipi_power(void)  {  	int ret = 0; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("MAX8997_PMIC"); +	if (!p) +		return -ENODEV;  	if (pmic_probe(p))  		return 0; diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c index 90fff5cf5..c4950ddc2 100644 --- a/board/samsung/universal_c210/universal.c +++ b/board/samsung/universal_c210/universal.c @@ -27,10 +27,10 @@  #include <asm/arch/adc.h>  #include <asm/arch/gpio.h>  #include <asm/arch/mmc.h> -#include <pmic.h> +#include <power/pmic.h>  #include <usb/s3c_udc.h>  #include <asm/arch/cpu.h> -#include <max8998_pmic.h> +#include <power/max8998_pmic.h>  DECLARE_GLOBAL_DATA_PTR; @@ -59,7 +59,7 @@ int board_init(void)  	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;  #if defined(CONFIG_PMIC) -	pmic_init(); +	pmic_init(I2C_5);  #endif  	check_hw_revision(); @@ -112,7 +112,9 @@ static unsigned short get_adc_value(int channel)  static int adc_power_control(int on)  {  	int ret; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("MAX8998_PMIC"); +	if (!p) +		return -ENODEV;  	if (pmic_probe(p))  		return -1; @@ -280,7 +282,9 @@ int board_mmc_init(bd_t *bis)  static int s5pc210_phy_control(int on)  {  	int ret = 0; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("MAX8998_PMIC"); +	if (!p) +		return -ENODEV;  	if (pmic_probe(p))  		return -1; diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c index abdd1aac2..a471fec23 100644 --- a/board/ttcontrol/vision2/vision2.c +++ b/board/ttcontrol/vision2/vision2.c @@ -34,7 +34,7 @@  #include <asm/arch/sys_proto.h>  #include <i2c.h>  #include <mmc.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_esdhc.h>  #include <fsl_pmic.h>  #include <mc13892.h> @@ -306,9 +306,15 @@ static void power_init_mx51(void)  {  	unsigned int val;  	struct pmic *p; +	int ret; + +	ret = pmic_init(I2C_PMIC); +	if (ret) +		return; -	pmic_init(); -	p = get_pmic(); +	p = pmic_get("FSL_PMIC"); +	if (!p) +		return;  	/* Write needed to Power Gate 2 register */  	pmic_reg_read(p, REG_POWER_MISC, &val); diff --git a/drivers/misc/pmic_core.c b/drivers/misc/pmic_core.c index 5d62a56d3..4066b15ad 100644 --- a/drivers/misc/pmic_core.c +++ b/drivers/misc/pmic_core.c @@ -27,18 +27,21 @@   */  #include <common.h> +#include <malloc.h>  #include <linux/types.h> -#include <pmic.h> +#include <linux/list.h> +#include <power/pmic.h> -static struct pmic pmic; +static LIST_HEAD(pmic_list); -int check_reg(u32 reg) +int check_reg(struct pmic *p, u32 reg)  { -	if (reg >= pmic.number_of_regs) { +	if (reg >= p->number_of_regs) {  		printf("<reg num> = %d is invalid. Should be less than %d\n", -		       reg, pmic.number_of_regs); +		       reg, p->number_of_regs);  		return -1;  	} +  	return 0;  } @@ -65,11 +68,16 @@ static void pmic_show_info(struct pmic *p)  	printf("PMIC: %s\n", p->name);  } -static void pmic_dump(struct pmic *p) +static int pmic_dump(struct pmic *p)  {  	int i, ret;  	u32 val; +	if (!p) { +		puts("Wrong PMIC name!\n"); +		return -1; +	} +  	pmic_show_info(p);  	for (i = 0; i < p->number_of_regs; i++) {  		ret = pmic_reg_read(p, i, &val); @@ -82,35 +90,84 @@ static void pmic_dump(struct pmic *p)  		printf("%08x ", val);  	}  	puts("\n"); +	return 0; +} + +struct pmic *pmic_alloc(void) +{ +	struct pmic *p; + +	p = calloc(sizeof(*p), 1); +	if (!p) { +		printf("%s: No available memory for allocation!\n", __func__); +		return NULL; +	} + +	list_add_tail(&p->list, &pmic_list); + +	debug("%s: new pmic struct: 0x%p\n", __func__, p); + +	return p; +} + +struct pmic *pmic_get(const char *s) +{ +	struct pmic *p; + +	list_for_each_entry(p, &pmic_list, list) { +		if (strcmp(p->name, s) == 0) { +			debug("%s: pmic %s -> 0x%p\n", __func__, p->name, p); +			return p; +		} +	} + +	return NULL;  } -struct pmic *get_pmic(void) +static void pmic_list_names(void)  { -	return &pmic; +	struct pmic *p; + +	puts("PMIC devices:\n"); +	list_for_each_entry(p, &pmic_list, list) { +		printf("name: %s\n", p->name); +	}  }  int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	u32 ret, reg, val; +	struct pmic *p;  	char *cmd; -	struct pmic *p = &pmic; -  	/* at least two arguments please */  	if (argc < 2) -		return cmd_usage(cmdtp); +		return CMD_RET_USAGE;  	cmd = argv[1]; + +	if (strcmp(cmd, "list") == 0) { +		pmic_list_names(); +		return CMD_RET_SUCCESS; +	} +  	if (strcmp(cmd, "dump") == 0) { -		pmic_dump(p); -		return 0; +		p = pmic_get(argv[2]); +		if (!p) +			return CMD_RET_FAILURE; +		if (pmic_dump(p)) +			return CMD_RET_FAILURE; +		return CMD_RET_SUCCESS;  	}  	if (strcmp(cmd, "read") == 0) { -		if (argc < 3) -			return cmd_usage(cmdtp); +		if (argc < 4) +			return CMD_RET_USAGE; -		reg = simple_strtoul(argv[2], NULL, 16); +		reg = simple_strtoul(argv[3], NULL, 16); +		p = pmic_get(argv[2]); +		if (!p) +			return CMD_RET_FAILURE;  		ret = pmic_reg_read(p, reg, &val); @@ -119,29 +176,32 @@ int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		printf("\n0x%02x: 0x%08x\n", reg, val); -		return 0; +		return CMD_RET_SUCCESS;  	}  	if (strcmp(cmd, "write") == 0) { -		if (argc < 4) -			return cmd_usage(cmdtp); - -		reg = simple_strtoul(argv[2], NULL, 16); -		val = simple_strtoul(argv[3], NULL, 16); +		if (argc < 5) +			return CMD_RET_USAGE; +		reg = simple_strtoul(argv[3], NULL, 16); +		val = simple_strtoul(argv[4], NULL, 16); +		p = pmic_get(argv[2]); +		if (!p) +			return CMD_RET_FAILURE;  		pmic_reg_write(p, reg, val); -		return 0; +		return CMD_RET_SUCCESS;  	}  	/* No subcommand found */ -	return 1; +	return CMD_RET_SUCCESS;  }  U_BOOT_CMD(  	pmic,	CONFIG_SYS_MAXARGS, 1, do_pmic,  	"PMIC", -	"dump - dump PMIC registers\n" -	"pmic read <reg> - read register\n" -	"pmic write <reg> <value> - write register" +	"list - list available PMICs\n" +	"pmic dump name - dump named PMIC registers\n" +	"pmic name read <reg> - read register\n" +	"pmic name write <reg> <value> - write register"  ); diff --git a/drivers/misc/pmic_dialog.c b/drivers/misc/pmic_dialog.c index e97af1d1d..d7ebd1583 100644 --- a/drivers/misc/pmic_dialog.c +++ b/drivers/misc/pmic_dialog.c @@ -17,13 +17,19 @@   */  #include <common.h> -#include <pmic.h> +#include <power/pmic.h>  #include <dialog_pmic.h> +#include <errno.h> -int pmic_dialog_init(void) +int pmic_dialog_init(unsigned char bus)  { -	struct pmic *p = get_pmic();  	static const char name[] = "DIALOG_PMIC"; +	struct pmic *p = pmic_alloc(); + +	if (!p) { +		printf("%s: POWER allocation error!\n", __func__); +		return -ENOMEM; +	}  	p->name = name;  	p->number_of_regs = DIALOG_NUM_OF_REGS; @@ -31,7 +37,7 @@ int pmic_dialog_init(void)  	p->interface = PMIC_I2C;  	p->hw.i2c.addr = CONFIG_SYS_DIALOG_PMIC_I2C_ADDR;  	p->hw.i2c.tx_num = 1; -	p->bus = I2C_PMIC; +	p->bus = bus;  	return 0;  } diff --git a/drivers/misc/pmic_fsl.c b/drivers/misc/pmic_fsl.c index 0ff75ed76..0275fd989 100644 --- a/drivers/misc/pmic_fsl.c +++ b/drivers/misc/pmic_fsl.c @@ -23,8 +23,9 @@  #include <common.h>  #include <spi.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h> +#include <errno.h>  #if defined(CONFIG_PMIC_SPI)  static u32 pmic_spi_prepare_tx(u32 reg, u32 *val, u32 write) @@ -33,10 +34,15 @@ static u32 pmic_spi_prepare_tx(u32 reg, u32 *val, u32 write)  }  #endif -int pmic_init(void) +int pmic_init(unsigned char bus)  { -	struct pmic *p = get_pmic();  	static const char name[] = "FSL_PMIC"; +	struct pmic *p = pmic_alloc(); + +	if (!p) { +		printf("%s: POWER allocation error!\n", __func__); +		return -ENOMEM; +	}  	p->name = name;  	p->number_of_regs = PMIC_NUM_OF_REGS; @@ -54,7 +60,7 @@ int pmic_init(void)  	p->interface = PMIC_I2C;  	p->hw.i2c.addr = CONFIG_SYS_FSL_PMIC_I2C_ADDR;  	p->hw.i2c.tx_num = 3; -	p->bus = I2C_PMIC; +	p->bus = bus;  #else  #error "You must select CONFIG_PMIC_SPI or CONFIG_PMIC_I2C"  #endif diff --git a/drivers/misc/pmic_i2c.c b/drivers/misc/pmic_i2c.c index 1064bfe99..3e5a784cf 100644 --- a/drivers/misc/pmic_i2c.c +++ b/drivers/misc/pmic_i2c.c @@ -28,7 +28,7 @@  #include <common.h>  #include <linux/types.h> -#include <pmic.h> +#include <power/pmic.h>  #include <i2c.h>  #include <compiler.h> @@ -36,7 +36,7 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val)  {  	unsigned char buf[4] = { 0 }; -	if (check_reg(reg)) +	if (check_reg(p, reg))  		return -1;  	switch (pmic_i2c_tx_num) { @@ -79,7 +79,7 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)  	unsigned char buf[4] = { 0 };  	u32 ret_val = 0; -	if (check_reg(reg)) +	if (check_reg(p, reg))  		return -1;  	if (i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num)) diff --git a/drivers/misc/pmic_max8997.c b/drivers/misc/pmic_max8997.c index 4943f667b..7fe1b53ff 100644 --- a/drivers/misc/pmic_max8997.c +++ b/drivers/misc/pmic_max8997.c @@ -22,14 +22,20 @@   */  #include <common.h> -#include <pmic.h> -#include <max8997_pmic.h> +#include <power/pmic.h> +#include <power/max8997_pmic.h>  #include <i2c.h> +#include <errno.h> -int pmic_init(void) +int pmic_init(unsigned char bus)  { -	struct pmic *p = get_pmic();  	static const char name[] = "MAX8997_PMIC"; +	struct pmic *p = pmic_alloc(); + +	if (!p) { +		printf("%s: POWER allocation error!\n", __func__); +		return -ENOMEM; +	}  	puts("Board PMIC init\n"); @@ -38,7 +44,7 @@ int pmic_init(void)  	p->number_of_regs = PMIC_NUM_OF_REGS;  	p->hw.i2c.addr = MAX8997_I2C_ADDR;  	p->hw.i2c.tx_num = 1; -	p->bus = I2C_0; +	p->bus = bus;  	return 0;  } diff --git a/drivers/misc/pmic_max8998.c b/drivers/misc/pmic_max8998.c index cc69fd708..452e1c8d8 100644 --- a/drivers/misc/pmic_max8998.c +++ b/drivers/misc/pmic_max8998.c @@ -22,13 +22,19 @@   */  #include <common.h> -#include <pmic.h> -#include <max8998_pmic.h> +#include <power/pmic.h> +#include <power/max8998_pmic.h> +#include <errno.h> -int pmic_init(void) +int pmic_init(unsigned char bus)  { -	struct pmic *p = get_pmic();  	static const char name[] = "MAX8998_PMIC"; +	struct pmic *p = pmic_alloc(); + +	if (!p) { +		printf("%s: POWER allocation error!\n", __func__); +		return -ENOMEM; +	}  	puts("Board PMIC init\n"); @@ -37,7 +43,7 @@ int pmic_init(void)  	p->number_of_regs = PMIC_NUM_OF_REGS;  	p->hw.i2c.addr = MAX8998_I2C_ADDR;  	p->hw.i2c.tx_num = 1; -	p->bus = I2C_PMIC; +	p->bus = bus;  	return 0;  } diff --git a/drivers/misc/pmic_spi.c b/drivers/misc/pmic_spi.c index 5a0dd22e2..27488ea5d 100644 --- a/drivers/misc/pmic_spi.c +++ b/drivers/misc/pmic_spi.c @@ -28,7 +28,7 @@  #include <common.h>  #include <linux/types.h> -#include <pmic.h> +#include <power/pmic.h>  #include <spi.h>  static struct spi_slave *slave; @@ -59,7 +59,7 @@ static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write)  			return -1;  	} -	if (check_reg(reg)) +	if (check_reg(p, reg))  		return -1;  	if (spi_claim_bus(slave)) diff --git a/drivers/rtc/mc13xxx-rtc.c b/drivers/rtc/mc13xxx-rtc.c index 70ea8a158..e79f4621d 100644 --- a/drivers/rtc/mc13xxx-rtc.c +++ b/drivers/rtc/mc13xxx-rtc.c @@ -23,16 +23,18 @@  #include <common.h>  #include <rtc.h>  #include <spi.h> -#include <pmic.h> +#include <power/pmic.h>  #include <fsl_pmic.h>  int rtc_get(struct rtc_time *rtc)  {  	u32 day1, day2, time;  	int tim, i = 0; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("FSL_PMIC");  	int ret; +	if (!p) +		return -1;  	do {  		ret = pmic_reg_read(p, REG_RTC_DAY, &day1);  		if (ret < 0) @@ -61,7 +63,9 @@ int rtc_get(struct rtc_time *rtc)  int rtc_set(struct rtc_time *rtc)  {  	u32 time, day; -	struct pmic *p = get_pmic(); +	struct pmic *p = pmic_get("FSL_PMIC"); +	if (!p) +		return -1;  	time = mktime(rtc->tm_year, rtc->tm_mon, rtc->tm_mday,  		      rtc->tm_hour, rtc->tm_min, rtc->tm_sec); diff --git a/include/max8997_pmic.h b/include/power/max8997_pmic.h index 17ae24ea6..1db7deb3b 100644 --- a/include/max8997_pmic.h +++ b/include/power/max8997_pmic.h @@ -111,7 +111,7 @@ enum {  	MAX8997_REG_MBCCTRL6	= 0x55,  	MAX8997_REG_OTPCGHCVS	= 0x56, -	MAX8997_REG_SAFEOUTCTRL	= 0x5a, +	MAX8997_REG_SAFEOUTCTRL = 0x5a,  	MAX8997_REG_LBCNFG1	= 0x5e,  	MAX8997_REG_LBCNFG2	= 0x5f, @@ -171,9 +171,22 @@ enum {  	PMIC_NUM_OF_REGS = 0x9b,  }; +#define ACTDISSAFEO1 (1 << 4) +#define ACTDISSAFEO2 (1 << 5)  #define ENSAFEOUT1 (1 << 6)  #define ENSAFEOUT2 (1 << 7) +/* Charger */ +enum {CHARGER_ENABLE, CHARGER_DISABLE}; +#define DETBAT                  (1 << 2) +#define MBCICHFCSET             (1 << 4) +#define MBCHOSTEN               (1 << 6) +#define VCHGR_FC                (1 << 7) + +#define CHARGER_MIN_CURRENT 200 +#define CHARGER_MAX_CURRENT 950 +#define CHARGER_CURRENT_RESOLUTION 50 +  #define MAX8997_I2C_ADDR        (0xCC >> 1)  #define MAX8997_RTC_ADDR	(0x0C >> 1)  #define MAX8997_MUIC_ADDR	(0x4A >> 1) diff --git a/include/max8998_pmic.h b/include/power/max8998_pmic.h index ca21f882c..ca21f882c 100644 --- a/include/max8998_pmic.h +++ b/include/power/max8998_pmic.h diff --git a/include/pmic.h b/include/power/pmic.h index 1a2db0511..e9affc8dd 100644 --- a/include/pmic.h +++ b/include/power/pmic.h @@ -1,5 +1,5 @@  /* - *  Copyright (C) 2011 Samsung Electronics + *  Copyright (C) 2011-2012 Samsung Electronics   *  Lukasz Majewski <l.majewski@samsung.com>   *   * See file CREDITS for list of people who contributed to this @@ -24,6 +24,10 @@  #ifndef __CORE_PMIC_H_  #define __CORE_PMIC_H_ +#include <common.h> +#include <linux/list.h> +#include <i2c.h> +  enum { PMIC_I2C, PMIC_SPI, };  enum { I2C_PMIC, I2C_NUM, };  enum { PMIC_READ, PMIC_WRITE, }; @@ -49,17 +53,20 @@ struct pmic {  	unsigned char bus;  	unsigned char interface;  	unsigned char sensor_byte_order; -	unsigned char number_of_regs; +	unsigned int number_of_regs;  	union hw {  		struct p_i2c i2c;  		struct p_spi spi;  	} hw; + +	struct list_head list;  }; -int pmic_init(void); -int pmic_dialog_init(void); -int check_reg(u32 reg); -struct pmic *get_pmic(void); +int pmic_init(unsigned char bus); +int pmic_dialog_init(unsigned char bus); +int check_reg(struct pmic *p, u32 reg); +struct pmic *pmic_alloc(void); +struct pmic *pmic_get(const char *s);  int pmic_probe(struct pmic *p);  int pmic_reg_read(struct pmic *p, u32 reg, u32 *val);  int pmic_reg_write(struct pmic *p, u32 reg, u32 val); |