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 __NOUVEAU_ENCODER_I2C_H__ 28 #define __NOUVEAU_ENCODER_I2C_H__ 29 30 #include <linux/i2c.h> 31 32 #include <drm/drm_crtc.h> 33 #include <drm/drm_encoder.h> 34 35 /** 36 * struct nouveau_i2c_encoder_funcs - Entry points exposed by a I2C 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 nouveau_i2c_encoder_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. 62 */ 63 void (*dpms)(struct drm_encoder *encoder, int mode); 64 65 /** 66 * @save: Save state. Wrapped by nouveau_i2c_encoder_save(). 67 */ 68 void (*save)(struct drm_encoder *encoder); 69 70 /** 71 * @restore: Restore state. Wrapped by nouveau_i2c_encoder_restore(). 72 */ 73 void (*restore)(struct drm_encoder *encoder); 74 75 /** 76 * @mode_fixup: Analogous to &drm_encoder_helper_funcs @mode_fixup 77 * callback. Wrapped by nouveau_i2c_encoder_mode_fixup(). 78 */ 79 bool (*mode_fixup)(struct drm_encoder *encoder, 80 const struct drm_display_mode *mode, 81 struct drm_display_mode *adjusted_mode); 82 83 /** 84 * @mode_valid: Analogous to &drm_encoder_helper_funcs @mode_valid. 85 */ 86 int (*mode_valid)(struct drm_encoder *encoder, 87 const struct drm_display_mode *mode); 88 /** 89 * @mode_set: Analogous to &drm_encoder_helper_funcs @mode_set 90 * callback. 91 */ 92 void (*mode_set)(struct drm_encoder *encoder, 93 struct drm_display_mode *mode, 94 struct drm_display_mode *adjusted_mode); 95 96 /** 97 * @detect: Analogous to &drm_encoder_helper_funcs @detect 98 * callback. Wrapped by nouveau_i2c_encoder_detect(). 99 */ 100 enum drm_connector_status (*detect)(struct drm_encoder *encoder, 101 struct drm_connector *connector); 102 /** 103 * @get_modes: Get modes. 104 */ 105 int (*get_modes)(struct drm_encoder *encoder, 106 struct drm_connector *connector); 107 /** 108 * @create_resources: Create resources. 109 */ 110 int (*create_resources)(struct drm_encoder *encoder, 111 struct drm_connector *connector); 112 /** 113 * @set_property: Set property. 114 */ 115 int (*set_property)(struct drm_encoder *encoder, 116 struct drm_connector *connector, 117 struct drm_property *property, 118 uint64_t val); 119 }; 120 121 /** 122 * struct nouveau_i2c_encoder - I2C encoder struct 123 * 124 * A &nouveau_i2c_encoder has two sets of callbacks, @encoder_i2c_funcs and the 125 * ones in @base. The former are never actually called by the common 126 * CRTC code, it's just a convenience for splitting the encoder 127 * functions in an upper, GPU-specific layer and a (hopefully) 128 * GPU-agnostic lower layer: It's the GPU driver responsibility to 129 * call the nouveau_i2c_encoder methods when appropriate. 130 * 131 * nouveau_i2c_encoder_init() provides a way to get an implementation of 132 * this. 133 */ 134 struct nouveau_i2c_encoder { 135 /** 136 * @base: DRM encoder object. 137 */ 138 struct drm_encoder base; 139 140 /** 141 * @encoder_i2c_funcs: I2C encoder callbacks. 142 */ 143 const struct nouveau_i2c_encoder_funcs *encoder_i2c_funcs; 144 145 /** 146 * @encoder_i2c_priv: I2C encoder private data. 147 */ 148 void *encoder_i2c_priv; 149 150 /** 151 * @i2c_client: corresponding I2C client structure 152 */ 153 struct i2c_client *i2c_client; 154 }; 155 156 #define to_encoder_i2c(x) container_of((x), struct nouveau_i2c_encoder, base) 157 158 int nouveau_i2c_encoder_init(struct drm_device *dev, 159 struct nouveau_i2c_encoder *encoder, 160 struct i2c_adapter *adap, 161 const struct i2c_board_info *info); 162 163 static inline const struct nouveau_i2c_encoder_funcs * 164 get_encoder_i2c_funcs(struct drm_encoder *enc) 165 { 166 return to_encoder_i2c(enc)->encoder_i2c_funcs; 167 } 168 169 /** 170 * struct nouveau_i2c_encoder_driver 171 * 172 * Describes a device driver for an encoder connected to the GPU through an I2C 173 * bus. 174 */ 175 struct nouveau_i2c_encoder_driver { 176 /** 177 * @i2c_driver: I2C device driver description. 178 */ 179 struct i2c_driver i2c_driver; 180 181 /** 182 * @encoder_init: Callback to allocate any per-encoder data structures 183 * and to initialize the @encoder_i2c_funcs and (optionally) @encoder_i2c_priv 184 * members of @encoder. 185 */ 186 int (*encoder_init)(struct i2c_client *client, 187 struct drm_device *dev, 188 struct nouveau_i2c_encoder *encoder); 189 190 }; 191 192 #define to_nouveau_i2c_encoder_driver(x) container_of((x), \ 193 struct nouveau_i2c_encoder_driver, \ 194 i2c_driver) 195 196 /** 197 * nouveau_i2c_encoder_get_client - Get the I2C client corresponding to an encoder 198 * @encoder: The encoder 199 */ 200 static inline struct i2c_client *nouveau_i2c_encoder_get_client(struct drm_encoder *encoder) 201 { 202 return to_encoder_i2c(encoder)->i2c_client; 203 } 204 205 void nouveau_i2c_encoder_destroy(struct drm_encoder *encoder); 206 207 /* 208 * Wrapper fxns which can be plugged in to drm_encoder_helper_funcs: 209 */ 210 211 bool nouveau_i2c_encoder_mode_fixup(struct drm_encoder *encoder, 212 const struct drm_display_mode *mode, 213 struct drm_display_mode *adjusted_mode); 214 enum drm_connector_status nouveau_i2c_encoder_detect(struct drm_encoder *encoder, 215 struct drm_connector *connector); 216 void nouveau_i2c_encoder_save(struct drm_encoder *encoder); 217 void nouveau_i2c_encoder_restore(struct drm_encoder *encoder); 218 219 220 #endif 221