1  /*
2   * MIPI DSI Bus
3   *
4   * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
5   * Andrzej Hajda <a.hajda@samsung.com>
6   *
7   * Permission is hereby granted, free of charge, to any person obtaining a
8   * copy of this software and associated documentation files (the
9   * "Software"), to deal in the Software without restriction, including
10   * without limitation the rights to use, copy, modify, merge, publish,
11   * distribute, sub license, and/or sell copies of the Software, and to
12   * permit persons to whom the Software is furnished to do so, subject to
13   * the following conditions:
14   *
15   * The above copyright notice and this permission notice (including the
16   * next paragraph) shall be included in all copies or substantial portions
17   * of the Software.
18   *
19   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21   * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22   * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
23   * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25   * USE OR OTHER DEALINGS IN THE SOFTWARE.
26   */
27  
28  #include <linux/device.h>
29  #include <linux/module.h>
30  #include <linux/of.h>
31  #include <linux/of_device.h>
32  #include <linux/pm_runtime.h>
33  #include <linux/slab.h>
34  
35  #include <drm/display/drm_dsc.h>
36  #include <drm/drm_mipi_dsi.h>
37  #include <drm/drm_print.h>
38  
39  #include <video/mipi_display.h>
40  
41  /**
42   * DOC: dsi helpers
43   *
44   * These functions contain some common logic and helpers to deal with MIPI DSI
45   * peripherals.
46   *
47   * Helpers are provided for a number of standard MIPI DSI command as well as a
48   * subset of the MIPI DCS command set.
49   */
50  
mipi_dsi_device_match(struct device * dev,const struct device_driver * drv)51  static int mipi_dsi_device_match(struct device *dev, const struct device_driver *drv)
52  {
53  	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
54  
55  	/* attempt OF style match */
56  	if (of_driver_match_device(dev, drv))
57  		return 1;
58  
59  	/* compare DSI device and driver names */
60  	if (!strcmp(dsi->name, drv->name))
61  		return 1;
62  
63  	return 0;
64  }
65  
mipi_dsi_uevent(const struct device * dev,struct kobj_uevent_env * env)66  static int mipi_dsi_uevent(const struct device *dev, struct kobj_uevent_env *env)
67  {
68  	const struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
69  	int err;
70  
71  	err = of_device_uevent_modalias(dev, env);
72  	if (err != -ENODEV)
73  		return err;
74  
75  	add_uevent_var(env, "MODALIAS=%s%s", MIPI_DSI_MODULE_PREFIX,
76  		       dsi->name);
77  
78  	return 0;
79  }
80  
81  static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
82  	.runtime_suspend = pm_generic_runtime_suspend,
83  	.runtime_resume = pm_generic_runtime_resume,
84  	.suspend = pm_generic_suspend,
85  	.resume = pm_generic_resume,
86  	.freeze = pm_generic_freeze,
87  	.thaw = pm_generic_thaw,
88  	.poweroff = pm_generic_poweroff,
89  	.restore = pm_generic_restore,
90  };
91  
92  static const struct bus_type mipi_dsi_bus_type = {
93  	.name = "mipi-dsi",
94  	.match = mipi_dsi_device_match,
95  	.uevent = mipi_dsi_uevent,
96  	.pm = &mipi_dsi_device_pm_ops,
97  };
98  
99  /**
100   * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
101   *    device tree node
102   * @np: device tree node
103   *
104   * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no
105   *    such device exists (or has not been registered yet).
106   */
of_find_mipi_dsi_device_by_node(struct device_node * np)107  struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)
108  {
109  	struct device *dev;
110  
111  	dev = bus_find_device_by_of_node(&mipi_dsi_bus_type, np);
112  
113  	return dev ? to_mipi_dsi_device(dev) : NULL;
114  }
115  EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
116  
mipi_dsi_dev_release(struct device * dev)117  static void mipi_dsi_dev_release(struct device *dev)
118  {
119  	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
120  
121  	of_node_put(dev->of_node);
122  	kfree(dsi);
123  }
124  
125  static const struct device_type mipi_dsi_device_type = {
126  	.release = mipi_dsi_dev_release,
127  };
128  
mipi_dsi_device_alloc(struct mipi_dsi_host * host)129  static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host)
130  {
131  	struct mipi_dsi_device *dsi;
132  
133  	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
134  	if (!dsi)
135  		return ERR_PTR(-ENOMEM);
136  
137  	dsi->host = host;
138  	dsi->dev.bus = &mipi_dsi_bus_type;
139  	dsi->dev.parent = host->dev;
140  	dsi->dev.type = &mipi_dsi_device_type;
141  
142  	device_initialize(&dsi->dev);
143  
144  	return dsi;
145  }
146  
mipi_dsi_device_add(struct mipi_dsi_device * dsi)147  static int mipi_dsi_device_add(struct mipi_dsi_device *dsi)
148  {
149  	struct mipi_dsi_host *host = dsi->host;
150  
151  	dev_set_name(&dsi->dev, "%s.%d", dev_name(host->dev),  dsi->channel);
152  
153  	return device_add(&dsi->dev);
154  }
155  
156  #if IS_ENABLED(CONFIG_OF)
157  static struct mipi_dsi_device *
of_mipi_dsi_device_add(struct mipi_dsi_host * host,struct device_node * node)158  of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
159  {
160  	struct mipi_dsi_device_info info = { };
161  	int ret;
162  	u32 reg;
163  
164  	if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) {
165  		drm_err(host, "modalias failure on %pOF\n", node);
166  		return ERR_PTR(-EINVAL);
167  	}
168  
169  	ret = of_property_read_u32(node, "reg", &reg);
170  	if (ret) {
171  		drm_err(host, "device node %pOF has no valid reg property: %d\n",
172  			node, ret);
173  		return ERR_PTR(-EINVAL);
174  	}
175  
176  	info.channel = reg;
177  	info.node = of_node_get(node);
178  
179  	return mipi_dsi_device_register_full(host, &info);
180  }
181  #else
182  static struct mipi_dsi_device *
of_mipi_dsi_device_add(struct mipi_dsi_host * host,struct device_node * node)183  of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
184  {
185  	return ERR_PTR(-ENODEV);
186  }
187  #endif
188  
189  /**
190   * mipi_dsi_device_register_full - create a MIPI DSI device
191   * @host: DSI host to which this device is connected
192   * @info: pointer to template containing DSI device information
193   *
194   * Create a MIPI DSI device by using the device information provided by
195   * mipi_dsi_device_info template
196   *
197   * Returns:
198   * A pointer to the newly created MIPI DSI device, or, a pointer encoded
199   * with an error
200   */
201  struct mipi_dsi_device *
mipi_dsi_device_register_full(struct mipi_dsi_host * host,const struct mipi_dsi_device_info * info)202  mipi_dsi_device_register_full(struct mipi_dsi_host *host,
203  			      const struct mipi_dsi_device_info *info)
204  {
205  	struct mipi_dsi_device *dsi;
206  	int ret;
207  
208  	if (!info) {
209  		drm_err(host, "invalid mipi_dsi_device_info pointer\n");
210  		return ERR_PTR(-EINVAL);
211  	}
212  
213  	if (info->channel > 3) {
214  		drm_err(host, "invalid virtual channel: %u\n", info->channel);
215  		return ERR_PTR(-EINVAL);
216  	}
217  
218  	dsi = mipi_dsi_device_alloc(host);
219  	if (IS_ERR(dsi)) {
220  		drm_err(host, "failed to allocate DSI device %ld\n",
221  			PTR_ERR(dsi));
222  		return dsi;
223  	}
224  
225  	device_set_node(&dsi->dev, of_fwnode_handle(info->node));
226  	dsi->channel = info->channel;
227  	strscpy(dsi->name, info->type, sizeof(dsi->name));
228  
229  	ret = mipi_dsi_device_add(dsi);
230  	if (ret) {
231  		drm_err(host, "failed to add DSI device %d\n", ret);
232  		kfree(dsi);
233  		return ERR_PTR(ret);
234  	}
235  
236  	return dsi;
237  }
238  EXPORT_SYMBOL(mipi_dsi_device_register_full);
239  
240  /**
241   * mipi_dsi_device_unregister - unregister MIPI DSI device
242   * @dsi: DSI peripheral device
243   */
mipi_dsi_device_unregister(struct mipi_dsi_device * dsi)244  void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
245  {
246  	device_unregister(&dsi->dev);
247  }
248  EXPORT_SYMBOL(mipi_dsi_device_unregister);
249  
devm_mipi_dsi_device_unregister(void * arg)250  static void devm_mipi_dsi_device_unregister(void *arg)
251  {
252  	struct mipi_dsi_device *dsi = arg;
253  
254  	mipi_dsi_device_unregister(dsi);
255  }
256  
257  /**
258   * devm_mipi_dsi_device_register_full - create a managed MIPI DSI device
259   * @dev: device to tie the MIPI-DSI device lifetime to
260   * @host: DSI host to which this device is connected
261   * @info: pointer to template containing DSI device information
262   *
263   * Create a MIPI DSI device by using the device information provided by
264   * mipi_dsi_device_info template
265   *
266   * This is the managed version of mipi_dsi_device_register_full() which
267   * automatically calls mipi_dsi_device_unregister() when @dev is
268   * unbound.
269   *
270   * Returns:
271   * A pointer to the newly created MIPI DSI device, or, a pointer encoded
272   * with an error
273   */
274  struct mipi_dsi_device *
devm_mipi_dsi_device_register_full(struct device * dev,struct mipi_dsi_host * host,const struct mipi_dsi_device_info * info)275  devm_mipi_dsi_device_register_full(struct device *dev,
276  				   struct mipi_dsi_host *host,
277  				   const struct mipi_dsi_device_info *info)
278  {
279  	struct mipi_dsi_device *dsi;
280  	int ret;
281  
282  	dsi = mipi_dsi_device_register_full(host, info);
283  	if (IS_ERR(dsi))
284  		return dsi;
285  
286  	ret = devm_add_action_or_reset(dev,
287  				       devm_mipi_dsi_device_unregister,
288  				       dsi);
289  	if (ret)
290  		return ERR_PTR(ret);
291  
292  	return dsi;
293  }
294  EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
295  
296  static DEFINE_MUTEX(host_lock);
297  static LIST_HEAD(host_list);
298  
299  /**
300   * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a
301   *				     device tree node
302   * @node: device tree node
303   *
304   * Returns:
305   * A pointer to the MIPI DSI host corresponding to @node or NULL if no
306   * such device exists (or has not been registered yet).
307   */
of_find_mipi_dsi_host_by_node(struct device_node * node)308  struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node)
309  {
310  	struct mipi_dsi_host *host;
311  
312  	mutex_lock(&host_lock);
313  
314  	list_for_each_entry(host, &host_list, list) {
315  		if (host->dev->of_node == node) {
316  			mutex_unlock(&host_lock);
317  			return host;
318  		}
319  	}
320  
321  	mutex_unlock(&host_lock);
322  
323  	return NULL;
324  }
325  EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node);
326  
mipi_dsi_host_register(struct mipi_dsi_host * host)327  int mipi_dsi_host_register(struct mipi_dsi_host *host)
328  {
329  	struct device_node *node;
330  
331  	for_each_available_child_of_node(host->dev->of_node, node) {
332  		/* skip nodes without reg property */
333  		if (!of_property_present(node, "reg"))
334  			continue;
335  		of_mipi_dsi_device_add(host, node);
336  	}
337  
338  	mutex_lock(&host_lock);
339  	list_add_tail(&host->list, &host_list);
340  	mutex_unlock(&host_lock);
341  
342  	return 0;
343  }
344  EXPORT_SYMBOL(mipi_dsi_host_register);
345  
mipi_dsi_remove_device_fn(struct device * dev,void * priv)346  static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
347  {
348  	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
349  
350  	if (dsi->attached)
351  		mipi_dsi_detach(dsi);
352  	mipi_dsi_device_unregister(dsi);
353  
354  	return 0;
355  }
356  
mipi_dsi_host_unregister(struct mipi_dsi_host * host)357  void mipi_dsi_host_unregister(struct mipi_dsi_host *host)
358  {
359  	device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn);
360  
361  	mutex_lock(&host_lock);
362  	list_del_init(&host->list);
363  	mutex_unlock(&host_lock);
364  }
365  EXPORT_SYMBOL(mipi_dsi_host_unregister);
366  
367  /**
368   * mipi_dsi_attach - attach a DSI device to its DSI host
369   * @dsi: DSI peripheral
370   */
mipi_dsi_attach(struct mipi_dsi_device * dsi)371  int mipi_dsi_attach(struct mipi_dsi_device *dsi)
372  {
373  	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
374  	int ret;
375  
376  	if (!ops || !ops->attach)
377  		return -ENOSYS;
378  
379  	ret = ops->attach(dsi->host, dsi);
380  	if (ret)
381  		return ret;
382  
383  	dsi->attached = true;
384  
385  	return 0;
386  }
387  EXPORT_SYMBOL(mipi_dsi_attach);
388  
389  /**
390   * mipi_dsi_detach - detach a DSI device from its DSI host
391   * @dsi: DSI peripheral
392   */
mipi_dsi_detach(struct mipi_dsi_device * dsi)393  int mipi_dsi_detach(struct mipi_dsi_device *dsi)
394  {
395  	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
396  
397  	if (WARN_ON(!dsi->attached))
398  		return -EINVAL;
399  
400  	if (!ops || !ops->detach)
401  		return -ENOSYS;
402  
403  	dsi->attached = false;
404  
405  	return ops->detach(dsi->host, dsi);
406  }
407  EXPORT_SYMBOL(mipi_dsi_detach);
408  
devm_mipi_dsi_detach(void * arg)409  static void devm_mipi_dsi_detach(void *arg)
410  {
411  	struct mipi_dsi_device *dsi = arg;
412  
413  	mipi_dsi_detach(dsi);
414  }
415  
416  /**
417   * devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host
418   * @dev: device to tie the MIPI-DSI device attachment lifetime to
419   * @dsi: DSI peripheral
420   *
421   * This is the managed version of mipi_dsi_attach() which automatically
422   * calls mipi_dsi_detach() when @dev is unbound.
423   *
424   * Returns:
425   * 0 on success, a negative error code on failure.
426   */
devm_mipi_dsi_attach(struct device * dev,struct mipi_dsi_device * dsi)427  int devm_mipi_dsi_attach(struct device *dev,
428  			 struct mipi_dsi_device *dsi)
429  {
430  	int ret;
431  
432  	ret = mipi_dsi_attach(dsi);
433  	if (ret)
434  		return ret;
435  
436  	ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi);
437  	if (ret)
438  		return ret;
439  
440  	return 0;
441  }
442  EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach);
443  
mipi_dsi_device_transfer(struct mipi_dsi_device * dsi,struct mipi_dsi_msg * msg)444  static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
445  					struct mipi_dsi_msg *msg)
446  {
447  	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
448  
449  	if (!ops || !ops->transfer)
450  		return -ENOSYS;
451  
452  	if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
453  		msg->flags |= MIPI_DSI_MSG_USE_LPM;
454  
455  	return ops->transfer(dsi->host, msg);
456  }
457  
458  /**
459   * mipi_dsi_packet_format_is_short - check if a packet is of the short format
460   * @type: MIPI DSI data type of the packet
461   *
462   * Return: true if the packet for the given data type is a short packet, false
463   * otherwise.
464   */
mipi_dsi_packet_format_is_short(u8 type)465  bool mipi_dsi_packet_format_is_short(u8 type)
466  {
467  	switch (type) {
468  	case MIPI_DSI_V_SYNC_START:
469  	case MIPI_DSI_V_SYNC_END:
470  	case MIPI_DSI_H_SYNC_START:
471  	case MIPI_DSI_H_SYNC_END:
472  	case MIPI_DSI_COMPRESSION_MODE:
473  	case MIPI_DSI_END_OF_TRANSMISSION:
474  	case MIPI_DSI_COLOR_MODE_OFF:
475  	case MIPI_DSI_COLOR_MODE_ON:
476  	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
477  	case MIPI_DSI_TURN_ON_PERIPHERAL:
478  	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
479  	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
480  	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
481  	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
482  	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
483  	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
484  	case MIPI_DSI_DCS_SHORT_WRITE:
485  	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
486  	case MIPI_DSI_DCS_READ:
487  	case MIPI_DSI_EXECUTE_QUEUE:
488  	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
489  		return true;
490  	}
491  
492  	return false;
493  }
494  EXPORT_SYMBOL(mipi_dsi_packet_format_is_short);
495  
496  /**
497   * mipi_dsi_packet_format_is_long - check if a packet is of the long format
498   * @type: MIPI DSI data type of the packet
499   *
500   * Return: true if the packet for the given data type is a long packet, false
501   * otherwise.
502   */
mipi_dsi_packet_format_is_long(u8 type)503  bool mipi_dsi_packet_format_is_long(u8 type)
504  {
505  	switch (type) {
506  	case MIPI_DSI_NULL_PACKET:
507  	case MIPI_DSI_BLANKING_PACKET:
508  	case MIPI_DSI_GENERIC_LONG_WRITE:
509  	case MIPI_DSI_DCS_LONG_WRITE:
510  	case MIPI_DSI_PICTURE_PARAMETER_SET:
511  	case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
512  	case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
513  	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
514  	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
515  	case MIPI_DSI_PACKED_PIXEL_STREAM_30:
516  	case MIPI_DSI_PACKED_PIXEL_STREAM_36:
517  	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
518  	case MIPI_DSI_PACKED_PIXEL_STREAM_16:
519  	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
520  	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
521  	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
522  		return true;
523  	}
524  
525  	return false;
526  }
527  EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
528  
529  /**
530   * mipi_dsi_create_packet - create a packet from a message according to the
531   *     DSI protocol
532   * @packet: pointer to a DSI packet structure
533   * @msg: message to translate into a packet
534   *
535   * Return: 0 on success or a negative error code on failure.
536   */
mipi_dsi_create_packet(struct mipi_dsi_packet * packet,const struct mipi_dsi_msg * msg)537  int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
538  			   const struct mipi_dsi_msg *msg)
539  {
540  	if (!packet || !msg)
541  		return -EINVAL;
542  
543  	/* do some minimum sanity checking */
544  	if (!mipi_dsi_packet_format_is_short(msg->type) &&
545  	    !mipi_dsi_packet_format_is_long(msg->type))
546  		return -EINVAL;
547  
548  	if (msg->channel > 3)
549  		return -EINVAL;
550  
551  	memset(packet, 0, sizeof(*packet));
552  	packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
553  
554  	/* TODO: compute ECC if hardware support is not available */
555  
556  	/*
557  	 * Long write packets contain the word count in header bytes 1 and 2.
558  	 * The payload follows the header and is word count bytes long.
559  	 *
560  	 * Short write packets encode up to two parameters in header bytes 1
561  	 * and 2.
562  	 */
563  	if (mipi_dsi_packet_format_is_long(msg->type)) {
564  		packet->header[1] = (msg->tx_len >> 0) & 0xff;
565  		packet->header[2] = (msg->tx_len >> 8) & 0xff;
566  
567  		packet->payload_length = msg->tx_len;
568  		packet->payload = msg->tx_buf;
569  	} else {
570  		const u8 *tx = msg->tx_buf;
571  
572  		packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
573  		packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
574  	}
575  
576  	packet->size = sizeof(packet->header) + packet->payload_length;
577  
578  	return 0;
579  }
580  EXPORT_SYMBOL(mipi_dsi_create_packet);
581  
582  /**
583   * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
584   * @dsi: DSI peripheral device
585   *
586   * Return: 0 on success or a negative error code on failure.
587   */
mipi_dsi_shutdown_peripheral(struct mipi_dsi_device * dsi)588  int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
589  {
590  	struct mipi_dsi_msg msg = {
591  		.channel = dsi->channel,
592  		.type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
593  		.tx_buf = (u8 [2]) { 0, 0 },
594  		.tx_len = 2,
595  	};
596  	int ret = mipi_dsi_device_transfer(dsi, &msg);
597  
598  	return (ret < 0) ? ret : 0;
599  }
600  EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
601  
602  /**
603   * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
604   * @dsi: DSI peripheral device
605   *
606   * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() instead.
607   *
608   * Return: 0 on success or a negative error code on failure.
609   */
mipi_dsi_turn_on_peripheral(struct mipi_dsi_device * dsi)610  int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
611  {
612  	struct mipi_dsi_msg msg = {
613  		.channel = dsi->channel,
614  		.type = MIPI_DSI_TURN_ON_PERIPHERAL,
615  		.tx_buf = (u8 [2]) { 0, 0 },
616  		.tx_len = 2,
617  	};
618  	int ret = mipi_dsi_device_transfer(dsi, &msg);
619  
620  	return (ret < 0) ? ret : 0;
621  }
622  EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral);
623  
624  /*
625   * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of
626   *    the payload in a long packet transmitted from the peripheral back to the
627   *    host processor
628   * @dsi: DSI peripheral device
629   * @value: the maximum size of the payload
630   *
631   * Return: 0 on success or a negative error code on failure.
632   */
mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device * dsi,u16 value)633  int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
634  					    u16 value)
635  {
636  	u8 tx[2] = { value & 0xff, value >> 8 };
637  	struct mipi_dsi_msg msg = {
638  		.channel = dsi->channel,
639  		.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
640  		.tx_len = sizeof(tx),
641  		.tx_buf = tx,
642  	};
643  	int ret = mipi_dsi_device_transfer(dsi, &msg);
644  
645  	return (ret < 0) ? ret : 0;
646  }
647  EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
648  
649  /**
650   * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral
651   * @dsi: DSI peripheral device
652   * @enable: Whether to enable or disable the DSC
653   * @algo: Selected compression algorithm
654   * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
655   *
656   * Enable or disable Display Stream Compression on the peripheral.
657   * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() instead.
658   *
659   * Return: 0 on success or a negative error code on failure.
660   */
mipi_dsi_compression_mode_ext(struct mipi_dsi_device * dsi,bool enable,enum mipi_dsi_compression_algo algo,unsigned int pps_selector)661  int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
662  				  enum mipi_dsi_compression_algo algo,
663  				  unsigned int pps_selector)
664  {
665  	u8 tx[2] = { };
666  	struct mipi_dsi_msg msg = {
667  		.channel = dsi->channel,
668  		.type = MIPI_DSI_COMPRESSION_MODE,
669  		.tx_len = sizeof(tx),
670  		.tx_buf = tx,
671  	};
672  	int ret;
673  
674  	if (algo > 3 || pps_selector > 3)
675  		return -EINVAL;
676  
677  	tx[0] = (enable << 0) |
678  		(algo << 1) |
679  		(pps_selector << 4);
680  
681  	ret = mipi_dsi_device_transfer(dsi, &msg);
682  
683  	return (ret < 0) ? ret : 0;
684  }
685  EXPORT_SYMBOL(mipi_dsi_compression_mode_ext);
686  
687  /**
688   * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
689   * @dsi: DSI peripheral device
690   * @enable: Whether to enable or disable the DSC
691   *
692   * Enable or disable Display Stream Compression on the peripheral using the
693   * default Picture Parameter Set and VESA DSC 1.1 algorithm.
694   *
695   * Return: 0 on success or a negative error code on failure.
696   */
mipi_dsi_compression_mode(struct mipi_dsi_device * dsi,bool enable)697  int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
698  {
699  	return mipi_dsi_compression_mode_ext(dsi, enable, MIPI_DSI_COMPRESSION_DSC, 0);
700  }
701  EXPORT_SYMBOL(mipi_dsi_compression_mode);
702  
703  /**
704   * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
705   * @dsi: DSI peripheral device
706   * @pps: VESA DSC 1.1 Picture Parameter Set
707   *
708   * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
709   * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() instead.
710   *
711   * Return: 0 on success or a negative error code on failure.
712   */
mipi_dsi_picture_parameter_set(struct mipi_dsi_device * dsi,const struct drm_dsc_picture_parameter_set * pps)713  int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
714  				   const struct drm_dsc_picture_parameter_set *pps)
715  {
716  	struct mipi_dsi_msg msg = {
717  		.channel = dsi->channel,
718  		.type = MIPI_DSI_PICTURE_PARAMETER_SET,
719  		.tx_len = sizeof(*pps),
720  		.tx_buf = pps,
721  	};
722  	int ret = mipi_dsi_device_transfer(dsi, &msg);
723  
724  	return (ret < 0) ? ret : 0;
725  }
726  EXPORT_SYMBOL(mipi_dsi_picture_parameter_set);
727  
728  /**
729   * mipi_dsi_generic_write() - transmit data using a generic write packet
730   * @dsi: DSI peripheral device
731   * @payload: buffer containing the payload
732   * @size: size of payload buffer
733   *
734   * This function will automatically choose the right data type depending on
735   * the payload length.
736   *
737   * Return: The number of bytes transmitted on success or a negative error code
738   * on failure.
739   */
mipi_dsi_generic_write(struct mipi_dsi_device * dsi,const void * payload,size_t size)740  ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
741  			       size_t size)
742  {
743  	struct mipi_dsi_msg msg = {
744  		.channel = dsi->channel,
745  		.tx_buf = payload,
746  		.tx_len = size
747  	};
748  
749  	switch (size) {
750  	case 0:
751  		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
752  		break;
753  
754  	case 1:
755  		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
756  		break;
757  
758  	case 2:
759  		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
760  		break;
761  
762  	default:
763  		msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
764  		break;
765  	}
766  
767  	return mipi_dsi_device_transfer(dsi, &msg);
768  }
769  EXPORT_SYMBOL(mipi_dsi_generic_write);
770  
771  /**
772   * mipi_dsi_generic_write_chatty() - mipi_dsi_generic_write() w/ an error log
773   * @dsi: DSI peripheral device
774   * @payload: buffer containing the payload
775   * @size: size of payload buffer
776   *
777   * Like mipi_dsi_generic_write() but includes a dev_err()
778   * call for you and returns 0 upon success, not the number of bytes sent.
779   *
780   * Return: 0 on success or a negative error code on failure.
781   */
mipi_dsi_generic_write_chatty(struct mipi_dsi_device * dsi,const void * payload,size_t size)782  int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
783  				  const void *payload, size_t size)
784  {
785  	struct device *dev = &dsi->dev;
786  	ssize_t ret;
787  
788  	ret = mipi_dsi_generic_write(dsi, payload, size);
789  	if (ret < 0) {
790  		dev_err(dev, "sending generic data %*ph failed: %zd\n",
791  			(int)size, payload, ret);
792  		return ret;
793  	}
794  
795  	return 0;
796  }
797  EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
798  
799  /**
800   * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ accum_err
801   * @ctx: Context for multiple DSI transactions
802   * @payload: buffer containing the payload
803   * @size: size of payload buffer
804   *
805   * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that
806   * makes it convenient to make several calls in a row.
807   */
mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context * ctx,const void * payload,size_t size)808  void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
809  				  const void *payload, size_t size)
810  {
811  	struct mipi_dsi_device *dsi = ctx->dsi;
812  	struct device *dev = &dsi->dev;
813  	ssize_t ret;
814  
815  	if (ctx->accum_err)
816  		return;
817  
818  	ret = mipi_dsi_generic_write(dsi, payload, size);
819  	if (ret < 0) {
820  		ctx->accum_err = ret;
821  		dev_err(dev, "sending generic data %*ph failed: %d\n",
822  			(int)size, payload, ctx->accum_err);
823  	}
824  }
825  EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
826  
827  /**
828   * mipi_dsi_generic_read() - receive data using a generic read packet
829   * @dsi: DSI peripheral device
830   * @params: buffer containing the request parameters
831   * @num_params: number of request parameters
832   * @data: buffer in which to return the received data
833   * @size: size of receive buffer
834   *
835   * This function will automatically choose the right data type depending on
836   * the number of parameters passed in.
837   *
838   * Return: The number of bytes successfully read or a negative error code on
839   * failure.
840   */
mipi_dsi_generic_read(struct mipi_dsi_device * dsi,const void * params,size_t num_params,void * data,size_t size)841  ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
842  			      size_t num_params, void *data, size_t size)
843  {
844  	struct mipi_dsi_msg msg = {
845  		.channel = dsi->channel,
846  		.tx_len = num_params,
847  		.tx_buf = params,
848  		.rx_len = size,
849  		.rx_buf = data
850  	};
851  
852  	switch (num_params) {
853  	case 0:
854  		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
855  		break;
856  
857  	case 1:
858  		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
859  		break;
860  
861  	case 2:
862  		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
863  		break;
864  
865  	default:
866  		return -EINVAL;
867  	}
868  
869  	return mipi_dsi_device_transfer(dsi, &msg);
870  }
871  EXPORT_SYMBOL(mipi_dsi_generic_read);
872  
873  /**
874   * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
875   * @dsi: DSI peripheral device
876   * @data: buffer containing data to be transmitted
877   * @len: size of transmission buffer
878   *
879   * This function will automatically choose the right data type depending on
880   * the command payload length.
881   *
882   * Return: The number of bytes successfully transmitted or a negative error
883   * code on failure.
884   */
mipi_dsi_dcs_write_buffer(struct mipi_dsi_device * dsi,const void * data,size_t len)885  ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
886  				  const void *data, size_t len)
887  {
888  	struct mipi_dsi_msg msg = {
889  		.channel = dsi->channel,
890  		.tx_buf = data,
891  		.tx_len = len
892  	};
893  
894  	switch (len) {
895  	case 0:
896  		return -EINVAL;
897  
898  	case 1:
899  		msg.type = MIPI_DSI_DCS_SHORT_WRITE;
900  		break;
901  
902  	case 2:
903  		msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
904  		break;
905  
906  	default:
907  		msg.type = MIPI_DSI_DCS_LONG_WRITE;
908  		break;
909  	}
910  
911  	return mipi_dsi_device_transfer(dsi, &msg);
912  }
913  EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
914  
915  /**
916   * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error log
917   * @dsi: DSI peripheral device
918   * @data: buffer containing data to be transmitted
919   * @len: size of transmission buffer
920   *
921   * Like mipi_dsi_dcs_write_buffer() but includes a dev_err()
922   * call for you and returns 0 upon success, not the number of bytes sent.
923   *
924   * Return: 0 on success or a negative error code on failure.
925   */
mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device * dsi,const void * data,size_t len)926  int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
927  				     const void *data, size_t len)
928  {
929  	struct device *dev = &dsi->dev;
930  	ssize_t ret;
931  
932  	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
933  	if (ret < 0) {
934  		dev_err(dev, "sending dcs data %*ph failed: %zd\n",
935  			(int)len, data, ret);
936  		return ret;
937  	}
938  
939  	return 0;
940  }
941  EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
942  
943  /**
944   * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err
945   * @ctx: Context for multiple DSI transactions
946   * @data: buffer containing data to be transmitted
947   * @len: size of transmission buffer
948   *
949   * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that
950   * makes it convenient to make several calls in a row.
951   */
mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context * ctx,const void * data,size_t len)952  void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
953  				     const void *data, size_t len)
954  {
955  	struct mipi_dsi_device *dsi = ctx->dsi;
956  	struct device *dev = &dsi->dev;
957  	ssize_t ret;
958  
959  	if (ctx->accum_err)
960  		return;
961  
962  	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
963  	if (ret < 0) {
964  		ctx->accum_err = ret;
965  		dev_err(dev, "sending dcs data %*ph failed: %d\n",
966  			(int)len, data, ctx->accum_err);
967  	}
968  }
969  EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi);
970  
971  /**
972   * mipi_dsi_dcs_write() - send DCS write command
973   * @dsi: DSI peripheral device
974   * @cmd: DCS command
975   * @data: buffer containing the command payload
976   * @len: command payload length
977   *
978   * This function will automatically choose the right data type depending on
979   * the command payload length.
980   *
981   * Return: The number of bytes successfully transmitted or a negative error
982   * code on failure.
983   */
mipi_dsi_dcs_write(struct mipi_dsi_device * dsi,u8 cmd,const void * data,size_t len)984  ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
985  			   const void *data, size_t len)
986  {
987  	ssize_t err;
988  	size_t size;
989  	u8 stack_tx[8];
990  	u8 *tx;
991  
992  	size = 1 + len;
993  	if (len > ARRAY_SIZE(stack_tx) - 1) {
994  		tx = kmalloc(size, GFP_KERNEL);
995  		if (!tx)
996  			return -ENOMEM;
997  	} else {
998  		tx = stack_tx;
999  	}
1000  
1001  	/* concatenate the DCS command byte and the payload */
1002  	tx[0] = cmd;
1003  	if (data)
1004  		memcpy(&tx[1], data, len);
1005  
1006  	err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
1007  
1008  	if (tx != stack_tx)
1009  		kfree(tx);
1010  
1011  	return err;
1012  }
1013  EXPORT_SYMBOL(mipi_dsi_dcs_write);
1014  
1015  /**
1016   * mipi_dsi_dcs_read() - send DCS read request command
1017   * @dsi: DSI peripheral device
1018   * @cmd: DCS command
1019   * @data: buffer in which to receive data
1020   * @len: size of receive buffer
1021   *
1022   * Return: The number of bytes read or a negative error code on failure.
1023   */
mipi_dsi_dcs_read(struct mipi_dsi_device * dsi,u8 cmd,void * data,size_t len)1024  ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
1025  			  size_t len)
1026  {
1027  	struct mipi_dsi_msg msg = {
1028  		.channel = dsi->channel,
1029  		.type = MIPI_DSI_DCS_READ,
1030  		.tx_buf = &cmd,
1031  		.tx_len = 1,
1032  		.rx_buf = data,
1033  		.rx_len = len
1034  	};
1035  
1036  	return mipi_dsi_device_transfer(dsi, &msg);
1037  }
1038  EXPORT_SYMBOL(mipi_dsi_dcs_read);
1039  
1040  /**
1041   * mipi_dsi_dcs_nop() - send DCS nop packet
1042   * @dsi: DSI peripheral device
1043   *
1044   * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead.
1045   *
1046   * Return: 0 on success or a negative error code on failure.
1047   */
mipi_dsi_dcs_nop(struct mipi_dsi_device * dsi)1048  int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
1049  {
1050  	ssize_t err;
1051  
1052  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
1053  	if (err < 0)
1054  		return err;
1055  
1056  	return 0;
1057  }
1058  EXPORT_SYMBOL(mipi_dsi_dcs_nop);
1059  
1060  /**
1061   * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
1062   * @dsi: DSI peripheral device
1063   *
1064   * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead.
1065   *
1066   * Return: 0 on success or a negative error code on failure.
1067   */
mipi_dsi_dcs_soft_reset(struct mipi_dsi_device * dsi)1068  int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
1069  {
1070  	ssize_t err;
1071  
1072  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
1073  	if (err < 0)
1074  		return err;
1075  
1076  	return 0;
1077  }
1078  EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset);
1079  
1080  /**
1081   * mipi_dsi_dcs_get_power_mode() - query the display module's current power
1082   *    mode
1083   * @dsi: DSI peripheral device
1084   * @mode: return location for the current power mode
1085   *
1086   * Return: 0 on success or a negative error code on failure.
1087   */
mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device * dsi,u8 * mode)1088  int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
1089  {
1090  	ssize_t err;
1091  
1092  	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
1093  				sizeof(*mode));
1094  	if (err <= 0) {
1095  		if (err == 0)
1096  			err = -ENODATA;
1097  
1098  		return err;
1099  	}
1100  
1101  	return 0;
1102  }
1103  EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode);
1104  
1105  /**
1106   * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
1107   *    data used by the interface
1108   * @dsi: DSI peripheral device
1109   * @format: return location for the pixel format
1110   *
1111   * Return: 0 on success or a negative error code on failure.
1112   */
mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device * dsi,u8 * format)1113  int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
1114  {
1115  	ssize_t err;
1116  
1117  	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
1118  				sizeof(*format));
1119  	if (err <= 0) {
1120  		if (err == 0)
1121  			err = -ENODATA;
1122  
1123  		return err;
1124  	}
1125  
1126  	return 0;
1127  }
1128  EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
1129  
1130  /**
1131   * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
1132   *    display module except interface communication
1133   * @dsi: DSI peripheral device
1134   *
1135   * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() instead.
1136   *
1137   * Return: 0 on success or a negative error code on failure.
1138   */
mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device * dsi)1139  int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
1140  {
1141  	ssize_t err;
1142  
1143  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
1144  	if (err < 0)
1145  		return err;
1146  
1147  	return 0;
1148  }
1149  EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
1150  
1151  /**
1152   * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
1153   *    module
1154   * @dsi: DSI peripheral device
1155   *
1156   * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() instead.
1157   *
1158   * Return: 0 on success or a negative error code on failure.
1159   */
mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device * dsi)1160  int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
1161  {
1162  	ssize_t err;
1163  
1164  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
1165  	if (err < 0)
1166  		return err;
1167  
1168  	return 0;
1169  }
1170  EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
1171  
1172  /**
1173   * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
1174   *    display device
1175   * @dsi: DSI peripheral device
1176   *
1177   * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() instead.
1178   *
1179   * Return: 0 on success or a negative error code on failure.
1180   */
mipi_dsi_dcs_set_display_off(struct mipi_dsi_device * dsi)1181  int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
1182  {
1183  	ssize_t err;
1184  
1185  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
1186  	if (err < 0)
1187  		return err;
1188  
1189  	return 0;
1190  }
1191  EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
1192  
1193  /**
1194   * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
1195   *    display device
1196   * @dsi: DSI peripheral device
1197   *
1198   * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() instead.
1199   *
1200   * Return: 0 on success or a negative error code on failure
1201   */
mipi_dsi_dcs_set_display_on(struct mipi_dsi_device * dsi)1202  int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
1203  {
1204  	ssize_t err;
1205  
1206  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
1207  	if (err < 0)
1208  		return err;
1209  
1210  	return 0;
1211  }
1212  EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
1213  
1214  /**
1215   * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
1216   *    memory accessed by the host processor
1217   * @dsi: DSI peripheral device
1218   * @start: first column of frame memory
1219   * @end: last column of frame memory
1220   *
1221   * This function is deprecated. Use mipi_dsi_dcs_set_column_address_multi()
1222   * instead.
1223   *
1224   * Return: 0 on success or a negative error code on failure.
1225   */
mipi_dsi_dcs_set_column_address(struct mipi_dsi_device * dsi,u16 start,u16 end)1226  int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
1227  				    u16 end)
1228  {
1229  	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
1230  	ssize_t err;
1231  
1232  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
1233  				 sizeof(payload));
1234  	if (err < 0)
1235  		return err;
1236  
1237  	return 0;
1238  }
1239  EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
1240  
1241  /**
1242   * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
1243   *    memory accessed by the host processor
1244   * @dsi: DSI peripheral device
1245   * @start: first page of frame memory
1246   * @end: last page of frame memory
1247   *
1248   * This function is deprecated. Use mipi_dsi_dcs_set_page_address_multi()
1249   * instead.
1250   *
1251   * Return: 0 on success or a negative error code on failure.
1252   */
mipi_dsi_dcs_set_page_address(struct mipi_dsi_device * dsi,u16 start,u16 end)1253  int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
1254  				  u16 end)
1255  {
1256  	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
1257  	ssize_t err;
1258  
1259  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
1260  				 sizeof(payload));
1261  	if (err < 0)
1262  		return err;
1263  
1264  	return 0;
1265  }
1266  EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
1267  
1268  /**
1269   * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
1270   *    output signal on the TE signal line
1271   * @dsi: DSI peripheral device
1272   *
1273   * Return: 0 on success or a negative error code on failure
1274   */
mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device * dsi)1275  int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
1276  {
1277  	ssize_t err;
1278  
1279  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
1280  	if (err < 0)
1281  		return err;
1282  
1283  	return 0;
1284  }
1285  EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
1286  
1287  /**
1288   * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
1289   *    output signal on the TE signal line.
1290   * @dsi: DSI peripheral device
1291   * @mode: the Tearing Effect Output Line mode
1292   *
1293   * This function is deprecated. Use mipi_dsi_dcs_set_tear_on_multi() instead.
1294   *
1295   * Return: 0 on success or a negative error code on failure
1296   */
mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device * dsi,enum mipi_dsi_dcs_tear_mode mode)1297  int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
1298  			     enum mipi_dsi_dcs_tear_mode mode)
1299  {
1300  	u8 value = mode;
1301  	ssize_t err;
1302  
1303  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
1304  				 sizeof(value));
1305  	if (err < 0)
1306  		return err;
1307  
1308  	return 0;
1309  }
1310  EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
1311  
1312  /**
1313   * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
1314   *    data used by the interface
1315   * @dsi: DSI peripheral device
1316   * @format: pixel format
1317   *
1318   * This function is deprecated. Use mipi_dsi_dcs_set_pixel_format_multi()
1319   * instead.
1320   *
1321   * Return: 0 on success or a negative error code on failure.
1322   */
mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device * dsi,u8 format)1323  int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
1324  {
1325  	ssize_t err;
1326  
1327  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
1328  				 sizeof(format));
1329  	if (err < 0)
1330  		return err;
1331  
1332  	return 0;
1333  }
1334  EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
1335  
1336  /**
1337   * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for
1338   *    the Tearing Effect output signal of the display module
1339   * @dsi: DSI peripheral device
1340   * @scanline: scanline to use as trigger
1341   *
1342   * This function is deprecated. Use mipi_dsi_dcs_set_tear_scanline_multi()
1343   * instead.
1344   *
1345   * Return: 0 on success or a negative error code on failure
1346   */
mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device * dsi,u16 scanline)1347  int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)
1348  {
1349  	u8 payload[2] = { scanline >> 8, scanline & 0xff };
1350  	ssize_t err;
1351  
1352  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload,
1353  				 sizeof(payload));
1354  	if (err < 0)
1355  		return err;
1356  
1357  	return 0;
1358  }
1359  EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline);
1360  
1361  /**
1362   * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the
1363   *    display
1364   * @dsi: DSI peripheral device
1365   * @brightness: brightness value
1366   *
1367   * This function is deprecated. Use mipi_dsi_dcs_set_display_brightness_multi()
1368   * instead.
1369   *
1370   * Return: 0 on success or a negative error code on failure.
1371   */
mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device * dsi,u16 brightness)1372  int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
1373  					u16 brightness)
1374  {
1375  	u8 payload[2] = { brightness & 0xff, brightness >> 8 };
1376  	ssize_t err;
1377  
1378  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
1379  				 payload, sizeof(payload));
1380  	if (err < 0)
1381  		return err;
1382  
1383  	return 0;
1384  }
1385  EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness);
1386  
1387  /**
1388   * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value
1389   *    of the display
1390   * @dsi: DSI peripheral device
1391   * @brightness: brightness value
1392   *
1393   * Return: 0 on success or a negative error code on failure.
1394   */
mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device * dsi,u16 * brightness)1395  int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
1396  					u16 *brightness)
1397  {
1398  	ssize_t err;
1399  
1400  	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
1401  				brightness, sizeof(*brightness));
1402  	if (err <= 0) {
1403  		if (err == 0)
1404  			err = -ENODATA;
1405  
1406  		return err;
1407  	}
1408  
1409  	return 0;
1410  }
1411  EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
1412  
1413  /**
1414   * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
1415   *    of the display
1416   * @dsi: DSI peripheral device
1417   * @brightness: brightness value
1418   *
1419   * Return: 0 on success or a negative error code on failure.
1420   */
mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device * dsi,u16 brightness)1421  int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
1422  					     u16 brightness)
1423  {
1424  	u8 payload[2] = { brightness >> 8, brightness & 0xff };
1425  	ssize_t err;
1426  
1427  	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
1428  				 payload, sizeof(payload));
1429  	if (err < 0)
1430  		return err;
1431  
1432  	return 0;
1433  }
1434  EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
1435  
1436  /**
1437   * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
1438   *    brightness value of the display
1439   * @dsi: DSI peripheral device
1440   * @brightness: brightness value
1441   *
1442   * Return: 0 on success or a negative error code on failure.
1443   */
mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device * dsi,u16 * brightness)1444  int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
1445  					     u16 *brightness)
1446  {
1447  	u8 brightness_be[2];
1448  	ssize_t err;
1449  
1450  	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
1451  				brightness_be, sizeof(brightness_be));
1452  	if (err <= 0) {
1453  		if (err == 0)
1454  			err = -ENODATA;
1455  
1456  		return err;
1457  	}
1458  
1459  	*brightness = (brightness_be[0] << 8) | brightness_be[1];
1460  
1461  	return 0;
1462  }
1463  EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
1464  
1465  /**
1466   * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral
1467   * @ctx: Context for multiple DSI transactions
1468   * @pps: VESA DSC 1.1 Picture Parameter Set
1469   *
1470   * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
1471   * makes it convenient to make several calls in a row.
1472   */
mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context * ctx,const struct drm_dsc_picture_parameter_set * pps)1473  void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
1474  				   const struct drm_dsc_picture_parameter_set *pps)
1475  {
1476  	struct mipi_dsi_device *dsi = ctx->dsi;
1477  	struct device *dev = &dsi->dev;
1478  	ssize_t ret;
1479  
1480  	if (ctx->accum_err)
1481  		return;
1482  
1483  	ret = mipi_dsi_picture_parameter_set(dsi, pps);
1484  	if (ret < 0) {
1485  		ctx->accum_err = ret;
1486  		dev_err(dev, "sending PPS failed: %d\n",
1487  			ctx->accum_err);
1488  	}
1489  }
1490  EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
1491  
1492  /**
1493   * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
1494   * @ctx: Context for multiple DSI transactions
1495   * @enable: Whether to enable or disable the DSC
1496   * @algo: Selected compression algorithm
1497   * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
1498   *
1499   * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
1500   * makes it convenient to make several calls in a row.
1501   */
mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context * ctx,bool enable,enum mipi_dsi_compression_algo algo,unsigned int pps_selector)1502  void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
1503  					 bool enable,
1504  					 enum mipi_dsi_compression_algo algo,
1505  					 unsigned int pps_selector)
1506  {
1507  	struct mipi_dsi_device *dsi = ctx->dsi;
1508  	struct device *dev = &dsi->dev;
1509  	ssize_t ret;
1510  
1511  	if (ctx->accum_err)
1512  		return;
1513  
1514  	ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
1515  	if (ret < 0) {
1516  		ctx->accum_err = ret;
1517  		dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
1518  			ctx->accum_err);
1519  	}
1520  }
1521  EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
1522  
1523  /**
1524   * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
1525   * @ctx: Context for multiple DSI transactions
1526   *
1527   * Like mipi_dsi_dcs_nop() but deals with errors in a way that
1528   * makes it convenient to make several calls in a row.
1529   */
mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context * ctx)1530  void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
1531  {
1532  	struct mipi_dsi_device *dsi = ctx->dsi;
1533  	struct device *dev = &dsi->dev;
1534  	ssize_t ret;
1535  
1536  	if (ctx->accum_err)
1537  		return;
1538  
1539  	ret = mipi_dsi_dcs_nop(dsi);
1540  	if (ret < 0) {
1541  		ctx->accum_err = ret;
1542  		dev_err(dev, "sending DCS NOP failed: %d\n",
1543  			ctx->accum_err);
1544  	}
1545  }
1546  EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
1547  
1548  /**
1549   * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE  packet
1550   * @ctx: Context for multiple DSI transactions
1551   *
1552   * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
1553   * makes it convenient to make several calls in a row.
1554   */
mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context * ctx)1555  void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
1556  {
1557  	struct mipi_dsi_device *dsi = ctx->dsi;
1558  	struct device *dev = &dsi->dev;
1559  	ssize_t ret;
1560  
1561  	if (ctx->accum_err)
1562  		return;
1563  
1564  	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
1565  	if (ret < 0) {
1566  		ctx->accum_err = ret;
1567  		dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
1568  			ctx->accum_err);
1569  	}
1570  }
1571  EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
1572  
1573  /**
1574   * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
1575   * @ctx: Context for multiple DSI transactions
1576   *
1577   * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
1578   * makes it convenient to make several calls in a row.
1579   */
mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context * ctx)1580  void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
1581  {
1582  	struct mipi_dsi_device *dsi = ctx->dsi;
1583  	struct device *dev = &dsi->dev;
1584  	ssize_t ret;
1585  
1586  	if (ctx->accum_err)
1587  		return;
1588  
1589  	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
1590  	if (ret < 0) {
1591  		ctx->accum_err = ret;
1592  		dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
1593  			ctx->accum_err);
1594  	}
1595  }
1596  EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
1597  
1598  /**
1599   * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
1600   * @ctx: Context for multiple DSI transactions
1601   *
1602   * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
1603   * makes it convenient to make several calls in a row.
1604   */
mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context * ctx)1605  void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
1606  {
1607  	struct mipi_dsi_device *dsi = ctx->dsi;
1608  	struct device *dev = &dsi->dev;
1609  	ssize_t ret;
1610  
1611  	if (ctx->accum_err)
1612  		return;
1613  
1614  	ret = mipi_dsi_dcs_set_display_off(dsi);
1615  	if (ret < 0) {
1616  		ctx->accum_err = ret;
1617  		dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
1618  			ctx->accum_err);
1619  	}
1620  }
1621  EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
1622  
1623  /**
1624   * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
1625   * @ctx: Context for multiple DSI transactions
1626   *
1627   * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
1628   * makes it convenient to make several calls in a row.
1629   */
mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context * ctx)1630  void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
1631  {
1632  	struct mipi_dsi_device *dsi = ctx->dsi;
1633  	struct device *dev = &dsi->dev;
1634  	ssize_t ret;
1635  
1636  	if (ctx->accum_err)
1637  		return;
1638  
1639  	ret = mipi_dsi_dcs_set_display_on(dsi);
1640  	if (ret < 0) {
1641  		ctx->accum_err = ret;
1642  		dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
1643  			ctx->accum_err);
1644  	}
1645  }
1646  EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
1647  
1648  /**
1649   * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
1650   * @ctx: Context for multiple DSI transactions
1651   * @mode: the Tearing Effect Output Line mode
1652   *
1653   * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
1654   * makes it convenient to make several calls in a row.
1655   */
mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context * ctx,enum mipi_dsi_dcs_tear_mode mode)1656  void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
1657  				    enum mipi_dsi_dcs_tear_mode mode)
1658  {
1659  	struct mipi_dsi_device *dsi = ctx->dsi;
1660  	struct device *dev = &dsi->dev;
1661  	ssize_t ret;
1662  
1663  	if (ctx->accum_err)
1664  		return;
1665  
1666  	ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
1667  	if (ret < 0) {
1668  		ctx->accum_err = ret;
1669  		dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
1670  			ctx->accum_err);
1671  	}
1672  }
1673  EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
1674  
1675  /**
1676   * mipi_dsi_turn_on_peripheral_multi() - sends a Turn On Peripheral command
1677   * @ctx: Context for multiple DSI transactions
1678   *
1679   * Like mipi_dsi_turn_on_peripheral() but deals with errors in a way that
1680   * makes it convenient to make several calls in a row.
1681   */
mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context * ctx)1682  void mipi_dsi_turn_on_peripheral_multi(struct mipi_dsi_multi_context *ctx)
1683  {
1684  	struct mipi_dsi_device *dsi = ctx->dsi;
1685  	struct device *dev = &dsi->dev;
1686  	int ret;
1687  
1688  	if (ctx->accum_err)
1689  		return;
1690  
1691  	ret = mipi_dsi_turn_on_peripheral(dsi);
1692  	if (ret < 0) {
1693  		ctx->accum_err = ret;
1694  		dev_err(dev, "Failed to turn on peripheral: %d\n",
1695  			ctx->accum_err);
1696  	}
1697  }
1698  EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral_multi);
1699  
1700  /**
1701   * mipi_dsi_dcs_soft_reset_multi() - perform a software reset of the display module
1702   * @ctx: Context for multiple DSI transactions
1703   *
1704   * Like mipi_dsi_dcs_soft_reset() but deals with errors in a way that
1705   * makes it convenient to make several calls in a row.
1706   */
mipi_dsi_dcs_soft_reset_multi(struct mipi_dsi_multi_context * ctx)1707  void mipi_dsi_dcs_soft_reset_multi(struct mipi_dsi_multi_context *ctx)
1708  {
1709  	struct mipi_dsi_device *dsi = ctx->dsi;
1710  	struct device *dev = &dsi->dev;
1711  	int ret;
1712  
1713  	if (ctx->accum_err)
1714  		return;
1715  
1716  	ret = mipi_dsi_dcs_soft_reset(dsi);
1717  	if (ret < 0) {
1718  		ctx->accum_err = ret;
1719  		dev_err(dev, "Failed to mipi_dsi_dcs_soft_reset: %d\n",
1720  			ctx->accum_err);
1721  	}
1722  }
1723  EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset_multi);
1724  
1725  /**
1726   * mipi_dsi_dcs_set_display_brightness_multi() - sets the brightness value of
1727   *	the display
1728   * @ctx: Context for multiple DSI transactions
1729   * @brightness: brightness value
1730   *
1731   * Like mipi_dsi_dcs_set_display_brightness() but deals with errors in a way that
1732   * makes it convenient to make several calls in a row.
1733   */
mipi_dsi_dcs_set_display_brightness_multi(struct mipi_dsi_multi_context * ctx,u16 brightness)1734  void mipi_dsi_dcs_set_display_brightness_multi(struct mipi_dsi_multi_context *ctx,
1735  					       u16 brightness)
1736  {
1737  	struct mipi_dsi_device *dsi = ctx->dsi;
1738  	struct device *dev = &dsi->dev;
1739  	int ret;
1740  
1741  	if (ctx->accum_err)
1742  		return;
1743  
1744  	ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness);
1745  	if (ret < 0) {
1746  		ctx->accum_err = ret;
1747  		dev_err(dev, "Failed to write display brightness: %d\n",
1748  			ctx->accum_err);
1749  	}
1750  }
1751  EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_multi);
1752  
1753  /**
1754   * mipi_dsi_dcs_set_pixel_format_multi() - sets the pixel format for the RGB image
1755   *	data used by the interface
1756   * @ctx: Context for multiple DSI transactions
1757   * @format: pixel format
1758   *
1759   * Like mipi_dsi_dcs_set_pixel_format() but deals with errors in a way that
1760   * makes it convenient to make several calls in a row.
1761   */
mipi_dsi_dcs_set_pixel_format_multi(struct mipi_dsi_multi_context * ctx,u8 format)1762  void mipi_dsi_dcs_set_pixel_format_multi(struct mipi_dsi_multi_context *ctx,
1763  					 u8 format)
1764  {
1765  	struct mipi_dsi_device *dsi = ctx->dsi;
1766  	struct device *dev = &dsi->dev;
1767  	int ret;
1768  
1769  	if (ctx->accum_err)
1770  		return;
1771  
1772  	ret = mipi_dsi_dcs_set_pixel_format(dsi, format);
1773  	if (ret < 0) {
1774  		ctx->accum_err = ret;
1775  		dev_err(dev, "Failed to set pixel format: %d\n",
1776  			ctx->accum_err);
1777  	}
1778  }
1779  EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format_multi);
1780  
1781  /**
1782   * mipi_dsi_dcs_set_column_address_multi() - define the column extent of the
1783   *	frame memory accessed by the host processor
1784   * @ctx: Context for multiple DSI transactions
1785   * @start: first column of frame memory
1786   * @end: last column of frame memory
1787   *
1788   * Like mipi_dsi_dcs_set_column_address() but deals with errors in a way that
1789   * makes it convenient to make several calls in a row.
1790   */
mipi_dsi_dcs_set_column_address_multi(struct mipi_dsi_multi_context * ctx,u16 start,u16 end)1791  void mipi_dsi_dcs_set_column_address_multi(struct mipi_dsi_multi_context *ctx,
1792  					   u16 start, u16 end)
1793  {
1794  	struct mipi_dsi_device *dsi = ctx->dsi;
1795  	struct device *dev = &dsi->dev;
1796  	int ret;
1797  
1798  	if (ctx->accum_err)
1799  		return;
1800  
1801  	ret = mipi_dsi_dcs_set_column_address(dsi, start, end);
1802  	if (ret < 0) {
1803  		ctx->accum_err = ret;
1804  		dev_err(dev, "Failed to set column address: %d\n",
1805  			ctx->accum_err);
1806  	}
1807  }
1808  EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address_multi);
1809  
1810  /**
1811   * mipi_dsi_dcs_set_page_address_multi() - define the page extent of the
1812   *	frame memory accessed by the host processor
1813   * @ctx: Context for multiple DSI transactions
1814   * @start: first page of frame memory
1815   * @end: last page of frame memory
1816   *
1817   * Like mipi_dsi_dcs_set_page_address() but deals with errors in a way that
1818   * makes it convenient to make several calls in a row.
1819   */
mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context * ctx,u16 start,u16 end)1820  void mipi_dsi_dcs_set_page_address_multi(struct mipi_dsi_multi_context *ctx,
1821  					 u16 start, u16 end)
1822  {
1823  	struct mipi_dsi_device *dsi = ctx->dsi;
1824  	struct device *dev = &dsi->dev;
1825  	int ret;
1826  
1827  	if (ctx->accum_err)
1828  		return;
1829  
1830  	ret = mipi_dsi_dcs_set_page_address(dsi, start, end);
1831  	if (ret < 0) {
1832  		ctx->accum_err = ret;
1833  		dev_err(dev, "Failed to set page address: %d\n",
1834  			ctx->accum_err);
1835  	}
1836  }
1837  EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address_multi);
1838  
1839  /**
1840   * mipi_dsi_dcs_set_tear_scanline_multi() - set the scanline to use as trigger for
1841   *    the Tearing Effect output signal of the display module
1842   * @ctx: Context for multiple DSI transactions
1843   * @scanline: scanline to use as trigger
1844   *
1845   * Like mipi_dsi_dcs_set_tear_scanline() but deals with errors in a way that
1846   * makes it convenient to make several calls in a row.
1847   */
mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context * ctx,u16 scanline)1848  void mipi_dsi_dcs_set_tear_scanline_multi(struct mipi_dsi_multi_context *ctx,
1849  					  u16 scanline)
1850  {
1851  	struct mipi_dsi_device *dsi = ctx->dsi;
1852  	struct device *dev = &dsi->dev;
1853  	int ret;
1854  
1855  	if (ctx->accum_err)
1856  		return;
1857  
1858  	ret = mipi_dsi_dcs_set_tear_scanline(dsi, scanline);
1859  	if (ret < 0) {
1860  		ctx->accum_err = ret;
1861  		dev_err(dev, "Failed to set tear scanline: %d\n",
1862  			ctx->accum_err);
1863  	}
1864  }
1865  EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_scanline_multi);
1866  
mipi_dsi_drv_probe(struct device * dev)1867  static int mipi_dsi_drv_probe(struct device *dev)
1868  {
1869  	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1870  	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1871  
1872  	return drv->probe(dsi);
1873  }
1874  
mipi_dsi_drv_remove(struct device * dev)1875  static int mipi_dsi_drv_remove(struct device *dev)
1876  {
1877  	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1878  	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1879  
1880  	drv->remove(dsi);
1881  
1882  	return 0;
1883  }
1884  
mipi_dsi_drv_shutdown(struct device * dev)1885  static void mipi_dsi_drv_shutdown(struct device *dev)
1886  {
1887  	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
1888  	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
1889  
1890  	drv->shutdown(dsi);
1891  }
1892  
1893  /**
1894   * mipi_dsi_driver_register_full() - register a driver for DSI devices
1895   * @drv: DSI driver structure
1896   * @owner: owner module
1897   *
1898   * Return: 0 on success or a negative error code on failure.
1899   */
mipi_dsi_driver_register_full(struct mipi_dsi_driver * drv,struct module * owner)1900  int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv,
1901  				  struct module *owner)
1902  {
1903  	drv->driver.bus = &mipi_dsi_bus_type;
1904  	drv->driver.owner = owner;
1905  
1906  	if (drv->probe)
1907  		drv->driver.probe = mipi_dsi_drv_probe;
1908  	if (drv->remove)
1909  		drv->driver.remove = mipi_dsi_drv_remove;
1910  	if (drv->shutdown)
1911  		drv->driver.shutdown = mipi_dsi_drv_shutdown;
1912  
1913  	return driver_register(&drv->driver);
1914  }
1915  EXPORT_SYMBOL(mipi_dsi_driver_register_full);
1916  
1917  /**
1918   * mipi_dsi_driver_unregister() - unregister a driver for DSI devices
1919   * @drv: DSI driver structure
1920   *
1921   * Return: 0 on success or a negative error code on failure.
1922   */
mipi_dsi_driver_unregister(struct mipi_dsi_driver * drv)1923  void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
1924  {
1925  	driver_unregister(&drv->driver);
1926  }
1927  EXPORT_SYMBOL(mipi_dsi_driver_unregister);
1928  
mipi_dsi_bus_init(void)1929  static int __init mipi_dsi_bus_init(void)
1930  {
1931  	return bus_register(&mipi_dsi_bus_type);
1932  }
1933  postcore_initcall(mipi_dsi_bus_init);
1934  
1935  MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
1936  MODULE_DESCRIPTION("MIPI DSI Bus");
1937  MODULE_LICENSE("GPL and additional rights");
1938