1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/module.h>
28
29#include <drm/drm_encoder_slave.h>
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52int drm_i2c_encoder_init(struct drm_device *dev,
53 struct drm_encoder_slave *encoder,
54 struct i2c_adapter *adap,
55 const struct i2c_board_info *info)
56{
57 struct module *module = NULL;
58 struct i2c_client *client;
59 struct drm_i2c_encoder_driver *encoder_drv;
60 int err = 0;
61
62 request_module("%s%s", I2C_MODULE_PREFIX, info->type);
63
64 client = i2c_new_device(adap, info);
65 if (!client) {
66 err = -ENOMEM;
67 goto fail;
68 }
69
70 if (!client->dev.driver) {
71 err = -ENODEV;
72 goto fail_unregister;
73 }
74
75 module = client->dev.driver->owner;
76 if (!try_module_get(module)) {
77 err = -ENODEV;
78 goto fail_unregister;
79 }
80
81 encoder->bus_priv = client;
82
83 encoder_drv = to_drm_i2c_encoder_driver(to_i2c_driver(client->dev.driver));
84
85 err = encoder_drv->encoder_init(client, dev, encoder);
86 if (err)
87 goto fail_unregister;
88
89 if (info->platform_data)
90 encoder->slave_funcs->set_config(&encoder->base,
91 info->platform_data);
92
93 return 0;
94
95fail_unregister:
96 i2c_unregister_device(client);
97 module_put(module);
98fail:
99 return err;
100}
101EXPORT_SYMBOL(drm_i2c_encoder_init);
102
103
104
105
106
107
108
109
110void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
111{
112 struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
113 struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
114 struct module *module = client->dev.driver->owner;
115
116 i2c_unregister_device(client);
117 encoder->bus_priv = NULL;
118
119 module_put(module);
120}
121EXPORT_SYMBOL(drm_i2c_encoder_destroy);
122
123
124
125
126
127static inline const struct drm_encoder_slave_funcs *
128get_slave_funcs(struct drm_encoder *enc)
129{
130 return to_encoder_slave(enc)->slave_funcs;
131}
132
133void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode)
134{
135 get_slave_funcs(encoder)->dpms(encoder, mode);
136}
137EXPORT_SYMBOL(drm_i2c_encoder_dpms);
138
139bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
140 const struct drm_display_mode *mode,
141 struct drm_display_mode *adjusted_mode)
142{
143 if (!get_slave_funcs(encoder)->mode_fixup)
144 return true;
145
146 return get_slave_funcs(encoder)->mode_fixup(encoder, mode, adjusted_mode);
147}
148EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup);
149
150void drm_i2c_encoder_prepare(struct drm_encoder *encoder)
151{
152 drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
153}
154EXPORT_SYMBOL(drm_i2c_encoder_prepare);
155
156void drm_i2c_encoder_commit(struct drm_encoder *encoder)
157{
158 drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
159}
160EXPORT_SYMBOL(drm_i2c_encoder_commit);
161
162void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
163 struct drm_display_mode *mode,
164 struct drm_display_mode *adjusted_mode)
165{
166 get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode);
167}
168EXPORT_SYMBOL(drm_i2c_encoder_mode_set);
169
170enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
171 struct drm_connector *connector)
172{
173 return get_slave_funcs(encoder)->detect(encoder, connector);
174}
175EXPORT_SYMBOL(drm_i2c_encoder_detect);
176
177void drm_i2c_encoder_save(struct drm_encoder *encoder)
178{
179 get_slave_funcs(encoder)->save(encoder);
180}
181EXPORT_SYMBOL(drm_i2c_encoder_save);
182
183void drm_i2c_encoder_restore(struct drm_encoder *encoder)
184{
185 get_slave_funcs(encoder)->restore(encoder);
186}
187EXPORT_SYMBOL(drm_i2c_encoder_restore);
188