commit
55e8250bd3
@ -1,363 +0,0 @@ |
||||
/*
|
||||
* Copyright (C) 2012 Samsung Electronics |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <cros_ec.h> |
||||
#include <fdtdec.h> |
||||
#include <asm/io.h> |
||||
#include <errno.h> |
||||
#include <i2c.h> |
||||
#include <lcd.h> |
||||
#include <netdev.h> |
||||
#include <spi.h> |
||||
#include <asm/arch/cpu.h> |
||||
#include <asm/arch/dwmmc.h> |
||||
#include <asm/arch/gpio.h> |
||||
#include <asm/arch/mmc.h> |
||||
#include <asm/arch/pinmux.h> |
||||
#include <asm/arch/power.h> |
||||
#include <asm/arch/sromc.h> |
||||
#include <asm/arch/dp_info.h> |
||||
#include <power/pmic.h> |
||||
#include <power/max77686_pmic.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#ifdef CONFIG_SOUND_MAX98095 |
||||
static void board_enable_audio_codec(void) |
||||
{ |
||||
/* Enable MAX98095 Codec */ |
||||
gpio_direction_output(EXYNOS5_GPIO_X17, 1); |
||||
gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE); |
||||
} |
||||
#endif |
||||
|
||||
int exynos_init(void) |
||||
{ |
||||
#ifdef CONFIG_SOUND_MAX98095 |
||||
board_enable_audio_codec(); |
||||
#endif |
||||
return 0; |
||||
} |
||||
|
||||
int board_eth_init(bd_t *bis) |
||||
{ |
||||
#ifdef CONFIG_SMC911X |
||||
u32 smc_bw_conf, smc_bc_conf; |
||||
struct fdt_sromc config; |
||||
fdt_addr_t base_addr; |
||||
|
||||
/* Non-FDT configuration - bank number and timing parameters*/ |
||||
config.bank = CONFIG_ENV_SROM_BANK; |
||||
config.width = 2; |
||||
|
||||
config.timing[FDT_SROM_TACS] = 0x01; |
||||
config.timing[FDT_SROM_TCOS] = 0x01; |
||||
config.timing[FDT_SROM_TACC] = 0x06; |
||||
config.timing[FDT_SROM_TCOH] = 0x01; |
||||
config.timing[FDT_SROM_TAH] = 0x0C; |
||||
config.timing[FDT_SROM_TACP] = 0x09; |
||||
config.timing[FDT_SROM_PMC] = 0x01; |
||||
base_addr = CONFIG_SMC911X_BASE; |
||||
|
||||
/* Ethernet needs data bus width of 16 bits */ |
||||
if (config.width != 2) { |
||||
debug("%s: Unsupported bus width %d\n", __func__, |
||||
config.width); |
||||
return -1; |
||||
} |
||||
smc_bw_conf = SROMC_DATA16_WIDTH(config.bank) |
||||
| SROMC_BYTE_ENABLE(config.bank); |
||||
|
||||
smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |\
|
||||
SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |\
|
||||
SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |\
|
||||
SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |\
|
||||
SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |\
|
||||
SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |\
|
||||
SROMC_BC_PMC(config.timing[FDT_SROM_PMC]); |
||||
|
||||
/* Select and configure the SROMC bank */ |
||||
exynos_pinmux_config(PERIPH_ID_SROMC, config.bank); |
||||
s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf); |
||||
return smc911x_initialize(0, base_addr); |
||||
#endif |
||||
return 0; |
||||
} |
||||
|
||||
#ifdef CONFIG_DISPLAY_BOARDINFO |
||||
int checkboard(void) |
||||
{ |
||||
printf("\nBoard: SMDK5250\n"); |
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
#ifdef CONFIG_GENERIC_MMC |
||||
int board_mmc_init(bd_t *bis) |
||||
{ |
||||
int err, ret = 0, index, bus_width; |
||||
u32 base; |
||||
|
||||
err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); |
||||
if (err) |
||||
debug("SDMMC0 not configured\n"); |
||||
ret |= err; |
||||
|
||||
/*EMMC: dwmmc Channel-0 with 8 bit bus width */ |
||||
index = 0; |
||||
base = samsung_get_base_mmc() + (0x10000 * index); |
||||
bus_width = 8; |
||||
err = exynos_dwmci_add_port(index, base, bus_width, (u32)NULL); |
||||
if (err) |
||||
debug("dwmmc Channel-0 init failed\n"); |
||||
ret |= err; |
||||
|
||||
err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); |
||||
if (err) |
||||
debug("SDMMC2 not configured\n"); |
||||
ret |= err; |
||||
|
||||
/*SD: dwmmc Channel-2 with 4 bit bus width */ |
||||
index = 2; |
||||
base = samsung_get_base_mmc() + (0x10000 * index); |
||||
bus_width = 4; |
||||
err = exynos_dwmci_add_port(index, base, bus_width, (u32)NULL); |
||||
if (err) |
||||
debug("dwmmc Channel-2 init failed\n"); |
||||
ret |= err; |
||||
|
||||
return ret; |
||||
} |
||||
#endif |
||||
|
||||
void board_i2c_init(const void *blob) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) { |
||||
exynos_pinmux_config((PERIPH_ID_I2C0 + i), |
||||
PINMUX_FLAG_NONE); |
||||
} |
||||
} |
||||
|
||||
#if defined(CONFIG_POWER) |
||||
#ifdef CONFIG_POWER_MAX77686 |
||||
static int pmic_reg_update(struct pmic *p, int reg, uint regval) |
||||
{ |
||||
u32 val; |
||||
int ret = 0; |
||||
|
||||
ret = pmic_reg_read(p, reg, &val); |
||||
if (ret) { |
||||
debug("%s: PMIC %d register read failed\n", __func__, reg); |
||||
return -1; |
||||
} |
||||
val |= regval; |
||||
ret = pmic_reg_write(p, reg, val); |
||||
if (ret) { |
||||
debug("%s: PMIC %d register write failed\n", __func__, reg); |
||||
return -1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static int max77686_init(void) |
||||
{ |
||||
struct pmic *p; |
||||
|
||||
if (pmic_init(I2C_PMIC)) |
||||
return -1; |
||||
|
||||
p = pmic_get("MAX77686_PMIC"); |
||||
if (!p) |
||||
return -ENODEV; |
||||
|
||||
if (pmic_probe(p)) |
||||
return -1; |
||||
|
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN)) |
||||
return -1; |
||||
|
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT, |
||||
MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V)) |
||||
return -1; |
||||
|
||||
/* VDD_MIF */ |
||||
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT, |
||||
MAX77686_BUCK1OUT_1V)) { |
||||
debug("%s: PMIC %d register write failed\n", __func__, |
||||
MAX77686_REG_PMIC_BUCK1OUT); |
||||
return -1; |
||||
} |
||||
|
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL, |
||||
MAX77686_BUCK1CTRL_EN)) |
||||
return -1; |
||||
|
||||
/* VDD_ARM */ |
||||
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1, |
||||
MAX77686_BUCK2DVS1_1_3V)) { |
||||
debug("%s: PMIC %d register write failed\n", __func__, |
||||
MAX77686_REG_PMIC_BUCK2DVS1); |
||||
return -1; |
||||
} |
||||
|
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1, |
||||
MAX77686_BUCK2CTRL_ON)) |
||||
return -1; |
||||
|
||||
/* VDD_INT */ |
||||
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1, |
||||
MAX77686_BUCK3DVS1_1_0125V)) { |
||||
debug("%s: PMIC %d register write failed\n", __func__, |
||||
MAX77686_REG_PMIC_BUCK3DVS1); |
||||
return -1; |
||||
} |
||||
|
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL, |
||||
MAX77686_BUCK3CTRL_ON)) |
||||
return -1; |
||||
|
||||
/* VDD_G3D */ |
||||
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1, |
||||
MAX77686_BUCK4DVS1_1_2V)) { |
||||
debug("%s: PMIC %d register write failed\n", __func__, |
||||
MAX77686_REG_PMIC_BUCK4DVS1); |
||||
return -1; |
||||
} |
||||
|
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1, |
||||
MAX77686_BUCK3CTRL_ON)) |
||||
return -1; |
||||
|
||||
/* VDD_LDO2 */ |
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1, |
||||
MAX77686_LD02CTRL1_1_5V | EN_LDO)) |
||||
return -1; |
||||
|
||||
/* VDD_LDO3 */ |
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1, |
||||
MAX77686_LD03CTRL1_1_8V | EN_LDO)) |
||||
return -1; |
||||
|
||||
/* VDD_LDO5 */ |
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1, |
||||
MAX77686_LD05CTRL1_1_8V | EN_LDO)) |
||||
return -1; |
||||
|
||||
/* VDD_LDO10 */ |
||||
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1, |
||||
MAX77686_LD10CTRL1_1_8V | EN_LDO)) |
||||
return -1; |
||||
|
||||
return 0; |
||||
} |
||||
#endif /* CONFIG_POWER_MAX77686 */ |
||||
|
||||
int exynos_power_init(void) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
#ifdef CONFIG_POWER_MAX77686 |
||||
ret = max77686_init(); |
||||
#endif |
||||
return ret; |
||||
} |
||||
#endif /* CONFIG_POWER */ |
||||
|
||||
#ifdef CONFIG_LCD |
||||
void exynos_cfg_lcd_gpio(void) |
||||
{ |
||||
|
||||
/* For Backlight */ |
||||
gpio_cfg_pin(EXYNOS5_GPIO_B20, S5P_GPIO_OUTPUT); |
||||
gpio_set_value(EXYNOS5_GPIO_B20, 1); |
||||
|
||||
/* LCD power on */ |
||||
gpio_cfg_pin(EXYNOS5_GPIO_X15, S5P_GPIO_OUTPUT); |
||||
gpio_set_value(EXYNOS5_GPIO_X15, 1); |
||||
|
||||
/* Set Hotplug detect for DP */ |
||||
gpio_cfg_pin(EXYNOS5_GPIO_X07, S5P_GPIO_FUNC(0x3)); |
||||
} |
||||
|
||||
void exynos_set_dp_phy(unsigned int onoff) |
||||
{ |
||||
set_dp_phy_ctrl(onoff); |
||||
} |
||||
|
||||
vidinfo_t panel_info = { |
||||
.vl_freq = 60, |
||||
.vl_col = 2560, |
||||
.vl_row = 1600, |
||||
.vl_width = 2560, |
||||
.vl_height = 1600, |
||||
.vl_clkp = CONFIG_SYS_LOW, |
||||
.vl_hsp = CONFIG_SYS_LOW, |
||||
.vl_vsp = CONFIG_SYS_LOW, |
||||
.vl_dp = CONFIG_SYS_LOW, |
||||
.vl_bpix = 4, /* LCD_BPP = 2^4, for output conosle on LCD */ |
||||
|
||||
/* wDP panel timing infomation */ |
||||
.vl_hspw = 32, |
||||
.vl_hbpd = 80, |
||||
.vl_hfpd = 48, |
||||
|
||||
.vl_vspw = 6, |
||||
.vl_vbpd = 37, |
||||
.vl_vfpd = 3, |
||||
.vl_cmd_allow_len = 0xf, |
||||
|
||||
.win_id = 3, |
||||
.dual_lcd_enabled = 0, |
||||
|
||||
.init_delay = 0, |
||||
.power_on_delay = 0, |
||||
.reset_delay = 0, |
||||
.interface_mode = FIMD_RGB_INTERFACE, |
||||
.dp_enabled = 1, |
||||
}; |
||||
|
||||
static struct edp_device_info edp_info = { |
||||
.disp_info = { |
||||
.h_res = 2560, |
||||
.h_sync_width = 32, |
||||
.h_back_porch = 80, |
||||
.h_front_porch = 48, |
||||
.v_res = 1600, |
||||
.v_sync_width = 6, |
||||
.v_back_porch = 37, |
||||
.v_front_porch = 3, |
||||
.v_sync_rate = 60, |
||||
}, |
||||
.lt_info = { |
||||
.lt_status = DP_LT_NONE, |
||||
}, |
||||
.video_info = { |
||||
.master_mode = 0, |
||||
.bist_mode = DP_DISABLE, |
||||
.bist_pattern = NO_PATTERN, |
||||
.h_sync_polarity = 0, |
||||
.v_sync_polarity = 0, |
||||
.interlaced = 0, |
||||
.color_space = COLOR_RGB, |
||||
.dynamic_range = VESA, |
||||
.ycbcr_coeff = COLOR_YCBCR601, |
||||
.color_depth = COLOR_8, |
||||
}, |
||||
}; |
||||
|
||||
static struct exynos_dp_platform_data dp_platform_data = { |
||||
.edp_dev_info = &edp_info, |
||||
}; |
||||
|
||||
void init_panel_info(vidinfo_t *vid) |
||||
{ |
||||
vid->rgb_mode = MODE_RGB_P; |
||||
exynos_set_dp_platform_data(&dp_platform_data); |
||||
} |
||||
#endif |
@ -0,0 +1,17 @@ |
||||
TPS65090 Frontend PMU with Switchmode Charger |
||||
|
||||
Required Properties: |
||||
-compatible: "ti,tps65090-charger" |
||||
|
||||
Optional Properties: |
||||
-ti,enable-low-current-chrg: Enables charging when a low current is detected |
||||
while the default logic is to stop charging. |
||||
|
||||
This node is a subnode of the tps65090 PMIC. |
||||
|
||||
Example: |
||||
|
||||
tps65090-charger { |
||||
compatible = "ti,tps65090-charger"; |
||||
ti,enable-low-current-chrg; |
||||
}; |
@ -0,0 +1,122 @@ |
||||
TPS65090 regulators |
||||
|
||||
Required properties: |
||||
- compatible: "ti,tps65090" |
||||
- reg: I2C slave address |
||||
- interrupts: the interrupt outputs of the controller |
||||
- regulators: A node that houses a sub-node for each regulator within the |
||||
device. Each sub-node is identified using the node's name, with valid |
||||
values listed below. The content of each sub-node is defined by the |
||||
standard binding for regulators; see regulator.txt. |
||||
dcdc[1-3], fet[1-7] and ldo[1-2] respectively. |
||||
- vsys[1-3]-supply: The input supply for DCDC[1-3] respectively. |
||||
- infet[1-7]-supply: The input supply for FET[1-7] respectively. |
||||
- vsys-l[1-2]-supply: The input supply for LDO[1-2] respectively. |
||||
|
||||
Optional properties: |
||||
- ti,enable-ext-control: This is applicable for DCDC1, DCDC2 and DCDC3. |
||||
If DCDCs are externally controlled then this property should be there. |
||||
- "dcdc-ext-control-gpios: This is applicable for DCDC1, DCDC2 and DCDC3. |
||||
If DCDCs are externally controlled and if it is from GPIO then GPIO |
||||
number should be provided. If it is externally controlled and no GPIO |
||||
entry then driver will just configure this rails as external control |
||||
and will not provide any enable/disable APIs. |
||||
|
||||
Each regulator is defined using the standard binding for regulators. |
||||
|
||||
Example: |
||||
|
||||
tps65090@48 { |
||||
compatible = "ti,tps65090"; |
||||
reg = <0x48>; |
||||
interrupts = <0 88 0x4>; |
||||
|
||||
vsys1-supply = <&some_reg>; |
||||
vsys2-supply = <&some_reg>; |
||||
vsys3-supply = <&some_reg>; |
||||
infet1-supply = <&some_reg>; |
||||
infet2-supply = <&some_reg>; |
||||
infet3-supply = <&some_reg>; |
||||
infet4-supply = <&some_reg>; |
||||
infet5-supply = <&some_reg>; |
||||
infet6-supply = <&some_reg>; |
||||
infet7-supply = <&some_reg>; |
||||
vsys_l1-supply = <&some_reg>; |
||||
vsys_l2-supply = <&some_reg>; |
||||
|
||||
regulators { |
||||
dcdc1 { |
||||
regulator-name = "dcdc1"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
ti,enable-ext-control; |
||||
dcdc-ext-control-gpios = <&gpio 10 0>; |
||||
}; |
||||
|
||||
dcdc2 { |
||||
regulator-name = "dcdc2"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
dcdc3 { |
||||
regulator-name = "dcdc3"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
fet1 { |
||||
regulator-name = "fet1"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
fet2 { |
||||
regulator-name = "fet2"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
fet3 { |
||||
regulator-name = "fet3"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
fet4 { |
||||
regulator-name = "fet4"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
fet5 { |
||||
regulator-name = "fet5"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
fet6 { |
||||
regulator-name = "fet6"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
fet7 { |
||||
regulator-name = "fet7"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
ldo1 { |
||||
regulator-name = "ldo1"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
|
||||
ldo2 { |
||||
regulator-name = "ldo2"; |
||||
regulator-boot-on; |
||||
regulator-always-on; |
||||
}; |
||||
}; |
||||
}; |
@ -0,0 +1,310 @@ |
||||
/*
|
||||
* Copyright (c) 2012 The Chromium OS Authors. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <errno.h> |
||||
#include <fdtdec.h> |
||||
#include <i2c.h> |
||||
#include <power/pmic.h> |
||||
#include <power/tps65090_pmic.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#define TPS65090_NAME "TPS65090_PMIC" |
||||
|
||||
/* TPS65090 register addresses */ |
||||
enum { |
||||
REG_IRQ1 = 0, |
||||
REG_CG_CTRL0 = 4, |
||||
REG_CG_STATUS1 = 0xa, |
||||
REG_FET1_CTRL = 0x0f, |
||||
REG_FET2_CTRL, |
||||
REG_FET3_CTRL, |
||||
REG_FET4_CTRL, |
||||
REG_FET5_CTRL, |
||||
REG_FET6_CTRL, |
||||
REG_FET7_CTRL, |
||||
TPS65090_NUM_REGS, |
||||
}; |
||||
|
||||
enum { |
||||
IRQ1_VBATG = 1 << 3, |
||||
CG_CTRL0_ENC_MASK = 0x01, |
||||
|
||||
MAX_FET_NUM = 7, |
||||
MAX_CTRL_READ_TRIES = 5, |
||||
|
||||
/* TPS65090 FET_CTRL register values */ |
||||
FET_CTRL_TOFET = 1 << 7, /* Timeout, startup, overload */ |
||||
FET_CTRL_PGFET = 1 << 4, /* Power good for FET status */ |
||||
FET_CTRL_WAIT = 3 << 2, /* Overcurrent timeout max */ |
||||
FET_CTRL_ADENFET = 1 << 1, /* Enable output auto discharge */ |
||||
FET_CTRL_ENFET = 1 << 0, /* Enable FET */ |
||||
}; |
||||
|
||||
/**
|
||||
* Checks for a valid FET number |
||||
* |
||||
* @param fet_id FET number to check |
||||
* @return 0 if ok, -EINVAL if FET value is out of range |
||||
*/ |
||||
static int tps65090_check_fet(unsigned int fet_id) |
||||
{ |
||||
if (fet_id == 0 || fet_id > MAX_FET_NUM) { |
||||
debug("parameter fet_id is out of range, %u not in 1 ~ %u\n", |
||||
fet_id, MAX_FET_NUM); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* Set the power state for a FET |
||||
* |
||||
* @param pmic pmic structure for the tps65090 |
||||
* @param fet_id Fet number to set (1..MAX_FET_NUM) |
||||
* @param set 1 to power on FET, 0 to power off |
||||
* @return -EIO if we got a comms error, -EAGAIN if the FET failed to |
||||
* change state. If all is ok, returns 0. |
||||
*/ |
||||
static int tps65090_fet_set(struct pmic *pmic, int fet_id, bool set) |
||||
{ |
||||
int retry; |
||||
u32 reg, value; |
||||
|
||||
value = FET_CTRL_ADENFET | FET_CTRL_WAIT; |
||||
if (set) |
||||
value |= FET_CTRL_ENFET; |
||||
|
||||
if (pmic_reg_write(pmic, REG_FET1_CTRL + fet_id - 1, value)) |
||||
return -EIO; |
||||
|
||||
/* Try reading until we get a result */ |
||||
for (retry = 0; retry < MAX_CTRL_READ_TRIES; retry++) { |
||||
if (pmic_reg_read(pmic, REG_FET1_CTRL + fet_id - 1, ®)) |
||||
return -EIO; |
||||
|
||||
/* Check that the fet went into the expected state */ |
||||
if (!!(reg & FET_CTRL_PGFET) == set) |
||||
return 0; |
||||
|
||||
/* If we got a timeout, there is no point in waiting longer */ |
||||
if (reg & FET_CTRL_TOFET) |
||||
break; |
||||
|
||||
mdelay(1); |
||||
} |
||||
|
||||
debug("FET %d: Power good should have set to %d but reg=%#02x\n", |
||||
fet_id, set, reg); |
||||
return -EAGAIN; |
||||
} |
||||
|
||||
int tps65090_fet_enable(unsigned int fet_id) |
||||
{ |
||||
struct pmic *pmic; |
||||
ulong start; |
||||
int loops; |
||||
int ret; |
||||
|
||||
ret = tps65090_check_fet(fet_id); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
pmic = pmic_get(TPS65090_NAME); |
||||
if (!pmic) |
||||
return -EACCES; |
||||
|
||||
start = get_timer(0); |
||||
for (loops = 0;; loops++) { |
||||
ret = tps65090_fet_set(pmic, fet_id, true); |
||||
if (!ret) |
||||
break; |
||||
|
||||
if (get_timer(start) > 100) |
||||
break; |
||||
|
||||
/* Turn it off and try again until we time out */ |
||||
tps65090_fet_set(pmic, fet_id, false); |
||||
} |
||||
|
||||
if (ret) |
||||
debug("%s: FET%d failed to power on: time=%lums, loops=%d\n", |
||||
__func__, fet_id, get_timer(start), loops); |
||||
else if (loops) |
||||
debug("%s: FET%d powered on after %lums, loops=%d\n", |
||||
__func__, fet_id, get_timer(start), loops); |
||||
|
||||
/*
|
||||
* Unfortunately, there are some conditions where the power |
||||
* good bit will be 0, but the fet still comes up. One such |
||||
* case occurs with the lcd backlight. We'll just return 0 here |
||||
* and assume that the fet will eventually come up. |
||||
*/ |
||||
if (ret == -EAGAIN) |
||||
ret = 0; |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
int tps65090_fet_disable(unsigned int fet_id) |
||||
{ |
||||
struct pmic *pmic; |
||||
int ret; |
||||
|
||||
ret = tps65090_check_fet(fet_id); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
pmic = pmic_get(TPS65090_NAME); |
||||
if (!pmic) |
||||
return -EACCES; |
||||
ret = tps65090_fet_set(pmic, fet_id, false); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
int tps65090_fet_is_enabled(unsigned int fet_id) |
||||
{ |
||||
struct pmic *pmic; |
||||
u32 reg; |
||||
int ret; |
||||
|
||||
ret = tps65090_check_fet(fet_id); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
pmic = pmic_get(TPS65090_NAME); |
||||
if (!pmic) |
||||
return -ENODEV; |
||||
ret = pmic_reg_read(pmic, REG_FET1_CTRL + fet_id - 1, ®); |
||||
if (ret) { |
||||
debug("fail to read FET%u_CTRL register over I2C", fet_id); |
||||
return -EIO; |
||||
} |
||||
|
||||
return reg & FET_CTRL_ENFET; |
||||
} |
||||
|
||||
int tps65090_get_charging(void) |
||||
{ |
||||
struct pmic *pmic; |
||||
u32 val; |
||||
int ret; |
||||
|
||||
pmic = pmic_get(TPS65090_NAME); |
||||
if (!pmic) |
||||
return -EACCES; |
||||
|
||||
ret = pmic_reg_read(pmic, REG_CG_CTRL0, &val); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
return !!(val & CG_CTRL0_ENC_MASK); |
||||
} |
||||
|
||||
static int tps65090_charger_state(struct pmic *pmic, int state, |
||||
int current) |
||||
{ |
||||
u32 val; |
||||
int ret; |
||||
|
||||
ret = pmic_reg_read(pmic, REG_CG_CTRL0, &val); |
||||
if (!ret) { |
||||
if (state == PMIC_CHARGER_ENABLE) |
||||
val |= CG_CTRL0_ENC_MASK; |
||||
else |
||||
val &= ~CG_CTRL0_ENC_MASK; |
||||
ret = pmic_reg_write(pmic, REG_CG_CTRL0, val); |
||||
} |
||||
if (ret) { |
||||
debug("%s: Failed to read/write register\n", __func__); |
||||
return ret; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int tps65090_get_status(void) |
||||
{ |
||||
struct pmic *pmic; |
||||
u32 val; |
||||
int ret; |
||||
|
||||
pmic = pmic_get(TPS65090_NAME); |
||||
if (!pmic) |
||||
return -EACCES; |
||||
|
||||
ret = pmic_reg_read(pmic, REG_CG_STATUS1, &val); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
return val; |
||||
} |
||||
|
||||
static int tps65090_charger_bat_present(struct pmic *pmic) |
||||
{ |
||||
u32 val; |
||||
int ret; |
||||
|
||||
ret = pmic_reg_read(pmic, REG_IRQ1, &val); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
return !!(val & IRQ1_VBATG); |
||||
} |
||||
|
||||
static struct power_chrg power_chrg_pmic_ops = { |
||||
.chrg_bat_present = tps65090_charger_bat_present, |
||||
.chrg_state = tps65090_charger_state, |
||||
}; |
||||
|
||||
int tps65090_init(void) |
||||
{ |
||||
struct pmic *p; |
||||
int bus; |
||||
int addr; |
||||
const void *blob = gd->fdt_blob; |
||||
int node, parent; |
||||
|
||||
node = fdtdec_next_compatible(blob, 0, COMPAT_TI_TPS65090); |
||||
if (node < 0) { |
||||
debug("PMIC: No node for PMIC Chip in device tree\n"); |
||||
debug("node = %d\n", node); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
parent = fdt_parent_offset(blob, node); |
||||
if (parent < 0) { |
||||
debug("%s: Cannot find node parent\n", __func__); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
bus = i2c_get_bus_num_fdt(parent); |
||||
if (p->bus < 0) { |
||||
debug("%s: Cannot find I2C bus\n", __func__); |
||||
return -ENOENT; |
||||
} |
||||
addr = fdtdec_get_int(blob, node, "reg", TPS65090_I2C_ADDR); |
||||
p = pmic_alloc(); |
||||
if (!p) { |
||||
printf("%s: POWER allocation error!\n", __func__); |
||||
return -ENOMEM; |
||||
} |
||||
|
||||
p->name = TPS65090_NAME; |
||||
p->bus = bus; |
||||
p->interface = PMIC_I2C; |
||||
p->number_of_regs = TPS65090_NUM_REGS; |
||||
p->hw.i2c.addr = addr; |
||||
p->hw.i2c.tx_num = 1; |
||||
p->chrg = &power_chrg_pmic_ops; |
||||
|
||||
puts("TPS65090 PMIC init\n"); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,97 @@ |
||||
/*
|
||||
* (C) Copyright 2011-2013 |
||||
* Texas Instruments, <www.ti.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <i2c.h> |
||||
#include <power/tps65218.h> |
||||
|
||||
/**
|
||||
* tps65218_reg_write() - Generic function that can write a TPS65218 PMIC |
||||
* register or bit field regardless of protection |
||||
* level. |
||||
* |
||||
* @prot_level: Register password protection. Use |
||||
* TPS65218_PROT_LEVEL_NONE, |
||||
* TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2 |
||||
* @dest_reg: Register address to write. |
||||
* @dest_val: Value to write. |
||||
* @mask: Bit mask (8 bits) to be applied. Function will only |
||||
* change bits that are set in the bit mask. |
||||
* |
||||
* @return: 0 for success, not 0 on failure, as per the i2c API |
||||
*/ |
||||
int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val, |
||||
uchar mask) |
||||
{ |
||||
uchar read_val; |
||||
uchar xor_reg; |
||||
int ret; |
||||
|
||||
/*
|
||||
* If we are affecting only a bit field, read dest_reg and apply the |
||||
* mask |
||||
*/ |
||||
if (mask != TPS65218_MASK_ALL_BITS) { |
||||
ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1); |
||||
if (ret) |
||||
return ret; |
||||
read_val &= (~mask); |
||||
read_val |= (dest_val & mask); |
||||
dest_val = read_val; |
||||
} |
||||
|
||||
if (prot_level > 0) { |
||||
xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK; |
||||
ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, |
||||
&xor_reg, 1); |
||||
if (ret) |
||||
return ret; |
||||
} |
||||
|
||||
ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
if (prot_level == TPS65218_PROT_LEVEL_2) { |
||||
ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1, |
||||
&xor_reg, 1); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1); |
||||
if (ret) |
||||
return ret; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* tps65218_voltage_update() - Function to change a voltage level, as this |
||||
* is a multi-step process. |
||||
* @dc_cntrl_reg: DC voltage control register to change. |
||||
* @volt_sel: New value for the voltage register |
||||
* @return: 0 for success, not 0 on failure. |
||||
*/ |
||||
int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel) |
||||
{ |
||||
if ((dc_cntrl_reg != TPS65218_DCDC1) && |
||||
(dc_cntrl_reg != TPS65218_DCDC2)) |
||||
return 1; |
||||
|
||||
/* set voltage level */ |
||||
if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel, |
||||
TPS65218_MASK_ALL_BITS)) |
||||
return 1; |
||||
|
||||
/* set GO bit to initiate voltage transition */ |
||||
if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW, |
||||
TPS65218_DCDC_GO, TPS65218_DCDC_GO)) |
||||
return 1; |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,26 @@ |
||||
/*
|
||||
* (C) Copyright 2014 |
||||
* NVIDIA Corporation <www.nvidia.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0 |
||||
*/ |
||||
|
||||
#ifndef _TEGRA_COMMON_UMS_H_ |
||||
#define _TEGRA_COMMON_UMS_H |
||||
|
||||
#ifndef CONFIG_SPL_BUILD |
||||
/* USB gadget, and mass storage protocol */ |
||||
#define CONFIG_USB_GADGET |
||||
#define CONFIG_USB_GADGET_VBUS_DRAW 2 |
||||
#define CONFIG_CI_UDC |
||||
#define CONFIG_CI_UDC_HAS_HOSTPC |
||||
#define CONFIG_USB_GADGET_DUALSPEED |
||||
#define CONFIG_G_DNL_VENDOR_NUM 0x0955 |
||||
#define CONFIG_G_DNL_PRODUCT_NUM 0x701A |
||||
#define CONFIG_G_DNL_MANUFACTURER "NVIDIA" |
||||
#define CONFIG_USBDOWNLOAD_GADGET |
||||
#define CONFIG_USB_GADGET_MASS_STORAGE |
||||
#define CONFIG_CMD_USB_MASS_STORAGE |
||||
#endif |
||||
|
||||
#endif /* _TEGRA_COMMON_UMS_H */ |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue