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