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