12066faccSFrancisco Jerez /*
22066faccSFrancisco Jerez * Copyright (C) 2009 Francisco Jerez.
32066faccSFrancisco Jerez * All Rights Reserved.
42066faccSFrancisco Jerez *
52066faccSFrancisco Jerez * Permission is hereby granted, free of charge, to any person obtaining
62066faccSFrancisco Jerez * a copy of this software and associated documentation files (the
72066faccSFrancisco Jerez * "Software"), to deal in the Software without restriction, including
82066faccSFrancisco Jerez * without limitation the rights to use, copy, modify, merge, publish,
92066faccSFrancisco Jerez * distribute, sublicense, and/or sell copies of the Software, and to
102066faccSFrancisco Jerez * permit persons to whom the Software is furnished to do so, subject to
112066faccSFrancisco Jerez * the following conditions:
122066faccSFrancisco Jerez *
132066faccSFrancisco Jerez * The above copyright notice and this permission notice (including the
142066faccSFrancisco Jerez * next paragraph) shall be included in all copies or substantial
152066faccSFrancisco Jerez * portions of the Software.
162066faccSFrancisco Jerez *
172066faccSFrancisco Jerez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
182066faccSFrancisco Jerez * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
192066faccSFrancisco Jerez * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
202066faccSFrancisco Jerez * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
212066faccSFrancisco Jerez * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
222066faccSFrancisco Jerez * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
232066faccSFrancisco Jerez * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
242066faccSFrancisco Jerez *
252066faccSFrancisco Jerez */
262066faccSFrancisco Jerez
272066faccSFrancisco Jerez #ifndef __DRM_ENCODER_SLAVE_H__
282066faccSFrancisco Jerez #define __DRM_ENCODER_SLAVE_H__
292066faccSFrancisco Jerez
30*a204f974SVille Syrjälä #include <linux/i2c.h>
31*a204f974SVille Syrjälä
32a1ce3928SDavid Howells #include <drm/drm_crtc.h>
339338203cSLaurent Pinchart #include <drm/drm_encoder.h>
342066faccSFrancisco Jerez
352066faccSFrancisco Jerez /**
362066faccSFrancisco Jerez * struct drm_encoder_slave_funcs - Entry points exposed by a slave encoder driver
372066faccSFrancisco Jerez * @set_config: Initialize any encoder-specific modesetting parameters.
382066faccSFrancisco Jerez * The meaning of the @params parameter is implementation
392066faccSFrancisco Jerez * dependent. It will usually be a structure with DVO port
402066faccSFrancisco Jerez * data format settings or timings. It's not required for
412066faccSFrancisco Jerez * the new parameters to take effect until the next mode
422066faccSFrancisco Jerez * is set.
432066faccSFrancisco Jerez *
442066faccSFrancisco Jerez * Most of its members are analogous to the function pointers in
452066faccSFrancisco Jerez * &drm_encoder_helper_funcs and they can optionally be used to
462066faccSFrancisco Jerez * initialize the latter. Connector-like methods (e.g. @get_modes and
472066faccSFrancisco Jerez * @set_property) will typically be wrapped around and only be called
482066faccSFrancisco Jerez * if the encoder is the currently selected one for the connector.
492066faccSFrancisco Jerez */
502066faccSFrancisco Jerez struct drm_encoder_slave_funcs {
512066faccSFrancisco Jerez void (*set_config)(struct drm_encoder *encoder,
522066faccSFrancisco Jerez void *params);
532066faccSFrancisco Jerez
542066faccSFrancisco Jerez void (*destroy)(struct drm_encoder *encoder);
552066faccSFrancisco Jerez void (*dpms)(struct drm_encoder *encoder, int mode);
562066faccSFrancisco Jerez void (*save)(struct drm_encoder *encoder);
572066faccSFrancisco Jerez void (*restore)(struct drm_encoder *encoder);
582066faccSFrancisco Jerez bool (*mode_fixup)(struct drm_encoder *encoder,
59e811f5aeSLaurent Pinchart const struct drm_display_mode *mode,
602066faccSFrancisco Jerez struct drm_display_mode *adjusted_mode);
612066faccSFrancisco Jerez int (*mode_valid)(struct drm_encoder *encoder,
622066faccSFrancisco Jerez struct drm_display_mode *mode);
632066faccSFrancisco Jerez void (*mode_set)(struct drm_encoder *encoder,
642066faccSFrancisco Jerez struct drm_display_mode *mode,
652066faccSFrancisco Jerez struct drm_display_mode *adjusted_mode);
662066faccSFrancisco Jerez
672066faccSFrancisco Jerez enum drm_connector_status (*detect)(struct drm_encoder *encoder,
682066faccSFrancisco Jerez struct drm_connector *connector);
692066faccSFrancisco Jerez int (*get_modes)(struct drm_encoder *encoder,
702066faccSFrancisco Jerez struct drm_connector *connector);
712066faccSFrancisco Jerez int (*create_resources)(struct drm_encoder *encoder,
722066faccSFrancisco Jerez struct drm_connector *connector);
732066faccSFrancisco Jerez int (*set_property)(struct drm_encoder *encoder,
742066faccSFrancisco Jerez struct drm_connector *connector,
752066faccSFrancisco Jerez struct drm_property *property,
762066faccSFrancisco Jerez uint64_t val);
772066faccSFrancisco Jerez
782066faccSFrancisco Jerez };
792066faccSFrancisco Jerez
802066faccSFrancisco Jerez /**
812066faccSFrancisco Jerez * struct drm_encoder_slave - Slave encoder struct
822066faccSFrancisco Jerez * @base: DRM encoder object.
832066faccSFrancisco Jerez * @slave_funcs: Slave encoder callbacks.
842066faccSFrancisco Jerez * @slave_priv: Slave encoder private data.
852066faccSFrancisco Jerez * @bus_priv: Bus specific data.
862066faccSFrancisco Jerez *
872066faccSFrancisco Jerez * A &drm_encoder_slave has two sets of callbacks, @slave_funcs and the
882066faccSFrancisco Jerez * ones in @base. The former are never actually called by the common
892066faccSFrancisco Jerez * CRTC code, it's just a convenience for splitting the encoder
902066faccSFrancisco Jerez * functions in an upper, GPU-specific layer and a (hopefully)
912066faccSFrancisco Jerez * GPU-agnostic lower layer: It's the GPU driver responsibility to
922066faccSFrancisco Jerez * call the slave methods when appropriate.
932066faccSFrancisco Jerez *
942066faccSFrancisco Jerez * drm_i2c_encoder_init() provides a way to get an implementation of
952066faccSFrancisco Jerez * this.
962066faccSFrancisco Jerez */
972066faccSFrancisco Jerez struct drm_encoder_slave {
982066faccSFrancisco Jerez struct drm_encoder base;
992066faccSFrancisco Jerez
10016c3719cSVille Syrjälä const struct drm_encoder_slave_funcs *slave_funcs;
1012066faccSFrancisco Jerez void *slave_priv;
1022066faccSFrancisco Jerez void *bus_priv;
1032066faccSFrancisco Jerez };
1042066faccSFrancisco Jerez #define to_encoder_slave(x) container_of((x), struct drm_encoder_slave, base)
1052066faccSFrancisco Jerez
1062066faccSFrancisco Jerez int drm_i2c_encoder_init(struct drm_device *dev,
1072066faccSFrancisco Jerez struct drm_encoder_slave *encoder,
1082066faccSFrancisco Jerez struct i2c_adapter *adap,
1092066faccSFrancisco Jerez const struct i2c_board_info *info);
1102066faccSFrancisco Jerez
1112066faccSFrancisco Jerez
1122066faccSFrancisco Jerez /**
1132066faccSFrancisco Jerez * struct drm_i2c_encoder_driver
1142066faccSFrancisco Jerez *
1152066faccSFrancisco Jerez * Describes a device driver for an encoder connected to the GPU
1162066faccSFrancisco Jerez * through an I2C bus. In addition to the entry points in @i2c_driver
1172066faccSFrancisco Jerez * an @encoder_init function should be provided. It will be called to
1182066faccSFrancisco Jerez * give the driver an opportunity to allocate any per-encoder data
1192066faccSFrancisco Jerez * structures and to initialize the @slave_funcs and (optionally)
1202066faccSFrancisco Jerez * @slave_priv members of @encoder.
1212066faccSFrancisco Jerez */
1222066faccSFrancisco Jerez struct drm_i2c_encoder_driver {
1232066faccSFrancisco Jerez struct i2c_driver i2c_driver;
1242066faccSFrancisco Jerez
1252066faccSFrancisco Jerez int (*encoder_init)(struct i2c_client *client,
1262066faccSFrancisco Jerez struct drm_device *dev,
1272066faccSFrancisco Jerez struct drm_encoder_slave *encoder);
1282066faccSFrancisco Jerez
1292066faccSFrancisco Jerez };
1302066faccSFrancisco Jerez #define to_drm_i2c_encoder_driver(x) container_of((x), \
1312066faccSFrancisco Jerez struct drm_i2c_encoder_driver, \
1322066faccSFrancisco Jerez i2c_driver)
1332066faccSFrancisco Jerez
1342066faccSFrancisco Jerez /**
1352066faccSFrancisco Jerez * drm_i2c_encoder_get_client - Get the I2C client corresponding to an encoder
1362066faccSFrancisco Jerez */
drm_i2c_encoder_get_client(struct drm_encoder * encoder)1372066faccSFrancisco Jerez static inline struct i2c_client *drm_i2c_encoder_get_client(struct drm_encoder *encoder)
1382066faccSFrancisco Jerez {
1392066faccSFrancisco Jerez return (struct i2c_client *)to_encoder_slave(encoder)->bus_priv;
1402066faccSFrancisco Jerez }
1412066faccSFrancisco Jerez
1422066faccSFrancisco Jerez /**
1432066faccSFrancisco Jerez * drm_i2c_encoder_register - Register an I2C encoder driver
1442066faccSFrancisco Jerez * @owner: Module containing the driver.
1452066faccSFrancisco Jerez * @driver: Driver to be registered.
1462066faccSFrancisco Jerez */
drm_i2c_encoder_register(struct module * owner,struct drm_i2c_encoder_driver * driver)1472066faccSFrancisco Jerez static inline int drm_i2c_encoder_register(struct module *owner,
1482066faccSFrancisco Jerez struct drm_i2c_encoder_driver *driver)
1492066faccSFrancisco Jerez {
1502066faccSFrancisco Jerez return i2c_register_driver(owner, &driver->i2c_driver);
1512066faccSFrancisco Jerez }
1522066faccSFrancisco Jerez
1532066faccSFrancisco Jerez /**
1542066faccSFrancisco Jerez * drm_i2c_encoder_unregister - Unregister an I2C encoder driver
1552066faccSFrancisco Jerez * @driver: Driver to be unregistered.
1562066faccSFrancisco Jerez */
drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver * driver)1572066faccSFrancisco Jerez static inline void drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver *driver)
1582066faccSFrancisco Jerez {
159949ef70eSPekka Paalanen i2c_del_driver(&driver->i2c_driver);
1602066faccSFrancisco Jerez }
1612066faccSFrancisco Jerez
1622066faccSFrancisco Jerez void drm_i2c_encoder_destroy(struct drm_encoder *encoder);
1632066faccSFrancisco Jerez
164a7c47d6dSRob Clark
165a7c47d6dSRob Clark /*
166a7c47d6dSRob Clark * Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
167a7c47d6dSRob Clark */
168a7c47d6dSRob Clark
169a7c47d6dSRob Clark void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode);
170a7c47d6dSRob Clark bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder,
171a7c47d6dSRob Clark const struct drm_display_mode *mode,
172a7c47d6dSRob Clark struct drm_display_mode *adjusted_mode);
173a7c47d6dSRob Clark void drm_i2c_encoder_prepare(struct drm_encoder *encoder);
174a7c47d6dSRob Clark void drm_i2c_encoder_commit(struct drm_encoder *encoder);
175a7c47d6dSRob Clark void drm_i2c_encoder_mode_set(struct drm_encoder *encoder,
176a7c47d6dSRob Clark struct drm_display_mode *mode,
177a7c47d6dSRob Clark struct drm_display_mode *adjusted_mode);
178a7c47d6dSRob Clark enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder,
179a7c47d6dSRob Clark struct drm_connector *connector);
180a7c47d6dSRob Clark void drm_i2c_encoder_save(struct drm_encoder *encoder);
181a7c47d6dSRob Clark void drm_i2c_encoder_restore(struct drm_encoder *encoder);
182a7c47d6dSRob Clark
183a7c47d6dSRob Clark
1842066faccSFrancisco Jerez #endif
185