blob: ecbcaa010931b8c01d435f4804c3da37bfa6ffde [file] [log] [blame]
Archit Taneja2437e7c2016-06-15 16:24:03 +05301/*
2 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Archit Taneja1e4d58c2016-06-15 17:01:27 +053014#include <linux/of_graph.h>
15
Archit Taneja2437e7c2016-06-15 16:24:03 +053016#include "adv7511.h"
17
18static const struct reg_sequence adv7533_fixed_registers[] = {
19 { 0x16, 0x20 },
20 { 0x9a, 0xe0 },
21 { 0xba, 0x70 },
22 { 0xde, 0x82 },
23 { 0xe4, 0x40 },
24 { 0xe5, 0x80 },
25};
26
27static const struct reg_sequence adv7533_cec_fixed_registers[] = {
28 { 0x15, 0xd0 },
29 { 0x17, 0xd0 },
30 { 0x24, 0x20 },
31 { 0x57, 0x11 },
32};
33
34static const struct regmap_config adv7533_cec_regmap_config = {
35 .reg_bits = 8,
36 .val_bits = 8,
37
38 .max_register = 0xff,
39 .cache_type = REGCACHE_RBTREE,
40};
41
42void adv7533_dsi_power_on(struct adv7511 *adv)
43{
Archit Taneja1e4d58c2016-06-15 17:01:27 +053044 struct mipi_dsi_device *dsi = adv->dsi;
45
46 /* set number of dsi lanes */
47 regmap_write(adv->regmap_cec, 0x1c, dsi->lanes << 4);
Archit Taneja2437e7c2016-06-15 16:24:03 +053048 /* disable internal timing generator */
49 regmap_write(adv->regmap_cec, 0x27, 0x0b);
50 /* enable hdmi */
51 regmap_write(adv->regmap_cec, 0x03, 0x89);
52 /* disable test mode */
53 regmap_write(adv->regmap_cec, 0x55, 0x00);
54
55 regmap_register_patch(adv->regmap_cec, adv7533_cec_fixed_registers,
56 ARRAY_SIZE(adv7533_cec_fixed_registers));
57}
58
59void adv7533_dsi_power_off(struct adv7511 *adv)
60{
61 /* disable hdmi */
62 regmap_write(adv->regmap_cec, 0x03, 0x0b);
63}
64
65int adv7533_patch_registers(struct adv7511 *adv)
66{
67 return regmap_register_patch(adv->regmap,
68 adv7533_fixed_registers,
69 ARRAY_SIZE(adv7533_fixed_registers));
70}
71
72void adv7533_uninit_cec(struct adv7511 *adv)
73{
74 i2c_unregister_device(adv->i2c_cec);
75}
76
77static const int cec_i2c_addr = 0x78;
78
79int adv7533_init_cec(struct adv7511 *adv)
80{
81 int ret;
82
83 adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter, cec_i2c_addr >> 1);
84 if (!adv->i2c_cec)
85 return -ENOMEM;
86
87 adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
88 &adv7533_cec_regmap_config);
89 if (IS_ERR(adv->regmap_cec)) {
90 ret = PTR_ERR(adv->regmap_cec);
91 goto err;
92 }
93
94 ret = regmap_register_patch(adv->regmap_cec,
95 adv7533_cec_fixed_registers,
96 ARRAY_SIZE(adv7533_cec_fixed_registers));
97 if (ret)
98 goto err;
99
100 return 0;
101err:
102 adv7533_uninit_cec(adv);
103 return ret;
104}
Archit Taneja1e4d58c2016-06-15 17:01:27 +0530105
106int adv7533_attach_dsi(struct adv7511 *adv)
107{
108 struct device *dev = &adv->i2c_main->dev;
109 struct mipi_dsi_host *host;
110 struct mipi_dsi_device *dsi;
111 int ret = 0;
112 const struct mipi_dsi_device_info info = { .type = "adv7533",
113 .channel = 0,
114 .node = NULL,
115 };
116
117 host = of_find_mipi_dsi_host_by_node(adv->host_node);
118 if (!host) {
119 dev_err(dev, "failed to find dsi host\n");
120 return -EPROBE_DEFER;
121 }
122
123 dsi = mipi_dsi_device_register_full(host, &info);
124 if (IS_ERR(dsi)) {
125 dev_err(dev, "failed to create dsi device\n");
126 ret = PTR_ERR(dsi);
127 goto err_dsi_device;
128 }
129
130 adv->dsi = dsi;
131
132 dsi->lanes = adv->num_dsi_lanes;
133 dsi->format = MIPI_DSI_FMT_RGB888;
134 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
135 MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE;
136
137 ret = mipi_dsi_attach(dsi);
138 if (ret < 0) {
139 dev_err(dev, "failed to attach dsi to host\n");
140 goto err_dsi_attach;
141 }
142
143 return 0;
144
145err_dsi_attach:
146 mipi_dsi_device_unregister(dsi);
147err_dsi_device:
148 return ret;
149}
150
151void adv7533_detach_dsi(struct adv7511 *adv)
152{
153 mipi_dsi_detach(adv->dsi);
154 mipi_dsi_device_unregister(adv->dsi);
155}
156
157int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv)
158{
159 u32 num_lanes;
160 struct device_node *endpoint;
161
162 of_property_read_u32(np, "adi,dsi-lanes", &num_lanes);
163
164 if (num_lanes < 1 || num_lanes > 4)
165 return -EINVAL;
166
167 adv->num_dsi_lanes = num_lanes;
168
169 endpoint = of_graph_get_next_endpoint(np, NULL);
170 if (!endpoint)
171 return -ENODEV;
172
173 adv->host_node = of_graph_get_remote_port_parent(endpoint);
174 if (!adv->host_node) {
175 of_node_put(endpoint);
176 return -ENODEV;
177 }
178
179 of_node_put(endpoint);
180 of_node_put(adv->host_node);
181
182 /* TODO: Check if these need to be parsed by DT or not */
183 adv->rgb = true;
184 adv->embedded_sync = false;
185
186 return 0;
187}