1  /*
2   * Copyright (C) 2009 Francisco Jerez.
3   * All Rights Reserved.
4   *
5   * Permission is hereby granted, free of charge, to any person obtaining
6   * a copy of this software and associated documentation files (the
7   * "Software"), to deal in the Software without restriction, including
8   * without limitation the rights to use, copy, modify, merge, publish,
9   * distribute, sublicense, and/or sell copies of the Software, and to
10   * permit persons to whom the Software is furnished to do so, subject to
11   * the following conditions:
12   *
13   * The above copyright notice and this permission notice (including the
14   * next paragraph) shall be included in all copies or substantial
15   * portions of the Software.
16   *
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20   * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24   *
25   */
26  
27  #ifndef __DRM_ENCODER_SLAVE_H__
28  #define __DRM_ENCODER_SLAVE_H__
29  
30  #include <linux/i2c.h>
31  
32  #include <drm/drm_crtc.h>
33  #include <drm/drm_encoder.h>
34  
35  /**
36   * struct drm_encoder_slave_funcs - Entry points exposed by a slave encoder driver
37   *
38   * Most of its members are analogous to the function pointers in
39   * &drm_encoder_helper_funcs and they can optionally be used to
40   * initialize the latter. Connector-like methods (e.g. @get_modes and
41   * @set_property) will typically be wrapped around and only be called
42   * if the encoder is the currently selected one for the connector.
43   */
44  struct drm_encoder_slave_funcs {
45  	/**
46  	 * @set_config: Initialize any encoder-specific modesetting parameters.
47  	 * The meaning of the @params parameter is implementation dependent. It
48  	 * will usually be a structure with DVO port data format settings or
49  	 * timings. It's not required for the new parameters to take effect
50  	 * until the next mode is set.
51  	 */
52  	void (*set_config)(struct drm_encoder *encoder,
53  			   void *params);
54  
55  	/**
56  	 * @destroy: Analogous to &drm_encoder_funcs @destroy callback.
57  	 */
58  	void (*destroy)(struct drm_encoder *encoder);
59  
60  	/**
61  	 * @dpms: Analogous to &drm_encoder_helper_funcs @dpms callback. Wrapped
62  	 * by drm_i2c_encoder_dpms().
63  	 */
64  	void (*dpms)(struct drm_encoder *encoder, int mode);
65  
66  	/**
67  	 * @save: Save state. Wrapped by drm_i2c_encoder_save().
68  	 */
69  	void (*save)(struct drm_encoder *encoder);
70  
71  	/**
72  	 * @restore: Restore state. Wrapped by drm_i2c_encoder_restore().
73  	 */
74  	void (*restore)(struct drm_encoder *encoder);
75  
76  	/**
77  	 * @mode_fixup: Analogous to &drm_encoder_helper_funcs @mode_fixup
78  	 * callback. Wrapped by drm_i2c_encoder_mode_fixup().
79  	 */
80  	bool (*mode_fixup)(struct drm_encoder *encoder,
81  			   const struct drm_display_mode *mode,
82  			   struct drm_display_mode *adjusted_mode);
83  
84  	/**
85  	 * @mode_valid: Analogous to &drm_encoder_helper_funcs @mode_valid.
86  	 */
87  	int (*mode_valid)(struct drm_encoder *encoder,
88  			  struct drm_display_mode *mode);
89  	/**
90  	 * @mode_set: Analogous to &drm_encoder_helper_funcs @mode_set
91  	 * callback. Wrapped by drm_i2c_encoder_mode_set().
92  	 */
93  	void (*mode_set)(struct drm_encoder *encoder,
94  			 struct drm_display_mode *mode,
95  			 struct drm_display_mode *adjusted_mode);
96  
97  	/**
98  	 * @detect: Analogous to &drm_encoder_helper_funcs @detect
99  	 * callback. Wrapped by drm_i2c_encoder_detect().
100  	 */
101  	enum drm_connector_status (*detect)(struct drm_encoder *encoder,
102  					    struct drm_connector *connector);
103  	/**
104  	 * @get_modes: Get modes.
105  	 */
106  	int (*get_modes)(struct drm_encoder *encoder,
107  			 struct drm_connector *connector);
108  	/**
109  	 * @create_resources: Create resources.
110  	 */
111  	int (*create_resources)(struct drm_encoder *encoder,
112  				 struct drm_connector *connector);
113  	/**
114  	 * @set_property: Set property.
115  	 */
116  	int (*set_property)(struct drm_encoder *encoder,
117  			    struct drm_connector *connector,
118  			    struct drm_property *property,
119  			    uint64_t val);
120  };
121  
122  /**
123   * struct drm_encoder_slave - Slave encoder struct
124   *
125   * A &drm_encoder_slave has two sets of callbacks, @slave_funcs and the
126   * ones in @base. The former are never actually called by the common
127   * CRTC code, it's just a convenience for splitting the encoder
128   * functions in an upper, GPU-specific layer and a (hopefully)
129   * GPU-agnostic lower layer: It's the GPU driver responsibility to
130   * call the slave methods when appropriate.
131   *
132   * drm_i2c_encoder_init() provides a way to get an implementation of
133   * this.
134   */
135  struct drm_encoder_slave {
136  	/**
137  	 * @base: DRM encoder object.
138  	 */
139  	struct drm_encoder base;
140  
141  	/**
142  	 * @slave_funcs: Slave encoder callbacks.
143  	 */
144  	const struct drm_encoder_slave_funcs *slave_funcs;
145  
146  	/**
147  	 * @slave_priv: Slave encoder private data.
148  	 */
149  	void *slave_priv;
150  
151  	/**
152  	 * @bus_priv: Bus specific data.
153  	 */
154  	void *bus_priv;
155  };
156  #define to_encoder_slave(x) container_of((x), struct drm_encoder_slave, base)
157  
158  int drm_i2c_encoder_init(struct drm_device *dev,
159  			 struct drm_encoder_slave *encoder,
160  			 struct i2c_adapter *adap,
161  			 const struct i2c_board_info *info);
162  
163  
164  /**
165   * struct drm_i2c_encoder_driver
166   *
167   * Describes a device driver for an encoder connected to the GPU through an I2C
168   * bus.
169   */
170  struct drm_i2c_encoder_driver {
171  	/**
172  	 * @i2c_driver: I2C device driver description.
173  	 */
174  	struct i2c_driver i2c_driver;
175  
176  	/**
177  	 * @encoder_init: Callback to allocate any per-encoder data structures
178  	 * and to initialize the @slave_funcs and (optionally) @slave_priv
179  	 * members of @encoder.
180  	 */
181  	int (*encoder_init)(struct i2c_client *client,
182  			    struct drm_device *dev,
183  			    struct drm_encoder_slave *encoder);
184  
185  };
186  #define to_drm_i2c_encoder_driver(x) container_of((x),			\
187  						  struct drm_i2c_encoder_driver, \
188  						  i2c_driver)
189  
190  /**
191   * drm_i2c_encoder_get_client - Get the I2C client corresponding to an encoder
192   * @encoder: The encoder
193   */
drm_i2c_encoder_get_client(struct drm_encoder * encoder)194  static inline struct i2c_client *drm_i2c_encoder_get_client(struct drm_encoder *encoder)
195  {
196  	return (struct i2c_client *)to_encoder_slave(encoder)->bus_priv;
197  }
198  
199  /**
200   * drm_i2c_encoder_register - Register an I2C encoder driver
201   * @owner:	Module containing the driver.
202   * @driver:	Driver to be registered.
203   */
drm_i2c_encoder_register(struct module * owner,struct drm_i2c_encoder_driver * driver)204  static inline int drm_i2c_encoder_register(struct module *owner,
205  					   struct drm_i2c_encoder_driver *driver)
206  {
207  	return i2c_register_driver(owner, &driver->i2c_driver);
208  }
209  
210  /**
211   * drm_i2c_encoder_unregister - Unregister an I2C encoder driver
212   * @driver:	Driver to be unregistered.
213   */
drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver * driver)214  static inline void drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver *driver)
215  {
216  	i2c_del_driver(&driver->i2c_driver);
217  }
218  
219  void drm_i2c_encoder_destroy(struct drm_encoder *encoder);
220  
221  
222  /*
223   * Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
224   */
225  
226  void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode);
227  bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
228  		const struct drm_display_mode *mode,
229  		struct drm_display_mode *adjusted_mode);
230  void drm_i2c_encoder_prepare(struct drm_encoder *encoder);
231  void drm_i2c_encoder_commit(struct drm_encoder *encoder);
232  void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
233  		struct drm_display_mode *mode,
234  		struct drm_display_mode *adjusted_mode);
235  enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
236  	    struct drm_connector *connector);
237  void drm_i2c_encoder_save(struct drm_encoder *encoder);
238  void drm_i2c_encoder_restore(struct drm_encoder *encoder);
239  
240  
241  #endif
242