1 // SPDX-License-Identifier: GPL-2.0-only
3 * NXP PTN3460 DP/LVDS bridge driver
5 * Copyright (C) 2013 Google, Inc.
8 #include <linux/delay.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/i2c.h>
11 #include <linux/module.h>
13 #include <drm/drm_atomic_helper.h>
14 #include <drm/drm_bridge.h>
15 #include <drm/drm_crtc.h>
16 #include <drm/drm_edid.h>
17 #include <drm/drm_of.h>
18 #include <drm/drm_panel.h>
19 #include <drm/drm_print.h>
20 #include <drm/drm_probe_helper.h>
22 #define PTN3460_EDID_ADDR 0x0
23 #define PTN3460_EDID_EMULATION_ADDR 0x84
24 #define PTN3460_EDID_ENABLE_EMULATION 0
25 #define PTN3460_EDID_EMULATION_SELECTION 1
26 #define PTN3460_EDID_SRAM_LOAD_ADDR 0x85
28 struct ptn3460_bridge
{
29 struct drm_connector connector
;
30 struct i2c_client
*client
;
31 struct drm_bridge bridge
;
32 struct drm_bridge
*panel_bridge
;
33 struct gpio_desc
*gpio_pd_n
;
34 struct gpio_desc
*gpio_rst_n
;
39 static inline struct ptn3460_bridge
*
40 bridge_to_ptn3460(struct drm_bridge
*bridge
)
42 return container_of(bridge
, struct ptn3460_bridge
, bridge
);
45 static inline struct ptn3460_bridge
*
46 connector_to_ptn3460(struct drm_connector
*connector
)
48 return container_of(connector
, struct ptn3460_bridge
, connector
);
51 static int ptn3460_read_bytes(struct ptn3460_bridge
*ptn_bridge
, char addr
,
56 ret
= i2c_master_send(ptn_bridge
->client
, &addr
, 1);
58 DRM_ERROR("Failed to send i2c command, ret=%d\n", ret
);
62 ret
= i2c_master_recv(ptn_bridge
->client
, buf
, len
);
64 DRM_ERROR("Failed to recv i2c data, ret=%d\n", ret
);
71 static int ptn3460_write_byte(struct ptn3460_bridge
*ptn_bridge
, char addr
,
80 ret
= i2c_master_send(ptn_bridge
->client
, buf
, ARRAY_SIZE(buf
));
82 DRM_ERROR("Failed to send i2c command, ret=%d\n", ret
);
89 static int ptn3460_select_edid(struct ptn3460_bridge
*ptn_bridge
)
94 /* Load the selected edid into SRAM (accessed at PTN3460_EDID_ADDR) */
95 ret
= ptn3460_write_byte(ptn_bridge
, PTN3460_EDID_SRAM_LOAD_ADDR
,
96 ptn_bridge
->edid_emulation
);
98 DRM_ERROR("Failed to transfer EDID to sram, ret=%d\n", ret
);
102 /* Enable EDID emulation and select the desired EDID */
103 val
= 1 << PTN3460_EDID_ENABLE_EMULATION
|
104 ptn_bridge
->edid_emulation
<< PTN3460_EDID_EMULATION_SELECTION
;
106 ret
= ptn3460_write_byte(ptn_bridge
, PTN3460_EDID_EMULATION_ADDR
, val
);
108 DRM_ERROR("Failed to write EDID value, ret=%d\n", ret
);
115 static void ptn3460_pre_enable(struct drm_bridge
*bridge
)
117 struct ptn3460_bridge
*ptn_bridge
= bridge_to_ptn3460(bridge
);
120 if (ptn_bridge
->enabled
)
123 gpiod_set_value(ptn_bridge
->gpio_pd_n
, 1);
125 gpiod_set_value(ptn_bridge
->gpio_rst_n
, 0);
126 usleep_range(10, 20);
127 gpiod_set_value(ptn_bridge
->gpio_rst_n
, 1);
130 * There's a bug in the PTN chip where it falsely asserts hotplug before
131 * it is fully functional. We're forced to wait for the maximum start up
132 * time specified in the chip's datasheet to make sure we're really up.
136 ret
= ptn3460_select_edid(ptn_bridge
);
138 DRM_ERROR("Select EDID failed ret=%d\n", ret
);
140 ptn_bridge
->enabled
= true;
143 static void ptn3460_disable(struct drm_bridge
*bridge
)
145 struct ptn3460_bridge
*ptn_bridge
= bridge_to_ptn3460(bridge
);
147 if (!ptn_bridge
->enabled
)
150 ptn_bridge
->enabled
= false;
152 gpiod_set_value(ptn_bridge
->gpio_rst_n
, 1);
153 gpiod_set_value(ptn_bridge
->gpio_pd_n
, 0);
157 static struct edid
*ptn3460_get_edid(struct drm_bridge
*bridge
,
158 struct drm_connector
*connector
)
160 struct ptn3460_bridge
*ptn_bridge
= bridge_to_ptn3460(bridge
);
165 power_off
= !ptn_bridge
->enabled
;
166 ptn3460_pre_enable(&ptn_bridge
->bridge
);
168 edid
= kmalloc(EDID_LENGTH
, GFP_KERNEL
);
170 DRM_ERROR("Failed to allocate EDID\n");
174 ret
= ptn3460_read_bytes(ptn_bridge
, PTN3460_EDID_ADDR
, edid
,
184 ptn3460_disable(&ptn_bridge
->bridge
);
186 return (struct edid
*)edid
;
189 static int ptn3460_connector_get_modes(struct drm_connector
*connector
)
191 struct ptn3460_bridge
*ptn_bridge
= connector_to_ptn3460(connector
);
195 edid
= ptn3460_get_edid(&ptn_bridge
->bridge
, connector
);
196 drm_connector_update_edid_property(connector
, edid
);
197 num_modes
= drm_add_edid_modes(connector
, edid
);
203 static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs
= {
204 .get_modes
= ptn3460_connector_get_modes
,
207 static const struct drm_connector_funcs ptn3460_connector_funcs
= {
208 .fill_modes
= drm_helper_probe_single_connector_modes
,
209 .destroy
= drm_connector_cleanup
,
210 .reset
= drm_atomic_helper_connector_reset
,
211 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
212 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
215 static int ptn3460_bridge_attach(struct drm_bridge
*bridge
,
216 enum drm_bridge_attach_flags flags
)
218 struct ptn3460_bridge
*ptn_bridge
= bridge_to_ptn3460(bridge
);
221 /* Let this driver create connector if requested */
222 ret
= drm_bridge_attach(bridge
->encoder
, ptn_bridge
->panel_bridge
,
223 bridge
, flags
| DRM_BRIDGE_ATTACH_NO_CONNECTOR
);
227 if (flags
& DRM_BRIDGE_ATTACH_NO_CONNECTOR
)
230 if (!bridge
->encoder
) {
231 DRM_ERROR("Parent encoder object not found");
235 ptn_bridge
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
236 ret
= drm_connector_init(bridge
->dev
, &ptn_bridge
->connector
,
237 &ptn3460_connector_funcs
, DRM_MODE_CONNECTOR_LVDS
);
239 DRM_ERROR("Failed to initialize connector with drm\n");
242 drm_connector_helper_add(&ptn_bridge
->connector
,
243 &ptn3460_connector_helper_funcs
);
244 drm_connector_register(&ptn_bridge
->connector
);
245 drm_connector_attach_encoder(&ptn_bridge
->connector
,
248 drm_helper_hpd_irq_event(ptn_bridge
->connector
.dev
);
253 static const struct drm_bridge_funcs ptn3460_bridge_funcs
= {
254 .pre_enable
= ptn3460_pre_enable
,
255 .disable
= ptn3460_disable
,
256 .attach
= ptn3460_bridge_attach
,
257 .get_edid
= ptn3460_get_edid
,
260 static int ptn3460_probe(struct i2c_client
*client
,
261 const struct i2c_device_id
*id
)
263 struct device
*dev
= &client
->dev
;
264 struct ptn3460_bridge
*ptn_bridge
;
265 struct drm_bridge
*panel_bridge
;
266 struct drm_panel
*panel
;
269 ptn_bridge
= devm_kzalloc(dev
, sizeof(*ptn_bridge
), GFP_KERNEL
);
274 ret
= drm_of_find_panel_or_bridge(dev
->of_node
, 0, 0, &panel
, NULL
);
278 panel_bridge
= devm_drm_panel_bridge_add(dev
, panel
);
279 if (IS_ERR(panel_bridge
))
280 return PTR_ERR(panel_bridge
);
282 ptn_bridge
->panel_bridge
= panel_bridge
;
283 ptn_bridge
->client
= client
;
285 ptn_bridge
->gpio_pd_n
= devm_gpiod_get(&client
->dev
, "powerdown",
287 if (IS_ERR(ptn_bridge
->gpio_pd_n
)) {
288 ret
= PTR_ERR(ptn_bridge
->gpio_pd_n
);
289 dev_err(dev
, "cannot get gpio_pd_n %d\n", ret
);
294 * Request the reset pin low to avoid the bridge being
295 * initialized prematurely
297 ptn_bridge
->gpio_rst_n
= devm_gpiod_get(&client
->dev
, "reset",
299 if (IS_ERR(ptn_bridge
->gpio_rst_n
)) {
300 ret
= PTR_ERR(ptn_bridge
->gpio_rst_n
);
301 DRM_ERROR("cannot get gpio_rst_n %d\n", ret
);
305 ret
= of_property_read_u32(dev
->of_node
, "edid-emulation",
306 &ptn_bridge
->edid_emulation
);
308 dev_err(dev
, "Can't read EDID emulation value\n");
312 ptn_bridge
->bridge
.funcs
= &ptn3460_bridge_funcs
;
313 ptn_bridge
->bridge
.ops
= DRM_BRIDGE_OP_EDID
;
314 ptn_bridge
->bridge
.type
= DRM_MODE_CONNECTOR_LVDS
;
315 ptn_bridge
->bridge
.of_node
= dev
->of_node
;
316 drm_bridge_add(&ptn_bridge
->bridge
);
318 i2c_set_clientdata(client
, ptn_bridge
);
323 static int ptn3460_remove(struct i2c_client
*client
)
325 struct ptn3460_bridge
*ptn_bridge
= i2c_get_clientdata(client
);
327 drm_bridge_remove(&ptn_bridge
->bridge
);
332 static const struct i2c_device_id ptn3460_i2c_table
[] = {
336 MODULE_DEVICE_TABLE(i2c
, ptn3460_i2c_table
);
338 static const struct of_device_id ptn3460_match
[] = {
339 { .compatible
= "nxp,ptn3460" },
342 MODULE_DEVICE_TABLE(of
, ptn3460_match
);
344 static struct i2c_driver ptn3460_driver
= {
345 .id_table
= ptn3460_i2c_table
,
346 .probe
= ptn3460_probe
,
347 .remove
= ptn3460_remove
,
349 .name
= "nxp,ptn3460",
350 .of_match_table
= ptn3460_match
,
353 module_i2c_driver(ptn3460_driver
);
355 MODULE_AUTHOR("Sean Paul <seanpaul@chromium.org>");
356 MODULE_DESCRIPTION("NXP ptn3460 eDP-LVDS converter driver");
357 MODULE_LICENSE("GPL v2");