2 * Copyright (C) 2012 Russell King
3 * Rewritten from the dovefb driver, and Armada510 manuals.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <drm/drm_crtc_helper.h>
11 #include <drm/drm_edid.h>
12 #include <drm/drm_encoder_slave.h>
13 #include "armada_drm.h"
14 #include "armada_output.h"
15 #include "armada_slave.h"
17 static int armada_drm_slave_get_modes(struct drm_connector
*conn
)
19 struct drm_encoder
*enc
= armada_drm_connector_encoder(conn
);
23 struct drm_encoder_slave
*slave
= to_encoder_slave(enc
);
25 count
= slave
->slave_funcs
->get_modes(enc
, conn
);
31 static void armada_drm_slave_destroy(struct drm_encoder
*enc
)
33 struct drm_encoder_slave
*slave
= to_encoder_slave(enc
);
34 struct i2c_client
*client
= drm_i2c_encoder_get_client(enc
);
36 if (slave
->slave_funcs
)
37 slave
->slave_funcs
->destroy(enc
);
39 i2c_put_adapter(client
->adapter
);
41 drm_encoder_cleanup(&slave
->base
);
45 static const struct drm_encoder_funcs armada_drm_slave_encoder_funcs
= {
46 .destroy
= armada_drm_slave_destroy
,
49 static const struct drm_connector_helper_funcs armada_drm_slave_helper_funcs
= {
50 .get_modes
= armada_drm_slave_get_modes
,
51 .mode_valid
= armada_drm_slave_encoder_mode_valid
,
52 .best_encoder
= armada_drm_connector_encoder
,
55 static const struct drm_encoder_helper_funcs drm_slave_encoder_helpers
= {
56 .dpms
= drm_i2c_encoder_dpms
,
57 .save
= drm_i2c_encoder_save
,
58 .restore
= drm_i2c_encoder_restore
,
59 .mode_fixup
= drm_i2c_encoder_mode_fixup
,
60 .prepare
= drm_i2c_encoder_prepare
,
61 .commit
= drm_i2c_encoder_commit
,
62 .mode_set
= drm_i2c_encoder_mode_set
,
63 .detect
= drm_i2c_encoder_detect
,
67 armada_drm_conn_slave_create(struct drm_connector
*conn
, const void *data
)
69 const struct armada_drm_slave_config
*config
= data
;
70 struct drm_encoder_slave
*slave
;
71 struct i2c_adapter
*adap
;
74 conn
->interlace_allowed
= config
->interlace_allowed
;
75 conn
->doublescan_allowed
= config
->doublescan_allowed
;
76 conn
->polled
= config
->polled
;
78 drm_connector_helper_add(conn
, &armada_drm_slave_helper_funcs
);
80 slave
= kzalloc(sizeof(*slave
), GFP_KERNEL
);
84 slave
->base
.possible_crtcs
= config
->crtcs
;
86 adap
= i2c_get_adapter(config
->i2c_adapter_id
);
92 ret
= drm_encoder_init(conn
->dev
, &slave
->base
,
93 &armada_drm_slave_encoder_funcs
,
94 DRM_MODE_ENCODER_TMDS
);
96 DRM_ERROR("unable to init encoder\n");
97 i2c_put_adapter(adap
);
102 ret
= drm_i2c_encoder_init(conn
->dev
, slave
, adap
, &config
->info
);
103 i2c_put_adapter(adap
);
105 DRM_ERROR("unable to init encoder slave\n");
106 armada_drm_slave_destroy(&slave
->base
);
110 drm_encoder_helper_add(&slave
->base
, &drm_slave_encoder_helpers
);
112 ret
= slave
->slave_funcs
->create_resources(&slave
->base
, conn
);
114 armada_drm_slave_destroy(&slave
->base
);
118 ret
= drm_mode_connector_attach_encoder(conn
, &slave
->base
);
120 armada_drm_slave_destroy(&slave
->base
);
124 conn
->encoder
= &slave
->base
;
129 static const struct armada_output_type armada_drm_conn_slave
= {
130 .connector_type
= DRM_MODE_CONNECTOR_HDMIA
,
131 .create
= armada_drm_conn_slave_create
,
132 .set_property
= armada_drm_slave_encoder_set_property
,
135 int armada_drm_connector_slave_create(struct drm_device
*dev
,
136 const struct armada_drm_slave_config
*config
)
138 return armada_output_create(dev
, &armada_drm_conn_slave
, config
);