1117fdc89SWyon Bi // SPDX-License-Identifier: GPL-2.0+
2117fdc89SWyon Bi /*
3117fdc89SWyon Bi * (C) Copyright 2008-2018 Fuzhou Rockchip Electronics Co., Ltd
4117fdc89SWyon Bi */
5117fdc89SWyon Bi
6117fdc89SWyon Bi #include <common.h>
7117fdc89SWyon Bi #include <i2c.h>
8117fdc89SWyon Bi #include <errno.h>
9117fdc89SWyon Bi #include <dm.h>
10117fdc89SWyon Bi #include <dm/uclass.h>
11117fdc89SWyon Bi #include <dm/uclass-id.h>
12117fdc89SWyon Bi
13117fdc89SWyon Bi #include "rk618.h"
14117fdc89SWyon Bi
rk618_i2c_write(struct rk618 * rk618,u16 reg,u32 val)15117fdc89SWyon Bi int rk618_i2c_write(struct rk618 *rk618, u16 reg, u32 val)
16117fdc89SWyon Bi {
17117fdc89SWyon Bi struct dm_i2c_chip *chip = dev_get_parent_platdata(rk618->dev);
18117fdc89SWyon Bi struct i2c_msg msg;
19117fdc89SWyon Bi u8 buf[] = {
20117fdc89SWyon Bi (reg >> 0) & 0xff, (reg >> 8) & 0xff,
21117fdc89SWyon Bi (val >> 0) & 0xff, (val >> 8) & 0xff,
22117fdc89SWyon Bi (val >> 16) & 0xff, (val >> 24) & 0xff
23117fdc89SWyon Bi };
24117fdc89SWyon Bi int ret;
25117fdc89SWyon Bi
26117fdc89SWyon Bi msg.addr = chip->chip_addr;
27117fdc89SWyon Bi msg.flags = 0;
28117fdc89SWyon Bi msg.len = sizeof(buf);
29117fdc89SWyon Bi msg.buf = buf;
30117fdc89SWyon Bi
31117fdc89SWyon Bi ret = dm_i2c_xfer(rk618->dev, &msg, 1);
32117fdc89SWyon Bi if (ret) {
33117fdc89SWyon Bi dev_err(rk618->dev, "Could not execute transfer: %d\n", ret);
34117fdc89SWyon Bi return ret;
35117fdc89SWyon Bi }
36117fdc89SWyon Bi
37117fdc89SWyon Bi return 0;
38117fdc89SWyon Bi }
39117fdc89SWyon Bi
rk618_i2c_read(struct rk618 * rk618,u16 reg,u32 * val)40117fdc89SWyon Bi int rk618_i2c_read(struct rk618 *rk618, u16 reg, u32 *val)
41117fdc89SWyon Bi {
42117fdc89SWyon Bi struct dm_i2c_chip *chip = dev_get_parent_platdata(rk618->dev);
43117fdc89SWyon Bi u32 data;
44117fdc89SWyon Bi struct i2c_msg msg[] = {
45117fdc89SWyon Bi {
46117fdc89SWyon Bi .addr = chip->chip_addr,
47117fdc89SWyon Bi .flags = 0,
48117fdc89SWyon Bi .buf = (u8 *)®,
49117fdc89SWyon Bi .len = 2,
50117fdc89SWyon Bi }, {
51117fdc89SWyon Bi .addr = chip->chip_addr,
52117fdc89SWyon Bi .flags = I2C_M_RD,
53117fdc89SWyon Bi .buf = (u8 *)&data,
54117fdc89SWyon Bi .len = 4,
55117fdc89SWyon Bi }
56117fdc89SWyon Bi };
57117fdc89SWyon Bi int ret;
58117fdc89SWyon Bi
59117fdc89SWyon Bi ret = dm_i2c_xfer(rk618->dev, msg, 2);
60117fdc89SWyon Bi if (ret) {
61117fdc89SWyon Bi dev_err(rk618->dev, "Could not execute transfer: %d\n", ret);
62117fdc89SWyon Bi return ret;
63117fdc89SWyon Bi }
64117fdc89SWyon Bi
65117fdc89SWyon Bi *val = data;
66117fdc89SWyon Bi
67117fdc89SWyon Bi return 0;
68117fdc89SWyon Bi }
69117fdc89SWyon Bi
rk618_frc_dither_disable(struct rk618 * rk618)70117fdc89SWyon Bi void rk618_frc_dither_disable(struct rk618 *rk618)
71117fdc89SWyon Bi {
72117fdc89SWyon Bi rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DITHER_DISABLE);
73117fdc89SWyon Bi }
74117fdc89SWyon Bi
rk618_frc_dither_enable(struct rk618 * rk618)75117fdc89SWyon Bi void rk618_frc_dither_enable(struct rk618 *rk618)
76117fdc89SWyon Bi {
77117fdc89SWyon Bi rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DITHER_ENABLE);
78117fdc89SWyon Bi }
79117fdc89SWyon Bi
rk618_frc_dclk_invert(struct rk618 * rk618)80117fdc89SWyon Bi void rk618_frc_dclk_invert(struct rk618 *rk618)
81117fdc89SWyon Bi {
82117fdc89SWyon Bi rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DCLK_INV);
83117fdc89SWyon Bi }
84117fdc89SWyon Bi
rk618_power_on(struct rk618 * rk618)85117fdc89SWyon Bi static int rk618_power_on(struct rk618 *rk618)
86117fdc89SWyon Bi {
87117fdc89SWyon Bi if (rk618->power_supply)
88117fdc89SWyon Bi regulator_set_enable(rk618->power_supply, 1);
89117fdc89SWyon Bi
90117fdc89SWyon Bi if (dm_gpio_is_valid(&rk618->enable_gpio))
91117fdc89SWyon Bi dm_gpio_set_value(&rk618->enable_gpio, 1);
92117fdc89SWyon Bi
93117fdc89SWyon Bi mdelay(2);
94117fdc89SWyon Bi dm_gpio_set_value(&rk618->reset_gpio, 0);
95117fdc89SWyon Bi mdelay(4);
96117fdc89SWyon Bi dm_gpio_set_value(&rk618->reset_gpio, 1);
97117fdc89SWyon Bi mdelay(50);
98117fdc89SWyon Bi dm_gpio_set_value(&rk618->reset_gpio, 0);
99117fdc89SWyon Bi
100117fdc89SWyon Bi return 0;
101117fdc89SWyon Bi }
102117fdc89SWyon Bi
rk618_cru_init(struct rk618 * rk618)103117fdc89SWyon Bi static void rk618_cru_init(struct rk618 *rk618)
104117fdc89SWyon Bi {
105117fdc89SWyon Bi rk618_i2c_write(rk618, 0x0058, 0xffff0000);
106*f8436d05SWyon Bi rk618_i2c_write(rk618, 0x005c, 0xffff191e);
107117fdc89SWyon Bi rk618_i2c_write(rk618, 0x0060, 0x00000000);
108117fdc89SWyon Bi rk618_i2c_write(rk618, 0x0064, 0xffff2186);
109117fdc89SWyon Bi rk618_i2c_write(rk618, 0x0068, 0xffff1028);
110117fdc89SWyon Bi rk618_i2c_write(rk618, 0x006c, 0xffff0641);
111117fdc89SWyon Bi rk618_i2c_write(rk618, 0x0070, 0x00800000);
112117fdc89SWyon Bi rk618_i2c_write(rk618, 0x0074, 0xffff1028);
113117fdc89SWyon Bi rk618_i2c_write(rk618, 0x0078, 0xffff0641);
114117fdc89SWyon Bi rk618_i2c_write(rk618, 0x007c, 0x00800000);
115117fdc89SWyon Bi }
116117fdc89SWyon Bi
rk618_probe(struct udevice * dev)117117fdc89SWyon Bi static int rk618_probe(struct udevice *dev)
118117fdc89SWyon Bi {
119117fdc89SWyon Bi struct rk618 *rk618 = dev_get_priv(dev);
120117fdc89SWyon Bi int ret;
121117fdc89SWyon Bi
122117fdc89SWyon Bi rk618->dev = dev;
123117fdc89SWyon Bi
124117fdc89SWyon Bi ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
125117fdc89SWyon Bi "power-supply",
126117fdc89SWyon Bi &rk618->power_supply);
127117fdc89SWyon Bi if (ret && ret != -ENOENT) {
128117fdc89SWyon Bi dev_err(dev, "Cannot get power supply: %d\n", ret);
129117fdc89SWyon Bi return ret;
130117fdc89SWyon Bi }
131117fdc89SWyon Bi
132117fdc89SWyon Bi ret = gpio_request_by_name(dev, "enable-gpios", 0,
133117fdc89SWyon Bi &rk618->enable_gpio, GPIOD_IS_OUT);
134117fdc89SWyon Bi if (ret && ret != -ENOENT) {
135117fdc89SWyon Bi dev_err(dev, "Cannot get enable GPIO: %d\n", ret);
136117fdc89SWyon Bi return ret;
137117fdc89SWyon Bi }
138117fdc89SWyon Bi
139117fdc89SWyon Bi ret = gpio_request_by_name(dev, "reset-gpios", 0,
140117fdc89SWyon Bi &rk618->reset_gpio, GPIOD_IS_OUT);
141117fdc89SWyon Bi if (ret) {
142117fdc89SWyon Bi dev_err(dev, "Cannot get reset GPIO: %d\n", ret);
143117fdc89SWyon Bi return ret;
144117fdc89SWyon Bi }
145117fdc89SWyon Bi
146117fdc89SWyon Bi ret = clk_get_by_name(dev, "clkin", &rk618->clkin);
147117fdc89SWyon Bi if (ret < 0) {
148117fdc89SWyon Bi dev_err(dev, "failed to get clkin: %d\n", ret);
149117fdc89SWyon Bi return ret;
150117fdc89SWyon Bi }
151117fdc89SWyon Bi
15290a6d58fSWyon Bi ret = clk_set_rate(&rk618->clkin, 11289600);
153117fdc89SWyon Bi if (ret < 0) {
154117fdc89SWyon Bi dev_err(dev, "failed to set rate: %d\n", ret);
155117fdc89SWyon Bi return ret;
156117fdc89SWyon Bi }
157117fdc89SWyon Bi
158117fdc89SWyon Bi clk_enable(&rk618->clkin);
159117fdc89SWyon Bi
160117fdc89SWyon Bi ret = rk618_power_on(rk618);
161117fdc89SWyon Bi if (ret) {
162117fdc89SWyon Bi dev_err(dev, "failed to power on: %d\n", ret);
163117fdc89SWyon Bi return ret;
164117fdc89SWyon Bi }
165117fdc89SWyon Bi
166117fdc89SWyon Bi rk618_cru_init(rk618);
167117fdc89SWyon Bi
168117fdc89SWyon Bi return 0;
169117fdc89SWyon Bi }
170117fdc89SWyon Bi
171117fdc89SWyon Bi static const struct udevice_id rk618_of_match[] = {
172117fdc89SWyon Bi { .compatible = "rockchip,rk618" },
173117fdc89SWyon Bi {}
174117fdc89SWyon Bi };
175117fdc89SWyon Bi
176117fdc89SWyon Bi U_BOOT_DRIVER(rk618) = {
177117fdc89SWyon Bi .name = "rk618",
178117fdc89SWyon Bi .id = UCLASS_I2C_GENERIC,
179117fdc89SWyon Bi .of_match = rk618_of_match,
180117fdc89SWyon Bi .probe = rk618_probe,
181117fdc89SWyon Bi .bind = dm_scan_fdt_dev,
182117fdc89SWyon Bi .priv_auto_alloc_size = sizeof(struct rk618),
183117fdc89SWyon Bi };
184