1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2008-2018 Fuzhou Rockchip Electronics Co., Ltd
4 */
5
6 #include <common.h>
7 #include <i2c.h>
8 #include <errno.h>
9 #include <dm.h>
10 #include <dm/uclass.h>
11 #include <dm/uclass-id.h>
12
13 #include "rk618.h"
14
rk618_i2c_write(struct rk618 * rk618,u16 reg,u32 val)15 int rk618_i2c_write(struct rk618 *rk618, u16 reg, u32 val)
16 {
17 struct dm_i2c_chip *chip = dev_get_parent_platdata(rk618->dev);
18 struct i2c_msg msg;
19 u8 buf[] = {
20 (reg >> 0) & 0xff, (reg >> 8) & 0xff,
21 (val >> 0) & 0xff, (val >> 8) & 0xff,
22 (val >> 16) & 0xff, (val >> 24) & 0xff
23 };
24 int ret;
25
26 msg.addr = chip->chip_addr;
27 msg.flags = 0;
28 msg.len = sizeof(buf);
29 msg.buf = buf;
30
31 ret = dm_i2c_xfer(rk618->dev, &msg, 1);
32 if (ret) {
33 dev_err(rk618->dev, "Could not execute transfer: %d\n", ret);
34 return ret;
35 }
36
37 return 0;
38 }
39
rk618_i2c_read(struct rk618 * rk618,u16 reg,u32 * val)40 int rk618_i2c_read(struct rk618 *rk618, u16 reg, u32 *val)
41 {
42 struct dm_i2c_chip *chip = dev_get_parent_platdata(rk618->dev);
43 u32 data;
44 struct i2c_msg msg[] = {
45 {
46 .addr = chip->chip_addr,
47 .flags = 0,
48 .buf = (u8 *)®,
49 .len = 2,
50 }, {
51 .addr = chip->chip_addr,
52 .flags = I2C_M_RD,
53 .buf = (u8 *)&data,
54 .len = 4,
55 }
56 };
57 int ret;
58
59 ret = dm_i2c_xfer(rk618->dev, msg, 2);
60 if (ret) {
61 dev_err(rk618->dev, "Could not execute transfer: %d\n", ret);
62 return ret;
63 }
64
65 *val = data;
66
67 return 0;
68 }
69
rk618_frc_dither_disable(struct rk618 * rk618)70 void rk618_frc_dither_disable(struct rk618 *rk618)
71 {
72 rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DITHER_DISABLE);
73 }
74
rk618_frc_dither_enable(struct rk618 * rk618)75 void rk618_frc_dither_enable(struct rk618 *rk618)
76 {
77 rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DITHER_ENABLE);
78 }
79
rk618_frc_dclk_invert(struct rk618 * rk618)80 void rk618_frc_dclk_invert(struct rk618 *rk618)
81 {
82 rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DCLK_INV);
83 }
84
rk618_power_on(struct rk618 * rk618)85 static int rk618_power_on(struct rk618 *rk618)
86 {
87 if (rk618->power_supply)
88 regulator_set_enable(rk618->power_supply, 1);
89
90 if (dm_gpio_is_valid(&rk618->enable_gpio))
91 dm_gpio_set_value(&rk618->enable_gpio, 1);
92
93 mdelay(2);
94 dm_gpio_set_value(&rk618->reset_gpio, 0);
95 mdelay(4);
96 dm_gpio_set_value(&rk618->reset_gpio, 1);
97 mdelay(50);
98 dm_gpio_set_value(&rk618->reset_gpio, 0);
99
100 return 0;
101 }
102
rk618_cru_init(struct rk618 * rk618)103 static void rk618_cru_init(struct rk618 *rk618)
104 {
105 rk618_i2c_write(rk618, 0x0058, 0xffff0000);
106 rk618_i2c_write(rk618, 0x005c, 0xffff191e);
107 rk618_i2c_write(rk618, 0x0060, 0x00000000);
108 rk618_i2c_write(rk618, 0x0064, 0xffff2186);
109 rk618_i2c_write(rk618, 0x0068, 0xffff1028);
110 rk618_i2c_write(rk618, 0x006c, 0xffff0641);
111 rk618_i2c_write(rk618, 0x0070, 0x00800000);
112 rk618_i2c_write(rk618, 0x0074, 0xffff1028);
113 rk618_i2c_write(rk618, 0x0078, 0xffff0641);
114 rk618_i2c_write(rk618, 0x007c, 0x00800000);
115 }
116
rk618_probe(struct udevice * dev)117 static int rk618_probe(struct udevice *dev)
118 {
119 struct rk618 *rk618 = dev_get_priv(dev);
120 int ret;
121
122 rk618->dev = dev;
123
124 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
125 "power-supply",
126 &rk618->power_supply);
127 if (ret && ret != -ENOENT) {
128 dev_err(dev, "Cannot get power supply: %d\n", ret);
129 return ret;
130 }
131
132 ret = gpio_request_by_name(dev, "enable-gpios", 0,
133 &rk618->enable_gpio, GPIOD_IS_OUT);
134 if (ret && ret != -ENOENT) {
135 dev_err(dev, "Cannot get enable GPIO: %d\n", ret);
136 return ret;
137 }
138
139 ret = gpio_request_by_name(dev, "reset-gpios", 0,
140 &rk618->reset_gpio, GPIOD_IS_OUT);
141 if (ret) {
142 dev_err(dev, "Cannot get reset GPIO: %d\n", ret);
143 return ret;
144 }
145
146 ret = clk_get_by_name(dev, "clkin", &rk618->clkin);
147 if (ret < 0) {
148 dev_err(dev, "failed to get clkin: %d\n", ret);
149 return ret;
150 }
151
152 ret = clk_set_rate(&rk618->clkin, 11289600);
153 if (ret < 0) {
154 dev_err(dev, "failed to set rate: %d\n", ret);
155 return ret;
156 }
157
158 clk_enable(&rk618->clkin);
159
160 ret = rk618_power_on(rk618);
161 if (ret) {
162 dev_err(dev, "failed to power on: %d\n", ret);
163 return ret;
164 }
165
166 rk618_cru_init(rk618);
167
168 return 0;
169 }
170
171 static const struct udevice_id rk618_of_match[] = {
172 { .compatible = "rockchip,rk618" },
173 {}
174 };
175
176 U_BOOT_DRIVER(rk618) = {
177 .name = "rk618",
178 .id = UCLASS_I2C_GENERIC,
179 .of_match = rk618_of_match,
180 .probe = rk618_probe,
181 .bind = dm_scan_fdt_dev,
182 .priv_auto_alloc_size = sizeof(struct rk618),
183 };
184