1 1.2 riastrad /* $NetBSD: drm_mipi_dsi.c,v 1.3 2021/12/18 23:44:57 riastradh Exp $ */ 2 1.2 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * MIPI DSI Bus 5 1.1 riastrad * 6 1.1 riastrad * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd. 7 1.1 riastrad * Andrzej Hajda <a.hajda (at) samsung.com> 8 1.1 riastrad * 9 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 10 1.1 riastrad * copy of this software and associated documentation files (the 11 1.1 riastrad * "Software"), to deal in the Software without restriction, including 12 1.1 riastrad * without limitation the rights to use, copy, modify, merge, publish, 13 1.1 riastrad * distribute, sub license, and/or sell copies of the Software, and to 14 1.1 riastrad * permit persons to whom the Software is furnished to do so, subject to 15 1.1 riastrad * the following conditions: 16 1.1 riastrad * 17 1.1 riastrad * The above copyright notice and this permission notice (including the 18 1.1 riastrad * next paragraph) shall be included in all copies or substantial portions 19 1.1 riastrad * of the Software. 20 1.1 riastrad * 21 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 24 1.1 riastrad * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 25 1.1 riastrad * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 26 1.1 riastrad * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 27 1.1 riastrad * USE OR OTHER DEALINGS IN THE SOFTWARE. 28 1.1 riastrad */ 29 1.1 riastrad 30 1.2 riastrad #include <sys/cdefs.h> 31 1.2 riastrad __KERNEL_RCSID(0, "$NetBSD: drm_mipi_dsi.c,v 1.3 2021/12/18 23:44:57 riastradh Exp $"); 32 1.2 riastrad 33 1.1 riastrad #include <drm/drm_mipi_dsi.h> 34 1.1 riastrad 35 1.1 riastrad #include <linux/device.h> 36 1.1 riastrad #include <linux/module.h> 37 1.1 riastrad #include <linux/of_device.h> 38 1.1 riastrad #include <linux/pm_runtime.h> 39 1.1 riastrad #include <linux/slab.h> 40 1.1 riastrad 41 1.3 riastrad #include <drm/drm_dsc.h> 42 1.1 riastrad #include <video/mipi_display.h> 43 1.1 riastrad 44 1.2 riastrad /** 45 1.2 riastrad * DOC: dsi helpers 46 1.2 riastrad * 47 1.2 riastrad * These functions contain some common logic and helpers to deal with MIPI DSI 48 1.2 riastrad * peripherals. 49 1.2 riastrad * 50 1.2 riastrad * Helpers are provided for a number of standard MIPI DSI command as well as a 51 1.2 riastrad * subset of the MIPI DCS command set. 52 1.2 riastrad */ 53 1.2 riastrad 54 1.1 riastrad static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv) 55 1.1 riastrad { 56 1.3 riastrad struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 57 1.3 riastrad 58 1.3 riastrad /* attempt OF style match */ 59 1.3 riastrad if (of_driver_match_device(dev, drv)) 60 1.3 riastrad return 1; 61 1.3 riastrad 62 1.3 riastrad /* compare DSI device and driver names */ 63 1.3 riastrad if (!strcmp(dsi->name, drv->name)) 64 1.3 riastrad return 1; 65 1.3 riastrad 66 1.3 riastrad return 0; 67 1.3 riastrad } 68 1.3 riastrad 69 1.3 riastrad static int mipi_dsi_uevent(struct device *dev, struct kobj_uevent_env *env) 70 1.3 riastrad { 71 1.3 riastrad struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 72 1.3 riastrad int err; 73 1.3 riastrad 74 1.3 riastrad err = of_device_uevent_modalias(dev, env); 75 1.3 riastrad if (err != -ENODEV) 76 1.3 riastrad return err; 77 1.3 riastrad 78 1.3 riastrad add_uevent_var(env, "MODALIAS=%s%s", MIPI_DSI_MODULE_PREFIX, 79 1.3 riastrad dsi->name); 80 1.3 riastrad 81 1.3 riastrad return 0; 82 1.1 riastrad } 83 1.1 riastrad 84 1.1 riastrad static const struct dev_pm_ops mipi_dsi_device_pm_ops = { 85 1.1 riastrad .runtime_suspend = pm_generic_runtime_suspend, 86 1.1 riastrad .runtime_resume = pm_generic_runtime_resume, 87 1.1 riastrad .suspend = pm_generic_suspend, 88 1.1 riastrad .resume = pm_generic_resume, 89 1.1 riastrad .freeze = pm_generic_freeze, 90 1.1 riastrad .thaw = pm_generic_thaw, 91 1.1 riastrad .poweroff = pm_generic_poweroff, 92 1.1 riastrad .restore = pm_generic_restore, 93 1.1 riastrad }; 94 1.1 riastrad 95 1.1 riastrad static struct bus_type mipi_dsi_bus_type = { 96 1.1 riastrad .name = "mipi-dsi", 97 1.1 riastrad .match = mipi_dsi_device_match, 98 1.3 riastrad .uevent = mipi_dsi_uevent, 99 1.1 riastrad .pm = &mipi_dsi_device_pm_ops, 100 1.1 riastrad }; 101 1.1 riastrad 102 1.2 riastrad /** 103 1.2 riastrad * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a 104 1.2 riastrad * device tree node 105 1.2 riastrad * @np: device tree node 106 1.2 riastrad * 107 1.2 riastrad * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no 108 1.2 riastrad * such device exists (or has not been registered yet). 109 1.2 riastrad */ 110 1.2 riastrad struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np) 111 1.2 riastrad { 112 1.2 riastrad struct device *dev; 113 1.2 riastrad 114 1.3 riastrad dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np); 115 1.2 riastrad 116 1.2 riastrad return dev ? to_mipi_dsi_device(dev) : NULL; 117 1.2 riastrad } 118 1.2 riastrad EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node); 119 1.2 riastrad 120 1.1 riastrad static void mipi_dsi_dev_release(struct device *dev) 121 1.1 riastrad { 122 1.1 riastrad struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 123 1.1 riastrad 124 1.1 riastrad of_node_put(dev->of_node); 125 1.1 riastrad kfree(dsi); 126 1.1 riastrad } 127 1.1 riastrad 128 1.1 riastrad static const struct device_type mipi_dsi_device_type = { 129 1.1 riastrad .release = mipi_dsi_dev_release, 130 1.1 riastrad }; 131 1.1 riastrad 132 1.1 riastrad static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host) 133 1.1 riastrad { 134 1.1 riastrad struct mipi_dsi_device *dsi; 135 1.1 riastrad 136 1.1 riastrad dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 137 1.1 riastrad if (!dsi) 138 1.1 riastrad return ERR_PTR(-ENOMEM); 139 1.1 riastrad 140 1.1 riastrad dsi->host = host; 141 1.1 riastrad dsi->dev.bus = &mipi_dsi_bus_type; 142 1.1 riastrad dsi->dev.parent = host->dev; 143 1.1 riastrad dsi->dev.type = &mipi_dsi_device_type; 144 1.1 riastrad 145 1.1 riastrad device_initialize(&dsi->dev); 146 1.1 riastrad 147 1.1 riastrad return dsi; 148 1.1 riastrad } 149 1.1 riastrad 150 1.1 riastrad static int mipi_dsi_device_add(struct mipi_dsi_device *dsi) 151 1.1 riastrad { 152 1.1 riastrad struct mipi_dsi_host *host = dsi->host; 153 1.1 riastrad 154 1.1 riastrad dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev), dsi->channel); 155 1.1 riastrad 156 1.1 riastrad return device_add(&dsi->dev); 157 1.1 riastrad } 158 1.1 riastrad 159 1.3 riastrad #if IS_ENABLED(CONFIG_OF) 160 1.1 riastrad static struct mipi_dsi_device * 161 1.1 riastrad of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) 162 1.1 riastrad { 163 1.1 riastrad struct device *dev = host->dev; 164 1.3 riastrad struct mipi_dsi_device_info info = { }; 165 1.1 riastrad int ret; 166 1.1 riastrad u32 reg; 167 1.1 riastrad 168 1.3 riastrad if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { 169 1.3 riastrad dev_err(dev, "modalias failure on %pOF\n", node); 170 1.3 riastrad return ERR_PTR(-EINVAL); 171 1.3 riastrad } 172 1.3 riastrad 173 1.1 riastrad ret = of_property_read_u32(node, "reg", ®); 174 1.1 riastrad if (ret) { 175 1.3 riastrad dev_err(dev, "device node %pOF has no valid reg property: %d\n", 176 1.3 riastrad node, ret); 177 1.1 riastrad return ERR_PTR(-EINVAL); 178 1.1 riastrad } 179 1.1 riastrad 180 1.3 riastrad info.channel = reg; 181 1.3 riastrad info.node = of_node_get(node); 182 1.3 riastrad 183 1.3 riastrad return mipi_dsi_device_register_full(host, &info); 184 1.3 riastrad } 185 1.3 riastrad #else 186 1.3 riastrad static struct mipi_dsi_device * 187 1.3 riastrad of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) 188 1.3 riastrad { 189 1.3 riastrad return ERR_PTR(-ENODEV); 190 1.3 riastrad } 191 1.3 riastrad #endif 192 1.3 riastrad 193 1.3 riastrad /** 194 1.3 riastrad * mipi_dsi_device_register_full - create a MIPI DSI device 195 1.3 riastrad * @host: DSI host to which this device is connected 196 1.3 riastrad * @info: pointer to template containing DSI device information 197 1.3 riastrad * 198 1.3 riastrad * Create a MIPI DSI device by using the device information provided by 199 1.3 riastrad * mipi_dsi_device_info template 200 1.3 riastrad * 201 1.3 riastrad * Returns: 202 1.3 riastrad * A pointer to the newly created MIPI DSI device, or, a pointer encoded 203 1.3 riastrad * with an error 204 1.3 riastrad */ 205 1.3 riastrad struct mipi_dsi_device * 206 1.3 riastrad mipi_dsi_device_register_full(struct mipi_dsi_host *host, 207 1.3 riastrad const struct mipi_dsi_device_info *info) 208 1.3 riastrad { 209 1.3 riastrad struct mipi_dsi_device *dsi; 210 1.3 riastrad struct device *dev = host->dev; 211 1.3 riastrad int ret; 212 1.3 riastrad 213 1.3 riastrad if (!info) { 214 1.3 riastrad dev_err(dev, "invalid mipi_dsi_device_info pointer\n"); 215 1.3 riastrad return ERR_PTR(-EINVAL); 216 1.3 riastrad } 217 1.3 riastrad 218 1.3 riastrad if (info->channel > 3) { 219 1.3 riastrad dev_err(dev, "invalid virtual channel: %u\n", info->channel); 220 1.1 riastrad return ERR_PTR(-EINVAL); 221 1.1 riastrad } 222 1.1 riastrad 223 1.1 riastrad dsi = mipi_dsi_device_alloc(host); 224 1.1 riastrad if (IS_ERR(dsi)) { 225 1.3 riastrad dev_err(dev, "failed to allocate DSI device %ld\n", 226 1.3 riastrad PTR_ERR(dsi)); 227 1.1 riastrad return dsi; 228 1.1 riastrad } 229 1.1 riastrad 230 1.3 riastrad dsi->dev.of_node = info->node; 231 1.3 riastrad dsi->channel = info->channel; 232 1.3 riastrad strlcpy(dsi->name, info->type, sizeof(dsi->name)); 233 1.1 riastrad 234 1.1 riastrad ret = mipi_dsi_device_add(dsi); 235 1.1 riastrad if (ret) { 236 1.3 riastrad dev_err(dev, "failed to add DSI device %d\n", ret); 237 1.1 riastrad kfree(dsi); 238 1.1 riastrad return ERR_PTR(ret); 239 1.1 riastrad } 240 1.1 riastrad 241 1.1 riastrad return dsi; 242 1.1 riastrad } 243 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_device_register_full); 244 1.3 riastrad 245 1.3 riastrad /** 246 1.3 riastrad * mipi_dsi_device_unregister - unregister MIPI DSI device 247 1.3 riastrad * @dsi: DSI peripheral device 248 1.3 riastrad */ 249 1.3 riastrad void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi) 250 1.3 riastrad { 251 1.3 riastrad device_unregister(&dsi->dev); 252 1.3 riastrad } 253 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_device_unregister); 254 1.3 riastrad 255 1.3 riastrad static DEFINE_MUTEX(host_lock); 256 1.3 riastrad static LIST_HEAD(host_list); 257 1.3 riastrad 258 1.3 riastrad /** 259 1.3 riastrad * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a 260 1.3 riastrad * device tree node 261 1.3 riastrad * @node: device tree node 262 1.3 riastrad * 263 1.3 riastrad * Returns: 264 1.3 riastrad * A pointer to the MIPI DSI host corresponding to @node or NULL if no 265 1.3 riastrad * such device exists (or has not been registered yet). 266 1.3 riastrad */ 267 1.3 riastrad struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node) 268 1.3 riastrad { 269 1.3 riastrad struct mipi_dsi_host *host; 270 1.3 riastrad 271 1.3 riastrad mutex_lock(&host_lock); 272 1.3 riastrad 273 1.3 riastrad list_for_each_entry(host, &host_list, list) { 274 1.3 riastrad if (host->dev->of_node == node) { 275 1.3 riastrad mutex_unlock(&host_lock); 276 1.3 riastrad return host; 277 1.3 riastrad } 278 1.3 riastrad } 279 1.3 riastrad 280 1.3 riastrad mutex_unlock(&host_lock); 281 1.3 riastrad 282 1.3 riastrad return NULL; 283 1.3 riastrad } 284 1.3 riastrad EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node); 285 1.1 riastrad 286 1.1 riastrad int mipi_dsi_host_register(struct mipi_dsi_host *host) 287 1.1 riastrad { 288 1.1 riastrad struct device_node *node; 289 1.1 riastrad 290 1.1 riastrad for_each_available_child_of_node(host->dev->of_node, node) { 291 1.1 riastrad /* skip nodes without reg property */ 292 1.1 riastrad if (!of_find_property(node, "reg", NULL)) 293 1.1 riastrad continue; 294 1.1 riastrad of_mipi_dsi_device_add(host, node); 295 1.1 riastrad } 296 1.1 riastrad 297 1.3 riastrad mutex_lock(&host_lock); 298 1.3 riastrad list_add_tail(&host->list, &host_list); 299 1.3 riastrad mutex_unlock(&host_lock); 300 1.3 riastrad 301 1.1 riastrad return 0; 302 1.1 riastrad } 303 1.1 riastrad EXPORT_SYMBOL(mipi_dsi_host_register); 304 1.1 riastrad 305 1.1 riastrad static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) 306 1.1 riastrad { 307 1.1 riastrad struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 308 1.1 riastrad 309 1.3 riastrad mipi_dsi_device_unregister(dsi); 310 1.1 riastrad 311 1.1 riastrad return 0; 312 1.1 riastrad } 313 1.1 riastrad 314 1.1 riastrad void mipi_dsi_host_unregister(struct mipi_dsi_host *host) 315 1.1 riastrad { 316 1.1 riastrad device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn); 317 1.3 riastrad 318 1.3 riastrad mutex_lock(&host_lock); 319 1.3 riastrad list_del_init(&host->list); 320 1.3 riastrad mutex_unlock(&host_lock); 321 1.1 riastrad } 322 1.1 riastrad EXPORT_SYMBOL(mipi_dsi_host_unregister); 323 1.1 riastrad 324 1.1 riastrad /** 325 1.1 riastrad * mipi_dsi_attach - attach a DSI device to its DSI host 326 1.1 riastrad * @dsi: DSI peripheral 327 1.1 riastrad */ 328 1.1 riastrad int mipi_dsi_attach(struct mipi_dsi_device *dsi) 329 1.1 riastrad { 330 1.1 riastrad const struct mipi_dsi_host_ops *ops = dsi->host->ops; 331 1.1 riastrad 332 1.1 riastrad if (!ops || !ops->attach) 333 1.1 riastrad return -ENOSYS; 334 1.1 riastrad 335 1.1 riastrad return ops->attach(dsi->host, dsi); 336 1.1 riastrad } 337 1.1 riastrad EXPORT_SYMBOL(mipi_dsi_attach); 338 1.1 riastrad 339 1.1 riastrad /** 340 1.1 riastrad * mipi_dsi_detach - detach a DSI device from its DSI host 341 1.1 riastrad * @dsi: DSI peripheral 342 1.1 riastrad */ 343 1.1 riastrad int mipi_dsi_detach(struct mipi_dsi_device *dsi) 344 1.1 riastrad { 345 1.1 riastrad const struct mipi_dsi_host_ops *ops = dsi->host->ops; 346 1.1 riastrad 347 1.1 riastrad if (!ops || !ops->detach) 348 1.1 riastrad return -ENOSYS; 349 1.1 riastrad 350 1.1 riastrad return ops->detach(dsi->host, dsi); 351 1.1 riastrad } 352 1.1 riastrad EXPORT_SYMBOL(mipi_dsi_detach); 353 1.1 riastrad 354 1.2 riastrad static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, 355 1.2 riastrad struct mipi_dsi_msg *msg) 356 1.2 riastrad { 357 1.2 riastrad const struct mipi_dsi_host_ops *ops = dsi->host->ops; 358 1.2 riastrad 359 1.2 riastrad if (!ops || !ops->transfer) 360 1.2 riastrad return -ENOSYS; 361 1.2 riastrad 362 1.2 riastrad if (dsi->mode_flags & MIPI_DSI_MODE_LPM) 363 1.2 riastrad msg->flags |= MIPI_DSI_MSG_USE_LPM; 364 1.2 riastrad 365 1.2 riastrad return ops->transfer(dsi->host, msg); 366 1.2 riastrad } 367 1.2 riastrad 368 1.2 riastrad /** 369 1.2 riastrad * mipi_dsi_packet_format_is_short - check if a packet is of the short format 370 1.2 riastrad * @type: MIPI DSI data type of the packet 371 1.2 riastrad * 372 1.2 riastrad * Return: true if the packet for the given data type is a short packet, false 373 1.2 riastrad * otherwise. 374 1.2 riastrad */ 375 1.2 riastrad bool mipi_dsi_packet_format_is_short(u8 type) 376 1.2 riastrad { 377 1.2 riastrad switch (type) { 378 1.2 riastrad case MIPI_DSI_V_SYNC_START: 379 1.2 riastrad case MIPI_DSI_V_SYNC_END: 380 1.2 riastrad case MIPI_DSI_H_SYNC_START: 381 1.2 riastrad case MIPI_DSI_H_SYNC_END: 382 1.3 riastrad case MIPI_DSI_COMPRESSION_MODE: 383 1.2 riastrad case MIPI_DSI_END_OF_TRANSMISSION: 384 1.2 riastrad case MIPI_DSI_COLOR_MODE_OFF: 385 1.2 riastrad case MIPI_DSI_COLOR_MODE_ON: 386 1.2 riastrad case MIPI_DSI_SHUTDOWN_PERIPHERAL: 387 1.2 riastrad case MIPI_DSI_TURN_ON_PERIPHERAL: 388 1.2 riastrad case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: 389 1.2 riastrad case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: 390 1.2 riastrad case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: 391 1.2 riastrad case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: 392 1.2 riastrad case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: 393 1.2 riastrad case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: 394 1.2 riastrad case MIPI_DSI_DCS_SHORT_WRITE: 395 1.2 riastrad case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 396 1.2 riastrad case MIPI_DSI_DCS_READ: 397 1.3 riastrad case MIPI_DSI_EXECUTE_QUEUE: 398 1.2 riastrad case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: 399 1.2 riastrad return true; 400 1.2 riastrad } 401 1.2 riastrad 402 1.2 riastrad return false; 403 1.2 riastrad } 404 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); 405 1.2 riastrad 406 1.2 riastrad /** 407 1.2 riastrad * mipi_dsi_packet_format_is_long - check if a packet is of the long format 408 1.2 riastrad * @type: MIPI DSI data type of the packet 409 1.2 riastrad * 410 1.2 riastrad * Return: true if the packet for the given data type is a long packet, false 411 1.2 riastrad * otherwise. 412 1.2 riastrad */ 413 1.2 riastrad bool mipi_dsi_packet_format_is_long(u8 type) 414 1.2 riastrad { 415 1.2 riastrad switch (type) { 416 1.2 riastrad case MIPI_DSI_NULL_PACKET: 417 1.2 riastrad case MIPI_DSI_BLANKING_PACKET: 418 1.2 riastrad case MIPI_DSI_GENERIC_LONG_WRITE: 419 1.2 riastrad case MIPI_DSI_DCS_LONG_WRITE: 420 1.3 riastrad case MIPI_DSI_PICTURE_PARAMETER_SET: 421 1.3 riastrad case MIPI_DSI_COMPRESSED_PIXEL_STREAM: 422 1.2 riastrad case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: 423 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: 424 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: 425 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_30: 426 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_36: 427 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: 428 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_16: 429 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_18: 430 1.2 riastrad case MIPI_DSI_PIXEL_STREAM_3BYTE_18: 431 1.2 riastrad case MIPI_DSI_PACKED_PIXEL_STREAM_24: 432 1.2 riastrad return true; 433 1.2 riastrad } 434 1.2 riastrad 435 1.2 riastrad return false; 436 1.2 riastrad } 437 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); 438 1.2 riastrad 439 1.2 riastrad /** 440 1.2 riastrad * mipi_dsi_create_packet - create a packet from a message according to the 441 1.2 riastrad * DSI protocol 442 1.2 riastrad * @packet: pointer to a DSI packet structure 443 1.2 riastrad * @msg: message to translate into a packet 444 1.2 riastrad * 445 1.2 riastrad * Return: 0 on success or a negative error code on failure. 446 1.2 riastrad */ 447 1.2 riastrad int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, 448 1.2 riastrad const struct mipi_dsi_msg *msg) 449 1.2 riastrad { 450 1.2 riastrad if (!packet || !msg) 451 1.2 riastrad return -EINVAL; 452 1.2 riastrad 453 1.2 riastrad /* do some minimum sanity checking */ 454 1.2 riastrad if (!mipi_dsi_packet_format_is_short(msg->type) && 455 1.2 riastrad !mipi_dsi_packet_format_is_long(msg->type)) 456 1.2 riastrad return -EINVAL; 457 1.2 riastrad 458 1.2 riastrad if (msg->channel > 3) 459 1.2 riastrad return -EINVAL; 460 1.2 riastrad 461 1.2 riastrad memset(packet, 0, sizeof(*packet)); 462 1.2 riastrad packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); 463 1.2 riastrad 464 1.2 riastrad /* TODO: compute ECC if hardware support is not available */ 465 1.2 riastrad 466 1.2 riastrad /* 467 1.2 riastrad * Long write packets contain the word count in header bytes 1 and 2. 468 1.2 riastrad * The payload follows the header and is word count bytes long. 469 1.2 riastrad * 470 1.2 riastrad * Short write packets encode up to two parameters in header bytes 1 471 1.2 riastrad * and 2. 472 1.2 riastrad */ 473 1.2 riastrad if (mipi_dsi_packet_format_is_long(msg->type)) { 474 1.2 riastrad packet->header[1] = (msg->tx_len >> 0) & 0xff; 475 1.2 riastrad packet->header[2] = (msg->tx_len >> 8) & 0xff; 476 1.2 riastrad 477 1.2 riastrad packet->payload_length = msg->tx_len; 478 1.2 riastrad packet->payload = msg->tx_buf; 479 1.2 riastrad } else { 480 1.2 riastrad const u8 *tx = msg->tx_buf; 481 1.2 riastrad 482 1.2 riastrad packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; 483 1.2 riastrad packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; 484 1.2 riastrad } 485 1.2 riastrad 486 1.2 riastrad packet->size = sizeof(packet->header) + packet->payload_length; 487 1.2 riastrad 488 1.2 riastrad return 0; 489 1.2 riastrad } 490 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_create_packet); 491 1.2 riastrad 492 1.3 riastrad /** 493 1.3 riastrad * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command 494 1.3 riastrad * @dsi: DSI peripheral device 495 1.3 riastrad * 496 1.3 riastrad * Return: 0 on success or a negative error code on failure. 497 1.3 riastrad */ 498 1.3 riastrad int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi) 499 1.3 riastrad { 500 1.3 riastrad struct mipi_dsi_msg msg = { 501 1.3 riastrad .channel = dsi->channel, 502 1.3 riastrad .type = MIPI_DSI_SHUTDOWN_PERIPHERAL, 503 1.3 riastrad .tx_buf = (u8 [2]) { 0, 0 }, 504 1.3 riastrad .tx_len = 2, 505 1.3 riastrad }; 506 1.3 riastrad int ret = mipi_dsi_device_transfer(dsi, &msg); 507 1.3 riastrad 508 1.3 riastrad return (ret < 0) ? ret : 0; 509 1.3 riastrad } 510 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral); 511 1.3 riastrad 512 1.3 riastrad /** 513 1.3 riastrad * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command 514 1.3 riastrad * @dsi: DSI peripheral device 515 1.3 riastrad * 516 1.3 riastrad * Return: 0 on success or a negative error code on failure. 517 1.3 riastrad */ 518 1.3 riastrad int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi) 519 1.3 riastrad { 520 1.3 riastrad struct mipi_dsi_msg msg = { 521 1.3 riastrad .channel = dsi->channel, 522 1.3 riastrad .type = MIPI_DSI_TURN_ON_PERIPHERAL, 523 1.3 riastrad .tx_buf = (u8 [2]) { 0, 0 }, 524 1.3 riastrad .tx_len = 2, 525 1.3 riastrad }; 526 1.3 riastrad int ret = mipi_dsi_device_transfer(dsi, &msg); 527 1.3 riastrad 528 1.3 riastrad return (ret < 0) ? ret : 0; 529 1.3 riastrad } 530 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral); 531 1.3 riastrad 532 1.2 riastrad /* 533 1.2 riastrad * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the 534 1.2 riastrad * the payload in a long packet transmitted from the peripheral back to the 535 1.2 riastrad * host processor 536 1.2 riastrad * @dsi: DSI peripheral device 537 1.2 riastrad * @value: the maximum size of the payload 538 1.2 riastrad * 539 1.2 riastrad * Return: 0 on success or a negative error code on failure. 540 1.2 riastrad */ 541 1.2 riastrad int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 542 1.2 riastrad u16 value) 543 1.2 riastrad { 544 1.2 riastrad u8 tx[2] = { value & 0xff, value >> 8 }; 545 1.2 riastrad struct mipi_dsi_msg msg = { 546 1.2 riastrad .channel = dsi->channel, 547 1.2 riastrad .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 548 1.2 riastrad .tx_len = sizeof(tx), 549 1.2 riastrad .tx_buf = tx, 550 1.2 riastrad }; 551 1.3 riastrad int ret = mipi_dsi_device_transfer(dsi, &msg); 552 1.2 riastrad 553 1.3 riastrad return (ret < 0) ? ret : 0; 554 1.2 riastrad } 555 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); 556 1.2 riastrad 557 1.2 riastrad /** 558 1.3 riastrad * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral 559 1.3 riastrad * @dsi: DSI peripheral device 560 1.3 riastrad * @enable: Whether to enable or disable the DSC 561 1.3 riastrad * 562 1.3 riastrad * Enable or disable Display Stream Compression on the peripheral using the 563 1.3 riastrad * default Picture Parameter Set and VESA DSC 1.1 algorithm. 564 1.3 riastrad * 565 1.3 riastrad * Return: 0 on success or a negative error code on failure. 566 1.3 riastrad */ 567 1.3 riastrad ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) 568 1.3 riastrad { 569 1.3 riastrad /* Note: Needs updating for non-default PPS or algorithm */ 570 1.3 riastrad u8 tx[2] = { enable << 0, 0 }; 571 1.3 riastrad struct mipi_dsi_msg msg = { 572 1.3 riastrad .channel = dsi->channel, 573 1.3 riastrad .type = MIPI_DSI_COMPRESSION_MODE, 574 1.3 riastrad .tx_len = sizeof(tx), 575 1.3 riastrad .tx_buf = tx, 576 1.3 riastrad }; 577 1.3 riastrad int ret = mipi_dsi_device_transfer(dsi, &msg); 578 1.3 riastrad 579 1.3 riastrad return (ret < 0) ? ret : 0; 580 1.3 riastrad } 581 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_compression_mode); 582 1.3 riastrad 583 1.3 riastrad /** 584 1.3 riastrad * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral 585 1.3 riastrad * @dsi: DSI peripheral device 586 1.3 riastrad * @pps: VESA DSC 1.1 Picture Parameter Set 587 1.3 riastrad * 588 1.3 riastrad * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral. 589 1.3 riastrad * 590 1.3 riastrad * Return: 0 on success or a negative error code on failure. 591 1.3 riastrad */ 592 1.3 riastrad ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, 593 1.3 riastrad const struct drm_dsc_picture_parameter_set *pps) 594 1.3 riastrad { 595 1.3 riastrad struct mipi_dsi_msg msg = { 596 1.3 riastrad .channel = dsi->channel, 597 1.3 riastrad .type = MIPI_DSI_PICTURE_PARAMETER_SET, 598 1.3 riastrad .tx_len = sizeof(*pps), 599 1.3 riastrad .tx_buf = pps, 600 1.3 riastrad }; 601 1.3 riastrad int ret = mipi_dsi_device_transfer(dsi, &msg); 602 1.3 riastrad 603 1.3 riastrad return (ret < 0) ? ret : 0; 604 1.3 riastrad } 605 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_picture_parameter_set); 606 1.3 riastrad 607 1.3 riastrad /** 608 1.2 riastrad * mipi_dsi_generic_write() - transmit data using a generic write packet 609 1.2 riastrad * @dsi: DSI peripheral device 610 1.2 riastrad * @payload: buffer containing the payload 611 1.2 riastrad * @size: size of payload buffer 612 1.2 riastrad * 613 1.2 riastrad * This function will automatically choose the right data type depending on 614 1.2 riastrad * the payload length. 615 1.2 riastrad * 616 1.2 riastrad * Return: The number of bytes transmitted on success or a negative error code 617 1.2 riastrad * on failure. 618 1.2 riastrad */ 619 1.2 riastrad ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, 620 1.2 riastrad size_t size) 621 1.2 riastrad { 622 1.2 riastrad struct mipi_dsi_msg msg = { 623 1.2 riastrad .channel = dsi->channel, 624 1.2 riastrad .tx_buf = payload, 625 1.2 riastrad .tx_len = size 626 1.2 riastrad }; 627 1.2 riastrad 628 1.2 riastrad switch (size) { 629 1.2 riastrad case 0: 630 1.2 riastrad msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; 631 1.2 riastrad break; 632 1.2 riastrad 633 1.2 riastrad case 1: 634 1.2 riastrad msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; 635 1.2 riastrad break; 636 1.2 riastrad 637 1.2 riastrad case 2: 638 1.2 riastrad msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; 639 1.2 riastrad break; 640 1.2 riastrad 641 1.2 riastrad default: 642 1.2 riastrad msg.type = MIPI_DSI_GENERIC_LONG_WRITE; 643 1.2 riastrad break; 644 1.2 riastrad } 645 1.2 riastrad 646 1.2 riastrad return mipi_dsi_device_transfer(dsi, &msg); 647 1.2 riastrad } 648 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_generic_write); 649 1.2 riastrad 650 1.2 riastrad /** 651 1.2 riastrad * mipi_dsi_generic_read() - receive data using a generic read packet 652 1.2 riastrad * @dsi: DSI peripheral device 653 1.2 riastrad * @params: buffer containing the request parameters 654 1.2 riastrad * @num_params: number of request parameters 655 1.2 riastrad * @data: buffer in which to return the received data 656 1.2 riastrad * @size: size of receive buffer 657 1.2 riastrad * 658 1.2 riastrad * This function will automatically choose the right data type depending on 659 1.2 riastrad * the number of parameters passed in. 660 1.2 riastrad * 661 1.2 riastrad * Return: The number of bytes successfully read or a negative error code on 662 1.2 riastrad * failure. 663 1.2 riastrad */ 664 1.2 riastrad ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, 665 1.2 riastrad size_t num_params, void *data, size_t size) 666 1.2 riastrad { 667 1.2 riastrad struct mipi_dsi_msg msg = { 668 1.2 riastrad .channel = dsi->channel, 669 1.2 riastrad .tx_len = num_params, 670 1.2 riastrad .tx_buf = params, 671 1.2 riastrad .rx_len = size, 672 1.2 riastrad .rx_buf = data 673 1.2 riastrad }; 674 1.2 riastrad 675 1.2 riastrad switch (num_params) { 676 1.2 riastrad case 0: 677 1.2 riastrad msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; 678 1.2 riastrad break; 679 1.2 riastrad 680 1.2 riastrad case 1: 681 1.2 riastrad msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; 682 1.2 riastrad break; 683 1.2 riastrad 684 1.2 riastrad case 2: 685 1.2 riastrad msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; 686 1.2 riastrad break; 687 1.2 riastrad 688 1.2 riastrad default: 689 1.2 riastrad return -EINVAL; 690 1.2 riastrad } 691 1.2 riastrad 692 1.2 riastrad return mipi_dsi_device_transfer(dsi, &msg); 693 1.2 riastrad } 694 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_generic_read); 695 1.2 riastrad 696 1.1 riastrad /** 697 1.2 riastrad * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload 698 1.2 riastrad * @dsi: DSI peripheral device 699 1.2 riastrad * @data: buffer containing data to be transmitted 700 1.2 riastrad * @len: size of transmission buffer 701 1.2 riastrad * 702 1.2 riastrad * This function will automatically choose the right data type depending on 703 1.2 riastrad * the command payload length. 704 1.2 riastrad * 705 1.2 riastrad * Return: The number of bytes successfully transmitted or a negative error 706 1.2 riastrad * code on failure. 707 1.1 riastrad */ 708 1.2 riastrad ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, 709 1.2 riastrad const void *data, size_t len) 710 1.1 riastrad { 711 1.1 riastrad struct mipi_dsi_msg msg = { 712 1.2 riastrad .channel = dsi->channel, 713 1.1 riastrad .tx_buf = data, 714 1.1 riastrad .tx_len = len 715 1.1 riastrad }; 716 1.1 riastrad 717 1.1 riastrad switch (len) { 718 1.1 riastrad case 0: 719 1.1 riastrad return -EINVAL; 720 1.2 riastrad 721 1.1 riastrad case 1: 722 1.1 riastrad msg.type = MIPI_DSI_DCS_SHORT_WRITE; 723 1.1 riastrad break; 724 1.2 riastrad 725 1.1 riastrad case 2: 726 1.1 riastrad msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; 727 1.1 riastrad break; 728 1.2 riastrad 729 1.1 riastrad default: 730 1.1 riastrad msg.type = MIPI_DSI_DCS_LONG_WRITE; 731 1.1 riastrad break; 732 1.1 riastrad } 733 1.1 riastrad 734 1.2 riastrad return mipi_dsi_device_transfer(dsi, &msg); 735 1.2 riastrad } 736 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); 737 1.2 riastrad 738 1.2 riastrad /** 739 1.2 riastrad * mipi_dsi_dcs_write() - send DCS write command 740 1.2 riastrad * @dsi: DSI peripheral device 741 1.2 riastrad * @cmd: DCS command 742 1.2 riastrad * @data: buffer containing the command payload 743 1.2 riastrad * @len: command payload length 744 1.2 riastrad * 745 1.2 riastrad * This function will automatically choose the right data type depending on 746 1.2 riastrad * the command payload length. 747 1.2 riastrad * 748 1.2 riastrad * Return: The number of bytes successfully transmitted or a negative error 749 1.2 riastrad * code on failure. 750 1.2 riastrad */ 751 1.2 riastrad ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, 752 1.2 riastrad const void *data, size_t len) 753 1.2 riastrad { 754 1.2 riastrad ssize_t err; 755 1.2 riastrad size_t size; 756 1.2 riastrad u8 *tx; 757 1.2 riastrad 758 1.2 riastrad if (len > 0) { 759 1.2 riastrad size = 1 + len; 760 1.2 riastrad 761 1.2 riastrad tx = kmalloc(size, GFP_KERNEL); 762 1.2 riastrad if (!tx) 763 1.2 riastrad return -ENOMEM; 764 1.2 riastrad 765 1.2 riastrad /* concatenate the DCS command byte and the payload */ 766 1.2 riastrad tx[0] = cmd; 767 1.2 riastrad memcpy(&tx[1], data, len); 768 1.2 riastrad } else { 769 1.2 riastrad tx = &cmd; 770 1.2 riastrad size = 1; 771 1.2 riastrad } 772 1.2 riastrad 773 1.2 riastrad err = mipi_dsi_dcs_write_buffer(dsi, tx, size); 774 1.2 riastrad 775 1.2 riastrad if (len > 0) 776 1.2 riastrad kfree(tx); 777 1.2 riastrad 778 1.2 riastrad return err; 779 1.1 riastrad } 780 1.1 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_write); 781 1.1 riastrad 782 1.1 riastrad /** 783 1.2 riastrad * mipi_dsi_dcs_read() - send DCS read request command 784 1.2 riastrad * @dsi: DSI peripheral device 785 1.2 riastrad * @cmd: DCS command 786 1.2 riastrad * @data: buffer in which to receive data 787 1.2 riastrad * @len: size of receive buffer 788 1.1 riastrad * 789 1.2 riastrad * Return: The number of bytes read or a negative error code on failure. 790 1.1 riastrad */ 791 1.2 riastrad ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 792 1.2 riastrad size_t len) 793 1.1 riastrad { 794 1.1 riastrad struct mipi_dsi_msg msg = { 795 1.2 riastrad .channel = dsi->channel, 796 1.1 riastrad .type = MIPI_DSI_DCS_READ, 797 1.1 riastrad .tx_buf = &cmd, 798 1.1 riastrad .tx_len = 1, 799 1.1 riastrad .rx_buf = data, 800 1.1 riastrad .rx_len = len 801 1.1 riastrad }; 802 1.1 riastrad 803 1.2 riastrad return mipi_dsi_device_transfer(dsi, &msg); 804 1.2 riastrad } 805 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_read); 806 1.2 riastrad 807 1.2 riastrad /** 808 1.2 riastrad * mipi_dsi_dcs_nop() - send DCS nop packet 809 1.2 riastrad * @dsi: DSI peripheral device 810 1.2 riastrad * 811 1.2 riastrad * Return: 0 on success or a negative error code on failure. 812 1.2 riastrad */ 813 1.2 riastrad int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) 814 1.2 riastrad { 815 1.2 riastrad ssize_t err; 816 1.2 riastrad 817 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); 818 1.2 riastrad if (err < 0) 819 1.2 riastrad return err; 820 1.2 riastrad 821 1.2 riastrad return 0; 822 1.2 riastrad } 823 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_nop); 824 1.2 riastrad 825 1.2 riastrad /** 826 1.2 riastrad * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module 827 1.2 riastrad * @dsi: DSI peripheral device 828 1.2 riastrad * 829 1.2 riastrad * Return: 0 on success or a negative error code on failure. 830 1.2 riastrad */ 831 1.2 riastrad int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) 832 1.2 riastrad { 833 1.2 riastrad ssize_t err; 834 1.2 riastrad 835 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); 836 1.2 riastrad if (err < 0) 837 1.2 riastrad return err; 838 1.2 riastrad 839 1.2 riastrad return 0; 840 1.2 riastrad } 841 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); 842 1.2 riastrad 843 1.2 riastrad /** 844 1.2 riastrad * mipi_dsi_dcs_get_power_mode() - query the display module's current power 845 1.2 riastrad * mode 846 1.2 riastrad * @dsi: DSI peripheral device 847 1.2 riastrad * @mode: return location for the current power mode 848 1.2 riastrad * 849 1.2 riastrad * Return: 0 on success or a negative error code on failure. 850 1.2 riastrad */ 851 1.2 riastrad int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) 852 1.2 riastrad { 853 1.2 riastrad ssize_t err; 854 1.2 riastrad 855 1.2 riastrad err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, 856 1.2 riastrad sizeof(*mode)); 857 1.2 riastrad if (err <= 0) { 858 1.2 riastrad if (err == 0) 859 1.2 riastrad err = -ENODATA; 860 1.2 riastrad 861 1.2 riastrad return err; 862 1.2 riastrad } 863 1.2 riastrad 864 1.2 riastrad return 0; 865 1.2 riastrad } 866 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); 867 1.2 riastrad 868 1.2 riastrad /** 869 1.2 riastrad * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image 870 1.2 riastrad * data used by the interface 871 1.2 riastrad * @dsi: DSI peripheral device 872 1.2 riastrad * @format: return location for the pixel format 873 1.2 riastrad * 874 1.2 riastrad * Return: 0 on success or a negative error code on failure. 875 1.2 riastrad */ 876 1.2 riastrad int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) 877 1.2 riastrad { 878 1.2 riastrad ssize_t err; 879 1.2 riastrad 880 1.2 riastrad err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, 881 1.2 riastrad sizeof(*format)); 882 1.2 riastrad if (err <= 0) { 883 1.2 riastrad if (err == 0) 884 1.2 riastrad err = -ENODATA; 885 1.2 riastrad 886 1.2 riastrad return err; 887 1.2 riastrad } 888 1.2 riastrad 889 1.2 riastrad return 0; 890 1.2 riastrad } 891 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); 892 1.2 riastrad 893 1.2 riastrad /** 894 1.2 riastrad * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the 895 1.2 riastrad * display module except interface communication 896 1.2 riastrad * @dsi: DSI peripheral device 897 1.2 riastrad * 898 1.2 riastrad * Return: 0 on success or a negative error code on failure. 899 1.2 riastrad */ 900 1.2 riastrad int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) 901 1.2 riastrad { 902 1.2 riastrad ssize_t err; 903 1.2 riastrad 904 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); 905 1.2 riastrad if (err < 0) 906 1.2 riastrad return err; 907 1.2 riastrad 908 1.2 riastrad return 0; 909 1.2 riastrad } 910 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); 911 1.2 riastrad 912 1.2 riastrad /** 913 1.2 riastrad * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display 914 1.2 riastrad * module 915 1.2 riastrad * @dsi: DSI peripheral device 916 1.2 riastrad * 917 1.2 riastrad * Return: 0 on success or a negative error code on failure. 918 1.2 riastrad */ 919 1.2 riastrad int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) 920 1.2 riastrad { 921 1.2 riastrad ssize_t err; 922 1.2 riastrad 923 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); 924 1.2 riastrad if (err < 0) 925 1.2 riastrad return err; 926 1.2 riastrad 927 1.2 riastrad return 0; 928 1.2 riastrad } 929 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); 930 1.2 riastrad 931 1.2 riastrad /** 932 1.2 riastrad * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the 933 1.2 riastrad * display device 934 1.2 riastrad * @dsi: DSI peripheral device 935 1.2 riastrad * 936 1.2 riastrad * Return: 0 on success or a negative error code on failure. 937 1.2 riastrad */ 938 1.2 riastrad int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) 939 1.2 riastrad { 940 1.2 riastrad ssize_t err; 941 1.2 riastrad 942 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); 943 1.2 riastrad if (err < 0) 944 1.2 riastrad return err; 945 1.2 riastrad 946 1.2 riastrad return 0; 947 1.2 riastrad } 948 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); 949 1.2 riastrad 950 1.2 riastrad /** 951 1.2 riastrad * mipi_dsi_dcs_set_display_on() - start displaying the image data on the 952 1.2 riastrad * display device 953 1.2 riastrad * @dsi: DSI peripheral device 954 1.2 riastrad * 955 1.2 riastrad * Return: 0 on success or a negative error code on failure 956 1.2 riastrad */ 957 1.2 riastrad int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) 958 1.2 riastrad { 959 1.2 riastrad ssize_t err; 960 1.2 riastrad 961 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); 962 1.2 riastrad if (err < 0) 963 1.2 riastrad return err; 964 1.2 riastrad 965 1.2 riastrad return 0; 966 1.2 riastrad } 967 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); 968 1.2 riastrad 969 1.2 riastrad /** 970 1.2 riastrad * mipi_dsi_dcs_set_column_address() - define the column extent of the frame 971 1.2 riastrad * memory accessed by the host processor 972 1.2 riastrad * @dsi: DSI peripheral device 973 1.2 riastrad * @start: first column of frame memory 974 1.2 riastrad * @end: last column of frame memory 975 1.2 riastrad * 976 1.2 riastrad * Return: 0 on success or a negative error code on failure. 977 1.2 riastrad */ 978 1.2 riastrad int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 979 1.2 riastrad u16 end) 980 1.2 riastrad { 981 1.2 riastrad u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 982 1.2 riastrad ssize_t err; 983 1.2 riastrad 984 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, 985 1.2 riastrad sizeof(payload)); 986 1.2 riastrad if (err < 0) 987 1.2 riastrad return err; 988 1.2 riastrad 989 1.2 riastrad return 0; 990 1.2 riastrad } 991 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); 992 1.2 riastrad 993 1.2 riastrad /** 994 1.2 riastrad * mipi_dsi_dcs_set_page_address() - define the page extent of the frame 995 1.2 riastrad * memory accessed by the host processor 996 1.2 riastrad * @dsi: DSI peripheral device 997 1.2 riastrad * @start: first page of frame memory 998 1.2 riastrad * @end: last page of frame memory 999 1.2 riastrad * 1000 1.2 riastrad * Return: 0 on success or a negative error code on failure. 1001 1.2 riastrad */ 1002 1.2 riastrad int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 1003 1.2 riastrad u16 end) 1004 1.2 riastrad { 1005 1.2 riastrad u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 1006 1.2 riastrad ssize_t err; 1007 1.2 riastrad 1008 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, 1009 1.2 riastrad sizeof(payload)); 1010 1.2 riastrad if (err < 0) 1011 1.2 riastrad return err; 1012 1.2 riastrad 1013 1.2 riastrad return 0; 1014 1.2 riastrad } 1015 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); 1016 1.2 riastrad 1017 1.2 riastrad /** 1018 1.2 riastrad * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect 1019 1.2 riastrad * output signal on the TE signal line 1020 1.2 riastrad * @dsi: DSI peripheral device 1021 1.2 riastrad * 1022 1.2 riastrad * Return: 0 on success or a negative error code on failure 1023 1.2 riastrad */ 1024 1.2 riastrad int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) 1025 1.2 riastrad { 1026 1.2 riastrad ssize_t err; 1027 1.2 riastrad 1028 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); 1029 1.2 riastrad if (err < 0) 1030 1.2 riastrad return err; 1031 1.2 riastrad 1032 1.2 riastrad return 0; 1033 1.2 riastrad } 1034 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); 1035 1.2 riastrad 1036 1.2 riastrad /** 1037 1.2 riastrad * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect 1038 1.2 riastrad * output signal on the TE signal line. 1039 1.2 riastrad * @dsi: DSI peripheral device 1040 1.2 riastrad * @mode: the Tearing Effect Output Line mode 1041 1.2 riastrad * 1042 1.2 riastrad * Return: 0 on success or a negative error code on failure 1043 1.2 riastrad */ 1044 1.2 riastrad int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 1045 1.2 riastrad enum mipi_dsi_dcs_tear_mode mode) 1046 1.2 riastrad { 1047 1.2 riastrad u8 value = mode; 1048 1.2 riastrad ssize_t err; 1049 1.2 riastrad 1050 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, 1051 1.2 riastrad sizeof(value)); 1052 1.2 riastrad if (err < 0) 1053 1.2 riastrad return err; 1054 1.2 riastrad 1055 1.2 riastrad return 0; 1056 1.2 riastrad } 1057 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 1058 1.2 riastrad 1059 1.2 riastrad /** 1060 1.2 riastrad * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 1061 1.2 riastrad * data used by the interface 1062 1.2 riastrad * @dsi: DSI peripheral device 1063 1.2 riastrad * @format: pixel format 1064 1.2 riastrad * 1065 1.2 riastrad * Return: 0 on success or a negative error code on failure. 1066 1.2 riastrad */ 1067 1.2 riastrad int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) 1068 1.2 riastrad { 1069 1.2 riastrad ssize_t err; 1070 1.2 riastrad 1071 1.2 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, 1072 1.2 riastrad sizeof(format)); 1073 1.2 riastrad if (err < 0) 1074 1.2 riastrad return err; 1075 1.1 riastrad 1076 1.2 riastrad return 0; 1077 1.1 riastrad } 1078 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); 1079 1.1 riastrad 1080 1.3 riastrad /** 1081 1.3 riastrad * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for 1082 1.3 riastrad * the Tearing Effect output signal of the display module 1083 1.3 riastrad * @dsi: DSI peripheral device 1084 1.3 riastrad * @scanline: scanline to use as trigger 1085 1.3 riastrad * 1086 1.3 riastrad * Return: 0 on success or a negative error code on failure 1087 1.3 riastrad */ 1088 1.3 riastrad int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) 1089 1.3 riastrad { 1090 1.3 riastrad u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8, 1091 1.3 riastrad scanline & 0xff }; 1092 1.3 riastrad ssize_t err; 1093 1.3 riastrad 1094 1.3 riastrad err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); 1095 1.3 riastrad if (err < 0) 1096 1.3 riastrad return err; 1097 1.3 riastrad 1098 1.3 riastrad return 0; 1099 1.3 riastrad } 1100 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline); 1101 1.3 riastrad 1102 1.3 riastrad /** 1103 1.3 riastrad * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the 1104 1.3 riastrad * display 1105 1.3 riastrad * @dsi: DSI peripheral device 1106 1.3 riastrad * @brightness: brightness value 1107 1.3 riastrad * 1108 1.3 riastrad * Return: 0 on success or a negative error code on failure. 1109 1.3 riastrad */ 1110 1.3 riastrad int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, 1111 1.3 riastrad u16 brightness) 1112 1.3 riastrad { 1113 1.3 riastrad u8 payload[2] = { brightness & 0xff, brightness >> 8 }; 1114 1.3 riastrad ssize_t err; 1115 1.3 riastrad 1116 1.3 riastrad err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 1117 1.3 riastrad payload, sizeof(payload)); 1118 1.3 riastrad if (err < 0) 1119 1.3 riastrad return err; 1120 1.3 riastrad 1121 1.3 riastrad return 0; 1122 1.3 riastrad } 1123 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness); 1124 1.3 riastrad 1125 1.3 riastrad /** 1126 1.3 riastrad * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value 1127 1.3 riastrad * of the display 1128 1.3 riastrad * @dsi: DSI peripheral device 1129 1.3 riastrad * @brightness: brightness value 1130 1.3 riastrad * 1131 1.3 riastrad * Return: 0 on success or a negative error code on failure. 1132 1.3 riastrad */ 1133 1.3 riastrad int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, 1134 1.3 riastrad u16 *brightness) 1135 1.3 riastrad { 1136 1.3 riastrad ssize_t err; 1137 1.3 riastrad 1138 1.3 riastrad err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, 1139 1.3 riastrad brightness, sizeof(*brightness)); 1140 1.3 riastrad if (err <= 0) { 1141 1.3 riastrad if (err == 0) 1142 1.3 riastrad err = -ENODATA; 1143 1.3 riastrad 1144 1.3 riastrad return err; 1145 1.3 riastrad } 1146 1.3 riastrad 1147 1.3 riastrad return 0; 1148 1.3 riastrad } 1149 1.3 riastrad EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); 1150 1.3 riastrad 1151 1.1 riastrad static int mipi_dsi_drv_probe(struct device *dev) 1152 1.1 riastrad { 1153 1.1 riastrad struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1154 1.1 riastrad struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1155 1.1 riastrad 1156 1.1 riastrad return drv->probe(dsi); 1157 1.1 riastrad } 1158 1.1 riastrad 1159 1.1 riastrad static int mipi_dsi_drv_remove(struct device *dev) 1160 1.1 riastrad { 1161 1.1 riastrad struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1162 1.1 riastrad struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1163 1.1 riastrad 1164 1.1 riastrad return drv->remove(dsi); 1165 1.1 riastrad } 1166 1.1 riastrad 1167 1.2 riastrad static void mipi_dsi_drv_shutdown(struct device *dev) 1168 1.2 riastrad { 1169 1.2 riastrad struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); 1170 1.2 riastrad struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); 1171 1.2 riastrad 1172 1.2 riastrad drv->shutdown(dsi); 1173 1.2 riastrad } 1174 1.2 riastrad 1175 1.1 riastrad /** 1176 1.2 riastrad * mipi_dsi_driver_register_full() - register a driver for DSI devices 1177 1.1 riastrad * @drv: DSI driver structure 1178 1.2 riastrad * @owner: owner module 1179 1.2 riastrad * 1180 1.2 riastrad * Return: 0 on success or a negative error code on failure. 1181 1.1 riastrad */ 1182 1.2 riastrad int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv, 1183 1.2 riastrad struct module *owner) 1184 1.1 riastrad { 1185 1.1 riastrad drv->driver.bus = &mipi_dsi_bus_type; 1186 1.2 riastrad drv->driver.owner = owner; 1187 1.2 riastrad 1188 1.1 riastrad if (drv->probe) 1189 1.1 riastrad drv->driver.probe = mipi_dsi_drv_probe; 1190 1.1 riastrad if (drv->remove) 1191 1.1 riastrad drv->driver.remove = mipi_dsi_drv_remove; 1192 1.2 riastrad if (drv->shutdown) 1193 1.2 riastrad drv->driver.shutdown = mipi_dsi_drv_shutdown; 1194 1.1 riastrad 1195 1.1 riastrad return driver_register(&drv->driver); 1196 1.1 riastrad } 1197 1.2 riastrad EXPORT_SYMBOL(mipi_dsi_driver_register_full); 1198 1.1 riastrad 1199 1.1 riastrad /** 1200 1.2 riastrad * mipi_dsi_driver_unregister() - unregister a driver for DSI devices 1201 1.1 riastrad * @drv: DSI driver structure 1202 1.2 riastrad * 1203 1.2 riastrad * Return: 0 on success or a negative error code on failure. 1204 1.1 riastrad */ 1205 1.1 riastrad void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv) 1206 1.1 riastrad { 1207 1.1 riastrad driver_unregister(&drv->driver); 1208 1.1 riastrad } 1209 1.1 riastrad EXPORT_SYMBOL(mipi_dsi_driver_unregister); 1210 1.1 riastrad 1211 1.1 riastrad static int __init mipi_dsi_bus_init(void) 1212 1.1 riastrad { 1213 1.1 riastrad return bus_register(&mipi_dsi_bus_type); 1214 1.1 riastrad } 1215 1.1 riastrad postcore_initcall(mipi_dsi_bus_init); 1216 1.1 riastrad 1217 1.1 riastrad MODULE_AUTHOR("Andrzej Hajda <a.hajda (at) samsung.com>"); 1218 1.1 riastrad MODULE_DESCRIPTION("MIPI DSI Bus"); 1219 1.1 riastrad MODULE_LICENSE("GPL and additional rights"); 1220