xref: /dflybsd-src/sys/dev/drm/drm_encoder_slave.c (revision aee94f86171368465eaa15d649743f13cea3363a)
1*aee94f86SFrançois Tigeot /*
2*aee94f86SFrançois Tigeot  * Copyright (C) 2009 Francisco Jerez.
3*aee94f86SFrançois Tigeot  * All Rights Reserved.
4*aee94f86SFrançois Tigeot  *
5*aee94f86SFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining
6*aee94f86SFrançois Tigeot  * a copy of this software and associated documentation files (the
7*aee94f86SFrançois Tigeot  * "Software"), to deal in the Software without restriction, including
8*aee94f86SFrançois Tigeot  * without limitation the rights to use, copy, modify, merge, publish,
9*aee94f86SFrançois Tigeot  * distribute, sublicense, and/or sell copies of the Software, and to
10*aee94f86SFrançois Tigeot  * permit persons to whom the Software is furnished to do so, subject to
11*aee94f86SFrançois Tigeot  * the following conditions:
12*aee94f86SFrançois Tigeot  *
13*aee94f86SFrançois Tigeot  * The above copyright notice and this permission notice (including the
14*aee94f86SFrançois Tigeot  * next paragraph) shall be included in all copies or substantial
15*aee94f86SFrançois Tigeot  * portions of the Software.
16*aee94f86SFrançois Tigeot  *
17*aee94f86SFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18*aee94f86SFrançois Tigeot  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19*aee94f86SFrançois Tigeot  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20*aee94f86SFrançois Tigeot  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21*aee94f86SFrançois Tigeot  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22*aee94f86SFrançois Tigeot  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23*aee94f86SFrançois Tigeot  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24*aee94f86SFrançois Tigeot  *
25*aee94f86SFrançois Tigeot  */
26*aee94f86SFrançois Tigeot 
27*aee94f86SFrançois Tigeot #include <linux/module.h>
28*aee94f86SFrançois Tigeot 
29*aee94f86SFrançois Tigeot #include <drm/drm_encoder_slave.h>
30*aee94f86SFrançois Tigeot 
31*aee94f86SFrançois Tigeot #if 0
32*aee94f86SFrançois Tigeot /**
33*aee94f86SFrançois Tigeot  * drm_i2c_encoder_init - Initialize an I2C slave encoder
34*aee94f86SFrançois Tigeot  * @dev:	DRM device.
35*aee94f86SFrançois Tigeot  * @encoder:    Encoder to be attached to the I2C device. You aren't
36*aee94f86SFrançois Tigeot  *		required to have called drm_encoder_init() before.
37*aee94f86SFrançois Tigeot  * @adap:	I2C adapter that will be used to communicate with
38*aee94f86SFrançois Tigeot  *		the device.
39*aee94f86SFrançois Tigeot  * @info:	Information that will be used to create the I2C device.
40*aee94f86SFrançois Tigeot  *		Required fields are @addr and @type.
41*aee94f86SFrançois Tigeot  *
42*aee94f86SFrançois Tigeot  * Create an I2C device on the specified bus (the module containing its
43*aee94f86SFrançois Tigeot  * driver is transparently loaded) and attach it to the specified
44*aee94f86SFrançois Tigeot  * &drm_encoder_slave. The @slave_funcs field will be initialized with
45*aee94f86SFrançois Tigeot  * the hooks provided by the slave driver.
46*aee94f86SFrançois Tigeot  *
47*aee94f86SFrançois Tigeot  * If @info->platform_data is non-NULL it will be used as the initial
48*aee94f86SFrançois Tigeot  * slave config.
49*aee94f86SFrançois Tigeot  *
50*aee94f86SFrançois Tigeot  * Returns 0 on success or a negative errno on failure, in particular,
51*aee94f86SFrançois Tigeot  * -ENODEV is returned when no matching driver is found.
52*aee94f86SFrançois Tigeot  */
53*aee94f86SFrançois Tigeot int drm_i2c_encoder_init(struct drm_device *dev,
54*aee94f86SFrançois Tigeot 			 struct drm_encoder_slave *encoder,
55*aee94f86SFrançois Tigeot 			 struct i2c_adapter *adap,
56*aee94f86SFrançois Tigeot 			 const struct i2c_board_info *info)
57*aee94f86SFrançois Tigeot {
58*aee94f86SFrançois Tigeot 	struct module *module = NULL;
59*aee94f86SFrançois Tigeot 	struct i2c_client *client;
60*aee94f86SFrançois Tigeot 	struct drm_i2c_encoder_driver *encoder_drv;
61*aee94f86SFrançois Tigeot 	int err = 0;
62*aee94f86SFrançois Tigeot 
63*aee94f86SFrançois Tigeot 	request_module("%s%s", I2C_MODULE_PREFIX, info->type);
64*aee94f86SFrançois Tigeot 
65*aee94f86SFrançois Tigeot 	client = i2c_new_device(adap, info);
66*aee94f86SFrançois Tigeot 	if (!client) {
67*aee94f86SFrançois Tigeot 		err = -ENOMEM;
68*aee94f86SFrançois Tigeot 		goto fail;
69*aee94f86SFrançois Tigeot 	}
70*aee94f86SFrançois Tigeot 
71*aee94f86SFrançois Tigeot 	if (!client->dev.driver) {
72*aee94f86SFrançois Tigeot 		err = -ENODEV;
73*aee94f86SFrançois Tigeot 		goto fail_unregister;
74*aee94f86SFrançois Tigeot 	}
75*aee94f86SFrançois Tigeot 
76*aee94f86SFrançois Tigeot 	module = client->dev.driver->owner;
77*aee94f86SFrançois Tigeot 	if (!try_module_get(module)) {
78*aee94f86SFrançois Tigeot 		err = -ENODEV;
79*aee94f86SFrançois Tigeot 		goto fail_unregister;
80*aee94f86SFrançois Tigeot 	}
81*aee94f86SFrançois Tigeot 
82*aee94f86SFrançois Tigeot 	encoder->bus_priv = client;
83*aee94f86SFrançois Tigeot 
84*aee94f86SFrançois Tigeot 	encoder_drv = to_drm_i2c_encoder_driver(to_i2c_driver(client->dev.driver));
85*aee94f86SFrançois Tigeot 
86*aee94f86SFrançois Tigeot 	err = encoder_drv->encoder_init(client, dev, encoder);
87*aee94f86SFrançois Tigeot 	if (err)
88*aee94f86SFrançois Tigeot 		goto fail_unregister;
89*aee94f86SFrançois Tigeot 
90*aee94f86SFrançois Tigeot 	if (info->platform_data)
91*aee94f86SFrançois Tigeot 		encoder->slave_funcs->set_config(&encoder->base,
92*aee94f86SFrançois Tigeot 						 info->platform_data);
93*aee94f86SFrançois Tigeot 
94*aee94f86SFrançois Tigeot 	return 0;
95*aee94f86SFrançois Tigeot 
96*aee94f86SFrançois Tigeot fail_unregister:
97*aee94f86SFrançois Tigeot 	i2c_unregister_device(client);
98*aee94f86SFrançois Tigeot 	module_put(module);
99*aee94f86SFrançois Tigeot fail:
100*aee94f86SFrançois Tigeot 	return err;
101*aee94f86SFrançois Tigeot }
102*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_init);
103*aee94f86SFrançois Tigeot 
104*aee94f86SFrançois Tigeot /**
105*aee94f86SFrançois Tigeot  * drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder
106*aee94f86SFrançois Tigeot  * @drm_encoder:	Encoder to be unregistered.
107*aee94f86SFrançois Tigeot  *
108*aee94f86SFrançois Tigeot  * This should be called from the @destroy method of an I2C slave
109*aee94f86SFrançois Tigeot  * encoder driver once I2C access is no longer needed.
110*aee94f86SFrançois Tigeot  */
111*aee94f86SFrançois Tigeot void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
112*aee94f86SFrançois Tigeot {
113*aee94f86SFrançois Tigeot 	struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
114*aee94f86SFrançois Tigeot 	struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
115*aee94f86SFrançois Tigeot 	struct module *module = client->dev.driver->owner;
116*aee94f86SFrançois Tigeot 
117*aee94f86SFrançois Tigeot 	i2c_unregister_device(client);
118*aee94f86SFrançois Tigeot 	encoder->bus_priv = NULL;
119*aee94f86SFrançois Tigeot 
120*aee94f86SFrançois Tigeot 	module_put(module);
121*aee94f86SFrançois Tigeot }
122*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_destroy);
123*aee94f86SFrançois Tigeot #endif
124*aee94f86SFrançois Tigeot 
125*aee94f86SFrançois Tigeot /*
126*aee94f86SFrançois Tigeot  * Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
127*aee94f86SFrançois Tigeot  */
128*aee94f86SFrançois Tigeot 
129*aee94f86SFrançois Tigeot static inline const struct drm_encoder_slave_funcs *
130*aee94f86SFrançois Tigeot get_slave_funcs(struct drm_encoder *enc)
131*aee94f86SFrançois Tigeot {
132*aee94f86SFrançois Tigeot 	return to_encoder_slave(enc)->slave_funcs;
133*aee94f86SFrançois Tigeot }
134*aee94f86SFrançois Tigeot 
135*aee94f86SFrançois Tigeot void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode)
136*aee94f86SFrançois Tigeot {
137*aee94f86SFrançois Tigeot 	get_slave_funcs(encoder)->dpms(encoder, mode);
138*aee94f86SFrançois Tigeot }
139*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_dpms);
140*aee94f86SFrançois Tigeot 
141*aee94f86SFrançois Tigeot bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
142*aee94f86SFrançois Tigeot 		const struct drm_display_mode *mode,
143*aee94f86SFrançois Tigeot 		struct drm_display_mode *adjusted_mode)
144*aee94f86SFrançois Tigeot {
145*aee94f86SFrançois Tigeot 	return get_slave_funcs(encoder)->mode_fixup(encoder, mode, adjusted_mode);
146*aee94f86SFrançois Tigeot }
147*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup);
148*aee94f86SFrançois Tigeot 
149*aee94f86SFrançois Tigeot void drm_i2c_encoder_prepare(struct drm_encoder *encoder)
150*aee94f86SFrançois Tigeot {
151*aee94f86SFrançois Tigeot 	drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
152*aee94f86SFrançois Tigeot }
153*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_prepare);
154*aee94f86SFrançois Tigeot 
155*aee94f86SFrançois Tigeot void drm_i2c_encoder_commit(struct drm_encoder *encoder)
156*aee94f86SFrançois Tigeot {
157*aee94f86SFrançois Tigeot 	drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
158*aee94f86SFrançois Tigeot }
159*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_commit);
160*aee94f86SFrançois Tigeot 
161*aee94f86SFrançois Tigeot void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
162*aee94f86SFrançois Tigeot 		struct drm_display_mode *mode,
163*aee94f86SFrançois Tigeot 		struct drm_display_mode *adjusted_mode)
164*aee94f86SFrançois Tigeot {
165*aee94f86SFrançois Tigeot 	get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode);
166*aee94f86SFrançois Tigeot }
167*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_mode_set);
168*aee94f86SFrançois Tigeot 
169*aee94f86SFrançois Tigeot enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
170*aee94f86SFrançois Tigeot 	    struct drm_connector *connector)
171*aee94f86SFrançois Tigeot {
172*aee94f86SFrançois Tigeot 	return get_slave_funcs(encoder)->detect(encoder, connector);
173*aee94f86SFrançois Tigeot }
174*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_detect);
175*aee94f86SFrançois Tigeot 
176*aee94f86SFrançois Tigeot void drm_i2c_encoder_save(struct drm_encoder *encoder)
177*aee94f86SFrançois Tigeot {
178*aee94f86SFrançois Tigeot 	get_slave_funcs(encoder)->save(encoder);
179*aee94f86SFrançois Tigeot }
180*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_save);
181*aee94f86SFrançois Tigeot 
182*aee94f86SFrançois Tigeot void drm_i2c_encoder_restore(struct drm_encoder *encoder)
183*aee94f86SFrançois Tigeot {
184*aee94f86SFrançois Tigeot 	get_slave_funcs(encoder)->restore(encoder);
185*aee94f86SFrançois Tigeot }
186*aee94f86SFrançois Tigeot EXPORT_SYMBOL(drm_i2c_encoder_restore);
187