xref: /rk3399_rockchip-uboot/drivers/video/rk_eink/tps65185.c (revision 39c952ae4eb8487bdc81b558bae44a2d9ccd07d1)
193a7515aSWenping Zhang /*
293a7515aSWenping Zhang  * (C) Copyright 2020 Rockchip Electronics Co., Ltd
393a7515aSWenping Zhang  *
493a7515aSWenping Zhang  * SPDX-License-Identifier:     GPL-2.0+
593a7515aSWenping Zhang  */
693a7515aSWenping Zhang 
793a7515aSWenping Zhang #include <common.h>
893a7515aSWenping Zhang #include <dm.h>
993a7515aSWenping Zhang #include <i2c.h>
1093a7515aSWenping Zhang #include <asm/gpio.h>
1193a7515aSWenping Zhang #include "rk_ebc.h"
1293a7515aSWenping Zhang 
1393a7515aSWenping Zhang #define msleep(a)		udelay((a) * 1000)
1493a7515aSWenping Zhang 
1593a7515aSWenping Zhang struct tps65185_priv_data {
1693a7515aSWenping Zhang 	struct udevice *dev;
1793a7515aSWenping Zhang 	struct gpio_desc pwr_up_gpio;
18*39c952aeSWeixin Zhou 	struct gpio_desc pwr_en_gpio;
1993a7515aSWenping Zhang 	struct gpio_desc vcom_gpio;
2093a7515aSWenping Zhang 	struct gpio_desc wake_up_gpio;
2193a7515aSWenping Zhang 	u8 rev_id;
2293a7515aSWenping Zhang 	u8 vadj;
2393a7515aSWenping Zhang 	u8 vcom1;
2493a7515aSWenping Zhang 	u8 vcom2;
2593a7515aSWenping Zhang 	u8 upseq0;
2693a7515aSWenping Zhang 	u8 upseq1;
2793a7515aSWenping Zhang 	u8 dwnseq0;
2893a7515aSWenping Zhang 	u8 dwnseq1;
2993a7515aSWenping Zhang 	u8 shadow_en;
3093a7515aSWenping Zhang };
3193a7515aSWenping Zhang 
3293a7515aSWenping Zhang #define REG_TMST_VALUE		0x00
3393a7515aSWenping Zhang #define REG_ENABLE		0x01
3493a7515aSWenping Zhang #define REG_VADJ		0x02
3593a7515aSWenping Zhang #define REG_VCOM1_ADJUST	0x03
3693a7515aSWenping Zhang #define REG_VCOM2_ADJUST	0x04
3793a7515aSWenping Zhang #define REG_INT_ENABLE1		0x05
3893a7515aSWenping Zhang #define REG_INT_ENABLE2		0x06
3993a7515aSWenping Zhang #define REG_INT_STATUS1		0x07
4093a7515aSWenping Zhang #define REG_INT_STATUS2		0x08
4193a7515aSWenping Zhang #define REG_UPSEQ0		0x09
4293a7515aSWenping Zhang #define REG_UPSEQ1		0x0a
4393a7515aSWenping Zhang #define REG_DWNSEQ0		0x0b
4493a7515aSWenping Zhang #define REG_DWNSEQ1		0x0c
4593a7515aSWenping Zhang #define REG_TMST1		0x0d
4693a7515aSWenping Zhang #define REG_TMST2		0x0e
4793a7515aSWenping Zhang #define REG_PG_STATUS		0x0f
4893a7515aSWenping Zhang #define REG_REVID		0x10
4993a7515aSWenping Zhang #define mv_to_vcom1_reg(mv)	(((mv) / 10) & 0xff)
5093a7515aSWenping Zhang #define mv_to_vcom2_reg(mv)	((((mv) / 10) & 0x100) >> 8)
5193a7515aSWenping Zhang 
5293a7515aSWenping Zhang /*
5393a7515aSWenping Zhang  * After waking up from sleep, Papyrus
5493a7515aSWenping Zhang  * waits for VN to be discharged and all
5593a7515aSWenping Zhang  * voltage ref to startup before loading
5693a7515aSWenping Zhang  * the default EEPROM settings. So accessing
5793a7515aSWenping Zhang  * registers too early after WAKEUP could
5893a7515aSWenping Zhang  * cause the register to be overridden by
5993a7515aSWenping Zhang  * default values
6093a7515aSWenping Zhang  */
6193a7515aSWenping Zhang #define PAPYRUS_EEPROM_DELAY_MS 50
6293a7515aSWenping Zhang /*
6393a7515aSWenping Zhang  * Papyrus WAKEUP pin must stay low for
6493a7515aSWenping Zhang  * a minimum time
6593a7515aSWenping Zhang  */
6693a7515aSWenping Zhang #define PAPYRUS_SLEEP_MINIMUM_MS 110
6793a7515aSWenping Zhang /*
6893a7515aSWenping Zhang  * Temp sensor might take a little time to
6993a7515aSWenping Zhang  * settle even though the status bit in TMST1
7093a7515aSWenping Zhang  * state conversion is done - if read too early
7193a7515aSWenping Zhang  * 0C will be returned instead of the right temp
7293a7515aSWenping Zhang  */
7393a7515aSWenping Zhang #define PAPYRUS_TEMP_READ_TIME_MS 10
7493a7515aSWenping Zhang 
7593a7515aSWenping Zhang /*
7693a7515aSWenping Zhang  * Powerup sequence takes at least 24 ms
7793a7515aSWenping Zhang  * - no need to poll too frequently
7893a7515aSWenping Zhang  */
7993a7515aSWenping Zhang #define HW_GET_STATE_INTERVAL_MS 24
8093a7515aSWenping Zhang 
8193a7515aSWenping Zhang #define SEQ_VDD(index)	(((index) % 4) << 6)
8293a7515aSWenping Zhang #define SEQ_VPOS(index)	(((index) % 4) << 4)
8393a7515aSWenping Zhang #define SEQ_VEE(index)	(((index) % 4) << 2)
8493a7515aSWenping Zhang #define SEQ_VNEG(index)	(((index) % 4) << 0)
8593a7515aSWenping Zhang 
8693a7515aSWenping Zhang /* power up seq delay time */
8793a7515aSWenping Zhang #define UDLY_3ms(index)		(0x00 << (((index) % 4) * 2))
8893a7515aSWenping Zhang #define UDLY_6ms(index)		(0x01 << (((index) % 4) * 2))
8993a7515aSWenping Zhang #define UDLY_9ms(index)		(0x10 << (((index) % 4) * 2))
9093a7515aSWenping Zhang #define UDLY_12ms(index)	(0x11 << (((index) % 4) * 2))
9193a7515aSWenping Zhang 
9293a7515aSWenping Zhang /* power down seq delay time */
9393a7515aSWenping Zhang #define DDLY_6ms(index)		(0x00 << (((index) % 4) * 2))
9493a7515aSWenping Zhang #define DDLY_12ms(index)	(0x01 << (((index) % 4) * 2))
9593a7515aSWenping Zhang #define DDLY_24ms(index)	(0x10 << (((index) % 4) * 2))
9693a7515aSWenping Zhang #define DDLY_48ms(index)	(0x11 << (((index) % 4) * 2))
9793a7515aSWenping Zhang 
9893a7515aSWenping Zhang #define NUMBER_PMIC_REGS		10
9993a7515aSWenping Zhang // INT_ENABLE1
10093a7515aSWenping Zhang #define PAPYRUS_INT_ENABLE1_ACQC_EN	1
10193a7515aSWenping Zhang #define PAPYRUS_INT_ENABLE1_PRGC_EN	0
10293a7515aSWenping Zhang 
10393a7515aSWenping Zhang // INT_STATUS1
10493a7515aSWenping Zhang #define PAPYRUS_INT_STATUS1_ACQC	1
10593a7515aSWenping Zhang #define PAPYRUS_INT_STATUS1_PRGC	0
10693a7515aSWenping Zhang 
10793a7515aSWenping Zhang // VCOM2_ADJUST
10893a7515aSWenping Zhang #define PAPYRUS_VCOM2_ACQ		7
10993a7515aSWenping Zhang #define PAPYRUS_VCOM2_PROG		6
11093a7515aSWenping Zhang #define PAPYRUS_VCOM2_HIZ		5
11193a7515aSWenping Zhang #define V3P3_EN_MASK			0x20
11293a7515aSWenping Zhang 
11393a7515aSWenping Zhang #define PAPYRUS_V3P3OFF_DELAY_MS	20//100
11493a7515aSWenping Zhang 
11593a7515aSWenping Zhang static struct udevice *pmic_dev;
11693a7515aSWenping Zhang 
tps65185_i2c_write(struct tps65185_priv_data * priv_data,u8 reg,u8 val)11793a7515aSWenping Zhang int tps65185_i2c_write(struct tps65185_priv_data *priv_data, u8 reg, u8 val)
11893a7515aSWenping Zhang {
11993a7515aSWenping Zhang 	int ret;
12093a7515aSWenping Zhang 	u8 buf[2];
12193a7515aSWenping Zhang 	struct i2c_msg msg;
12293a7515aSWenping Zhang 	struct dm_i2c_chip *chip = dev_get_parent_platdata(priv_data->dev);
12393a7515aSWenping Zhang 
12493a7515aSWenping Zhang 	buf[0] = reg;
12593a7515aSWenping Zhang 	buf[1] = val;
12693a7515aSWenping Zhang 	msg.addr = chip->chip_addr;
12793a7515aSWenping Zhang 	msg.flags = 0;
12893a7515aSWenping Zhang 	msg.len = 2;
12993a7515aSWenping Zhang 	msg.buf = buf;
13093a7515aSWenping Zhang 
13193a7515aSWenping Zhang 	ret = dm_i2c_xfer(priv_data->dev, &msg, 1);
13293a7515aSWenping Zhang 	if (ret) {
13393a7515aSWenping Zhang 		printf("tps65185 i2c write failed: %d\n", ret);
13493a7515aSWenping Zhang 		return ret;
13593a7515aSWenping Zhang 	}
13693a7515aSWenping Zhang 
13793a7515aSWenping Zhang 	return 0;
13893a7515aSWenping Zhang }
13993a7515aSWenping Zhang 
tps65185_i2c_read(struct tps65185_priv_data * priv_data,u8 reg,u8 * val)14093a7515aSWenping Zhang int tps65185_i2c_read(struct tps65185_priv_data *priv_data, u8 reg, u8 *val)
14193a7515aSWenping Zhang {
14293a7515aSWenping Zhang 	int ret;
14393a7515aSWenping Zhang 	u8 data;
14493a7515aSWenping Zhang 	struct dm_i2c_chip *chip = dev_get_parent_platdata(priv_data->dev);
14593a7515aSWenping Zhang 	struct i2c_msg msg[] = {
14693a7515aSWenping Zhang 		{
14793a7515aSWenping Zhang 			.addr = chip->chip_addr,
14893a7515aSWenping Zhang 			.flags = 0,
14993a7515aSWenping Zhang 			.buf = (u8 *)&reg,
15093a7515aSWenping Zhang 			.len = 1,
15193a7515aSWenping Zhang 		}, {
15293a7515aSWenping Zhang 			.addr = chip->chip_addr,
15393a7515aSWenping Zhang 			.flags = I2C_M_RD,
15493a7515aSWenping Zhang 			.buf = (u8 *)&data,
15593a7515aSWenping Zhang 			.len = 1,
15693a7515aSWenping Zhang 		}
15793a7515aSWenping Zhang 	};
15893a7515aSWenping Zhang 
15993a7515aSWenping Zhang 	ret = dm_i2c_xfer(priv_data->dev, msg, 2);
16093a7515aSWenping Zhang 	if (ret) {
16193a7515aSWenping Zhang 		printf("tps65185 i2c read failed: %d\n", ret);
16293a7515aSWenping Zhang 		return ret;
16393a7515aSWenping Zhang 	}
16493a7515aSWenping Zhang 
16593a7515aSWenping Zhang 	*val = data;
16693a7515aSWenping Zhang 
16793a7515aSWenping Zhang 	return 0;
16893a7515aSWenping Zhang }
16993a7515aSWenping Zhang 
tps65185_dump_registers(void)17093a7515aSWenping Zhang void tps65185_dump_registers(void)
17193a7515aSWenping Zhang {
17293a7515aSWenping Zhang 	u8 i, reg = 0;
17393a7515aSWenping Zhang 	struct tps65185_priv_data *priv_data = dev_get_priv(pmic_dev);
17493a7515aSWenping Zhang 
17593a7515aSWenping Zhang 	for (i = 0; i <= REG_REVID; i++) {
17693a7515aSWenping Zhang 		tps65185_i2c_read(priv_data, i, &reg);
17793a7515aSWenping Zhang 		printf("0x%x\t", reg);
17893a7515aSWenping Zhang 	}
17993a7515aSWenping Zhang 	printf("\n");
18093a7515aSWenping Zhang }
18193a7515aSWenping Zhang 
tps65185_read_vcom_value(struct tps65185_priv_data * priv_data,u32 * vcom_read)18293a7515aSWenping Zhang static int tps65185_read_vcom_value(struct tps65185_priv_data *priv_data,
18393a7515aSWenping Zhang 				    u32 *vcom_read)
18493a7515aSWenping Zhang {
18593a7515aSWenping Zhang 	int ret;
18693a7515aSWenping Zhang 	u8 vcom_reg;
18793a7515aSWenping Zhang 
18893a7515aSWenping Zhang 	dm_gpio_set_value(&priv_data->wake_up_gpio, 0);
18993a7515aSWenping Zhang 	msleep(10);
19093a7515aSWenping Zhang 	dm_gpio_set_value(&priv_data->wake_up_gpio, 1);
19193a7515aSWenping Zhang 	msleep(10);
19293a7515aSWenping Zhang 	ret = tps65185_i2c_read(priv_data, REG_VCOM1_ADJUST, &vcom_reg);
19393a7515aSWenping Zhang 	if (ret) {
19493a7515aSWenping Zhang 		printf("read vcom failed: %d\n", ret);
19593a7515aSWenping Zhang 		return ret;
19693a7515aSWenping Zhang 	}
19793a7515aSWenping Zhang 	*vcom_read = vcom_reg;
19893a7515aSWenping Zhang 	ret = tps65185_i2c_read(priv_data, REG_VCOM2_ADJUST, &vcom_reg);
19993a7515aSWenping Zhang 	if (ret) {
20093a7515aSWenping Zhang 		printf("read vcom failed: %d\n", ret);
20193a7515aSWenping Zhang 		return ret;
20293a7515aSWenping Zhang 	}
20393a7515aSWenping Zhang 	*vcom_read += (vcom_reg & 0x1) << 8;
20493a7515aSWenping Zhang 
20593a7515aSWenping Zhang 	printf("read vcom value: %d\n", *vcom_read);
20693a7515aSWenping Zhang 
20793a7515aSWenping Zhang 	return 0;
20893a7515aSWenping Zhang }
20993a7515aSWenping Zhang 
tps65185_set_vcom_value(struct udevice * dev,u32 set_value)21093a7515aSWenping Zhang static int tps65185_set_vcom_value(struct udevice *dev, u32 set_value)
21193a7515aSWenping Zhang {
21293a7515aSWenping Zhang 	int ret = 0;
21393a7515aSWenping Zhang 	u32 vcom_readback = 0;
21493a7515aSWenping Zhang 	u8 vcom1_val, vcom2_val, int_stat = 0;
21593a7515aSWenping Zhang 	struct tps65185_priv_data *priv_data = dev_get_priv(dev);
21693a7515aSWenping Zhang 
21793a7515aSWenping Zhang 	ret = tps65185_read_vcom_value(priv_data, &vcom_readback);
21893a7515aSWenping Zhang 	if (ret < 0) {
21993a7515aSWenping Zhang 		printf("tps65185 read vcom value failed\n");
22093a7515aSWenping Zhang 	} else {
22193a7515aSWenping Zhang 		if (vcom_readback == set_value / 10) {
22293a7515aSWenping Zhang 			printf("Same as pmic default value, just return.\n");
22393a7515aSWenping Zhang 			return 0;
22493a7515aSWenping Zhang 		}
22593a7515aSWenping Zhang 	}
22693a7515aSWenping Zhang 
22793a7515aSWenping Zhang 	vcom1_val = mv_to_vcom1_reg(set_value);
22893a7515aSWenping Zhang 	vcom2_val = mv_to_vcom2_reg(set_value);
22993a7515aSWenping Zhang 
23093a7515aSWenping Zhang 	dm_gpio_set_value(&priv_data->wake_up_gpio, 1);
23193a7515aSWenping Zhang 	msleep(20);
23293a7515aSWenping Zhang 	// Set vcom voltage
23393a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_VCOM1_ADJUST, vcom1_val);
23493a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_VCOM2_ADJUST, vcom2_val);
23593a7515aSWenping Zhang 	// PROGRAMMING
23693a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_VCOM2_ADJUST,
23793a7515aSWenping Zhang 			   vcom2_val | (1 << PAPYRUS_VCOM2_PROG));
23893a7515aSWenping Zhang 	do {
23993a7515aSWenping Zhang 		msleep(20);
24093a7515aSWenping Zhang 		ret = tps65185_i2c_read(priv_data, REG_INT_STATUS1, &int_stat);
24193a7515aSWenping Zhang 		if (ret) {
24293a7515aSWenping Zhang 			printf("read status1 failed: %d\n", ret);
24393a7515aSWenping Zhang 			break;
24493a7515aSWenping Zhang 		}
24593a7515aSWenping Zhang 	} while (!(int_stat & (1 << PAPYRUS_INT_STATUS1_PRGC)));
24693a7515aSWenping Zhang 
24793a7515aSWenping Zhang 	// VERIFICATION
24893a7515aSWenping Zhang 	tps65185_read_vcom_value(priv_data, &vcom_readback);
24993a7515aSWenping Zhang 
25093a7515aSWenping Zhang 	if (vcom_readback != set_value / 10) {
25193a7515aSWenping Zhang 		printf("vcom set failed, expect: %d, readback: %d\n",
25293a7515aSWenping Zhang 		       set_value, vcom_readback);
25393a7515aSWenping Zhang 		return -1;
25493a7515aSWenping Zhang 	}
25593a7515aSWenping Zhang 
25693a7515aSWenping Zhang 	return 0;
25793a7515aSWenping Zhang }
25893a7515aSWenping Zhang 
tps65185_hw_power_ack(struct tps65185_priv_data * priv_data,int up)25993a7515aSWenping Zhang static bool tps65185_hw_power_ack(struct tps65185_priv_data *priv_data, int up)
26093a7515aSWenping Zhang {
26193a7515aSWenping Zhang 	u8 pg_status;
26293a7515aSWenping Zhang 	int st, ret, retries_left = 10;
26393a7515aSWenping Zhang 
26493a7515aSWenping Zhang 	do {
26593a7515aSWenping Zhang 		ret = tps65185_i2c_read(priv_data, REG_PG_STATUS, &pg_status);
26693a7515aSWenping Zhang 		if (ret)
26793a7515aSWenping Zhang 			printf("read REG_PG_STATUS failed: %d\n", ret);
26893a7515aSWenping Zhang 
26993a7515aSWenping Zhang 		pg_status &= 0xfa;
27093a7515aSWenping Zhang 		if (pg_status == 0xfa && up == 1) {
27193a7515aSWenping Zhang 			st = 1;
27293a7515aSWenping Zhang 		} else if (pg_status == 0x00 && up == 0) {
27393a7515aSWenping Zhang 			st = 0;
27493a7515aSWenping Zhang 		} else {
27593a7515aSWenping Zhang 			st = -1;	/* not settled yet */
27693a7515aSWenping Zhang 			msleep(HW_GET_STATE_INTERVAL_MS);
27793a7515aSWenping Zhang 		}
27893a7515aSWenping Zhang 		retries_left--;
27993a7515aSWenping Zhang 	} while ((st == -1) && retries_left);
28093a7515aSWenping Zhang 
28193a7515aSWenping Zhang 	if ((st == -1) && !retries_left)
28293a7515aSWenping Zhang 		printf("power %s settle error (PG = %02x)\n",
28393a7515aSWenping Zhang 		       up ? "up" : "down", pg_status);
28493a7515aSWenping Zhang 
28593a7515aSWenping Zhang 	return (st == up);
28693a7515aSWenping Zhang }
28793a7515aSWenping Zhang 
tps65185_power_on(struct udevice * dev)28893a7515aSWenping Zhang static int tps65185_power_on(struct udevice *dev)
28993a7515aSWenping Zhang {
29093a7515aSWenping Zhang 	struct tps65185_priv_data *priv_data = dev_get_priv(dev);
29193a7515aSWenping Zhang 
29293a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_VADJ, priv_data->vadj);
29393a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_UPSEQ0, priv_data->upseq0);
29493a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_UPSEQ1, priv_data->upseq1);
29593a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_DWNSEQ0, priv_data->dwnseq0);
29693a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_DWNSEQ1, priv_data->dwnseq1);
29793a7515aSWenping Zhang 
29893a7515aSWenping Zhang 	priv_data->shadow_en |= V3P3_EN_MASK;
29993a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_ENABLE, priv_data->shadow_en);
30093a7515aSWenping Zhang 	msleep(PAPYRUS_V3P3OFF_DELAY_MS);
30193a7515aSWenping Zhang 	priv_data->shadow_en = (0x80 | 0x30 | 0x0F);
30293a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_ENABLE, priv_data->shadow_en);
30393a7515aSWenping Zhang 
30493a7515aSWenping Zhang 	tps65185_hw_power_ack(priv_data, 1);
30593a7515aSWenping Zhang 	return 0;
30693a7515aSWenping Zhang }
30793a7515aSWenping Zhang 
tps65185_power_down(struct udevice * dev)30893a7515aSWenping Zhang static int tps65185_power_down(struct udevice *dev)
30993a7515aSWenping Zhang {
31093a7515aSWenping Zhang 	struct tps65185_priv_data *priv_data = dev_get_priv(dev);
31193a7515aSWenping Zhang 
31293a7515aSWenping Zhang 	priv_data->shadow_en = (0x40 | 0x20 | 0x0F);
31393a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_ENABLE, priv_data->shadow_en);
31493a7515aSWenping Zhang 	msleep(PAPYRUS_V3P3OFF_DELAY_MS);
31593a7515aSWenping Zhang 	priv_data->shadow_en &= ~V3P3_EN_MASK;
31693a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_ENABLE, priv_data->shadow_en);
31793a7515aSWenping Zhang 
31893a7515aSWenping Zhang 	tps65185_hw_power_ack(priv_data, 0);
31993a7515aSWenping Zhang 
32093a7515aSWenping Zhang 	return 0;
32193a7515aSWenping Zhang }
32293a7515aSWenping Zhang 
tps65185_temp_get(struct udevice * dev,u32 * temp)32393a7515aSWenping Zhang static int tps65185_temp_get(struct udevice *dev, u32 *temp)
32493a7515aSWenping Zhang {
32593a7515aSWenping Zhang 	int ret;
32693a7515aSWenping Zhang 	u8 read_val = 0;
32793a7515aSWenping Zhang 	struct tps65185_priv_data *priv_data = dev_get_priv(dev);
32893a7515aSWenping Zhang 
32993a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_TMST1, 0x80);
33093a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_TMST1, 0x80);
33193a7515aSWenping Zhang 	do {
33293a7515aSWenping Zhang 		int retry_time = 100;
33393a7515aSWenping Zhang 
33493a7515aSWenping Zhang 		ret = tps65185_i2c_read(priv_data, REG_TMST1, &read_val);
33593a7515aSWenping Zhang 		if (ret < 0) {
33693a7515aSWenping Zhang 			printf("read REG_TMST1 failed: %d\n", ret);
33793a7515aSWenping Zhang 			return ret;
33893a7515aSWenping Zhang 		}
33993a7515aSWenping Zhang 		if (retry_time-- == 0) {
34093a7515aSWenping Zhang 			printf("read REG_TMST1 retry 100 times\n");
34193a7515aSWenping Zhang 			break;
34293a7515aSWenping Zhang 		}
34393a7515aSWenping Zhang 		debug("read_val = 0x%x\n", read_val);
34493a7515aSWenping Zhang 	} while (((read_val & 0x20) == 0 || (read_val & 0x80)));
34593a7515aSWenping Zhang 
34693a7515aSWenping Zhang 	mdelay(PAPYRUS_TEMP_READ_TIME_MS);
34793a7515aSWenping Zhang 	ret = tps65185_i2c_read(priv_data, REG_TMST_VALUE, &read_val);
34893a7515aSWenping Zhang 	if (ret) {
34993a7515aSWenping Zhang 		printf("read REG_TMST_VALUE failed: %d\n", ret);
35093a7515aSWenping Zhang 		return ret;
35193a7515aSWenping Zhang 	}
35293a7515aSWenping Zhang 	*temp = (u32)read_val;
35393a7515aSWenping Zhang 
35493a7515aSWenping Zhang 	return 0;
35593a7515aSWenping Zhang }
35693a7515aSWenping Zhang 
tps65185_hw_init(struct udevice * dev)35793a7515aSWenping Zhang static int tps65185_hw_init(struct udevice *dev)
35893a7515aSWenping Zhang {
35993a7515aSWenping Zhang 	int ret;
36093a7515aSWenping Zhang 	u8 rev_id = 0;
36193a7515aSWenping Zhang 	struct tps65185_priv_data *priv_data = dev_get_priv(dev);
36293a7515aSWenping Zhang 
36393a7515aSWenping Zhang 	dm_gpio_set_value(&priv_data->wake_up_gpio, 0);
36493a7515aSWenping Zhang 	mdelay(PAPYRUS_SLEEP_MINIMUM_MS);
36593a7515aSWenping Zhang 	dm_gpio_set_value(&priv_data->wake_up_gpio, 1);
36693a7515aSWenping Zhang 	dm_gpio_set_value(&priv_data->pwr_up_gpio, 0);
36793a7515aSWenping Zhang 	dm_gpio_set_value(&priv_data->vcom_gpio, 1);
36893a7515aSWenping Zhang 	mdelay(PAPYRUS_EEPROM_DELAY_MS);
36993a7515aSWenping Zhang 	ret = tps65185_i2c_read(priv_data, REG_REVID, &rev_id);
37093a7515aSWenping Zhang 	if (ret) {
37193a7515aSWenping Zhang 		printf("read revid failed: %d\n", ret);
37293a7515aSWenping Zhang 		return ret;
37393a7515aSWenping Zhang 	}
37493a7515aSWenping Zhang 
37593a7515aSWenping Zhang 	if (rev_id > 0)
37693a7515aSWenping Zhang 		printf("detected device with ID=%02x (TPS6518%dr%dp%d)\n",
37793a7515aSWenping Zhang 		       rev_id, rev_id & 0xF, (rev_id & 0xC0) >> 6,
37893a7515aSWenping Zhang 		       (rev_id & 0x30) >> 4);
37993a7515aSWenping Zhang 
38093a7515aSWenping Zhang 	tps65185_i2c_write(priv_data, REG_ENABLE, priv_data->shadow_en);
38193a7515aSWenping Zhang 	priv_data->rev_id = rev_id;
38293a7515aSWenping Zhang 	printf("rev_id=%x\n", rev_id);
38393a7515aSWenping Zhang 	return 0;
38493a7515aSWenping Zhang }
38593a7515aSWenping Zhang 
tps65185_init_arg(struct tps65185_priv_data * priv_data)38693a7515aSWenping Zhang static void tps65185_init_arg(struct tps65185_priv_data *priv_data)
38793a7515aSWenping Zhang {
38893a7515aSWenping Zhang 	priv_data->vadj = 0x03;
38993a7515aSWenping Zhang 
39093a7515aSWenping Zhang 	priv_data->upseq0 = SEQ_VEE(0) | SEQ_VNEG(1)
39193a7515aSWenping Zhang 				| SEQ_VPOS(2) | SEQ_VDD(3);
39293a7515aSWenping Zhang 	priv_data->upseq1 = UDLY_3ms(0) | UDLY_3ms(1)
39393a7515aSWenping Zhang 				| UDLY_3ms(2) | UDLY_3ms(3);
39493a7515aSWenping Zhang 
39593a7515aSWenping Zhang 	priv_data->dwnseq0 = SEQ_VDD(0) | SEQ_VPOS(1)
39693a7515aSWenping Zhang 				| SEQ_VNEG(2) | SEQ_VEE(3);
39793a7515aSWenping Zhang 	priv_data->dwnseq1 = DDLY_6ms(0) | DDLY_6ms(1)
39893a7515aSWenping Zhang 				| DDLY_6ms(2) | DDLY_6ms(3);
39993a7515aSWenping Zhang 
40093a7515aSWenping Zhang 	priv_data->vcom1 = mv_to_vcom1_reg(1560);
40193a7515aSWenping Zhang 	priv_data->vcom2 = mv_to_vcom2_reg(1560);
40293a7515aSWenping Zhang 	priv_data->shadow_en = 0;
40393a7515aSWenping Zhang }
40493a7515aSWenping Zhang 
tps65185_probe(struct udevice * dev)40593a7515aSWenping Zhang static int tps65185_probe(struct udevice *dev)
40693a7515aSWenping Zhang {
40793a7515aSWenping Zhang 	int ret;
40893a7515aSWenping Zhang 	struct tps65185_priv_data *tps65185_priv = dev_get_priv(dev);
40993a7515aSWenping Zhang 
41093a7515aSWenping Zhang 	tps65185_priv->dev = dev;
41193a7515aSWenping Zhang 	pmic_dev = dev;
41293a7515aSWenping Zhang 	tps65185_init_arg(tps65185_priv);
41393a7515aSWenping Zhang 
41493a7515aSWenping Zhang 	ret = gpio_request_by_name(dev, "wakeup-gpios", 0,
41593a7515aSWenping Zhang 				   &tps65185_priv->wake_up_gpio, GPIOD_IS_OUT);
41693a7515aSWenping Zhang 	if (ret) {
41793a7515aSWenping Zhang 		printf("Cannot get wakeup_pin GPIO: %d\n", ret);
41893a7515aSWenping Zhang 		return ret;
41993a7515aSWenping Zhang 	}
42093a7515aSWenping Zhang 	ret = gpio_request_by_name(dev, "powerup-gpios", 0,
42193a7515aSWenping Zhang 				   &tps65185_priv->pwr_up_gpio, GPIOD_IS_OUT);
42293a7515aSWenping Zhang 	if (ret) {
42393a7515aSWenping Zhang 		printf("Cannot get pwr_up_gpio GPIO: %d\n", ret);
42493a7515aSWenping Zhang 		return ret;
42593a7515aSWenping Zhang 	}
42693a7515aSWenping Zhang 	ret = gpio_request_by_name(dev, "vcomctl-gpios", 0,
42793a7515aSWenping Zhang 				   &tps65185_priv->vcom_gpio, GPIOD_IS_OUT);
42893a7515aSWenping Zhang 	if (ret) {
42993a7515aSWenping Zhang 		printf("Cannot get vcom_gpio GPIO: %d\n", ret);
43093a7515aSWenping Zhang 		return ret;
43193a7515aSWenping Zhang 	}
432*39c952aeSWeixin Zhou 	ret = gpio_request_by_name(dev, "poweren-gpios", 0,
433*39c952aeSWeixin Zhou 				   &tps65185_priv->pwr_en_gpio, GPIOD_IS_OUT);
434*39c952aeSWeixin Zhou 	if (!ret)
435*39c952aeSWeixin Zhou 		dm_gpio_set_value(&tps65185_priv->pwr_en_gpio, 1);
436*39c952aeSWeixin Zhou 	else
437*39c952aeSWeixin Zhou 		printf("Cannot get pwren_pin GPIO: %d\n", ret);
438*39c952aeSWeixin Zhou 
43993a7515aSWenping Zhang 	ret = tps65185_hw_init(dev);
44093a7515aSWenping Zhang 	if (ret) {
44193a7515aSWenping Zhang 		printf("Cannot init hardware for tps65185: %d\n", ret);
44293a7515aSWenping Zhang 		return ret;
44393a7515aSWenping Zhang 	}
44493a7515aSWenping Zhang 
44593a7515aSWenping Zhang 	return 0;
44693a7515aSWenping Zhang }
44793a7515aSWenping Zhang 
44893a7515aSWenping Zhang const struct rk_ebc_pwr_ops tps65185_funcs = {
44993a7515aSWenping Zhang 	.power_on = tps65185_power_on,
45093a7515aSWenping Zhang 	.power_down = tps65185_power_down,
45193a7515aSWenping Zhang 	.temp_get = tps65185_temp_get,
45293a7515aSWenping Zhang 	.vcom_set = tps65185_set_vcom_value,
45393a7515aSWenping Zhang };
45493a7515aSWenping Zhang 
45593a7515aSWenping Zhang static const struct udevice_id ebc_power_of_match[] = {
45693a7515aSWenping Zhang 	{ .compatible = "ti,tps65185" },
45793a7515aSWenping Zhang 	{}
45893a7515aSWenping Zhang };
45993a7515aSWenping Zhang 
46093a7515aSWenping Zhang U_BOOT_DRIVER(tps65185_ebc_pwr) = {
46193a7515aSWenping Zhang 	.name = "tps65185_ebc_pwr",
46293a7515aSWenping Zhang 	.id = UCLASS_I2C_GENERIC,
46393a7515aSWenping Zhang 	.of_match = ebc_power_of_match,
46493a7515aSWenping Zhang 	.probe = tps65185_probe,
46593a7515aSWenping Zhang 	.ops = &tps65185_funcs,
46693a7515aSWenping Zhang 	.bind = dm_scan_fdt_dev,
46793a7515aSWenping Zhang 	.priv_auto_alloc_size = sizeof(struct tps65185_priv_data),
46893a7515aSWenping Zhang };
46993a7515aSWenping Zhang 
470