xref: /rk3399_rockchip-uboot/drivers/video/drm/drm_mipi_dsi.c (revision a92bdacccc2618a4682820c07546173ffa74b21c)
11953e619SWyon Bi // SPDX-License-Identifier: GPL-2.0+
21953e619SWyon Bi /*
31953e619SWyon Bi  * MIPI DSI Bus
41953e619SWyon Bi  *
51953e619SWyon Bi  * Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
61953e619SWyon Bi  * Andrzej Hajda <a.hajda@samsung.com>
71953e619SWyon Bi  */
81953e619SWyon Bi 
91953e619SWyon Bi #include <drm/drm_mipi_dsi.h>
101953e619SWyon Bi 
111953e619SWyon Bi #include <config.h>
121953e619SWyon Bi #include <common.h>
131953e619SWyon Bi #include <errno.h>
141953e619SWyon Bi #include <malloc.h>
151953e619SWyon Bi 
161953e619SWyon Bi /**
171953e619SWyon Bi  * mipi_dsi_attach - attach a DSI device to its DSI host
181953e619SWyon Bi  * @dsi: DSI peripheral
191953e619SWyon Bi  */
mipi_dsi_attach(struct mipi_dsi_device * dsi)201953e619SWyon Bi int mipi_dsi_attach(struct mipi_dsi_device *dsi)
211953e619SWyon Bi {
221953e619SWyon Bi 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
231953e619SWyon Bi 
241953e619SWyon Bi 	if (!ops || !ops->attach)
251953e619SWyon Bi 		return -ENOSYS;
261953e619SWyon Bi 
271953e619SWyon Bi 	return ops->attach(dsi->host, dsi);
281953e619SWyon Bi }
291953e619SWyon Bi 
301953e619SWyon Bi /**
311953e619SWyon Bi  * mipi_dsi_detach - detach a DSI device from its DSI host
321953e619SWyon Bi  * @dsi: DSI peripheral
331953e619SWyon Bi  */
mipi_dsi_detach(struct mipi_dsi_device * dsi)341953e619SWyon Bi int mipi_dsi_detach(struct mipi_dsi_device *dsi)
351953e619SWyon Bi {
361953e619SWyon Bi 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
371953e619SWyon Bi 
381953e619SWyon Bi 	if (!ops || !ops->detach)
391953e619SWyon Bi 		return -ENOSYS;
401953e619SWyon Bi 
411953e619SWyon Bi 	return ops->detach(dsi->host, dsi);
421953e619SWyon Bi }
431953e619SWyon Bi 
mipi_dsi_device_transfer(struct mipi_dsi_device * dsi,struct mipi_dsi_msg * msg)441953e619SWyon Bi static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
451953e619SWyon Bi 					struct mipi_dsi_msg *msg)
461953e619SWyon Bi {
471953e619SWyon Bi 	const struct mipi_dsi_host_ops *ops = dsi->host->ops;
481953e619SWyon Bi 
491953e619SWyon Bi 	if (!ops || !ops->transfer)
501953e619SWyon Bi 		return -ENOSYS;
511953e619SWyon Bi 
521953e619SWyon Bi 	if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
531953e619SWyon Bi 		msg->flags |= MIPI_DSI_MSG_USE_LPM;
541953e619SWyon Bi 
551953e619SWyon Bi 	return ops->transfer(dsi->host, msg);
561953e619SWyon Bi }
571953e619SWyon Bi 
581953e619SWyon Bi /**
591953e619SWyon Bi  * mipi_dsi_packet_format_is_short - check if a packet is of the short format
601953e619SWyon Bi  * @type: MIPI DSI data type of the packet
611953e619SWyon Bi  *
621953e619SWyon Bi  * Return: true if the packet for the given data type is a short packet, false
631953e619SWyon Bi  * otherwise.
641953e619SWyon Bi  */
mipi_dsi_packet_format_is_short(u8 type)651953e619SWyon Bi bool mipi_dsi_packet_format_is_short(u8 type)
661953e619SWyon Bi {
671953e619SWyon Bi 	switch (type) {
681953e619SWyon Bi 	case MIPI_DSI_V_SYNC_START:
691953e619SWyon Bi 	case MIPI_DSI_V_SYNC_END:
701953e619SWyon Bi 	case MIPI_DSI_H_SYNC_START:
711953e619SWyon Bi 	case MIPI_DSI_H_SYNC_END:
72*a92bdaccSGuochun Huang 	case MIPI_DSI_COMPRESSION_MODE:
731953e619SWyon Bi 	case MIPI_DSI_END_OF_TRANSMISSION:
741953e619SWyon Bi 	case MIPI_DSI_COLOR_MODE_OFF:
751953e619SWyon Bi 	case MIPI_DSI_COLOR_MODE_ON:
761953e619SWyon Bi 	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
771953e619SWyon Bi 	case MIPI_DSI_TURN_ON_PERIPHERAL:
781953e619SWyon Bi 	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
791953e619SWyon Bi 	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
801953e619SWyon Bi 	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
811953e619SWyon Bi 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
821953e619SWyon Bi 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
831953e619SWyon Bi 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
841953e619SWyon Bi 	case MIPI_DSI_DCS_SHORT_WRITE:
851953e619SWyon Bi 	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
861953e619SWyon Bi 	case MIPI_DSI_DCS_READ:
871953e619SWyon Bi 	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
881953e619SWyon Bi 		return true;
891953e619SWyon Bi 	}
901953e619SWyon Bi 
911953e619SWyon Bi 	return false;
921953e619SWyon Bi }
931953e619SWyon Bi 
941953e619SWyon Bi /**
951953e619SWyon Bi  * mipi_dsi_packet_format_is_long - check if a packet is of the long format
961953e619SWyon Bi  * @type: MIPI DSI data type of the packet
971953e619SWyon Bi  *
981953e619SWyon Bi  * Return: true if the packet for the given data type is a long packet, false
991953e619SWyon Bi  * otherwise.
1001953e619SWyon Bi  */
mipi_dsi_packet_format_is_long(u8 type)1011953e619SWyon Bi bool mipi_dsi_packet_format_is_long(u8 type)
1021953e619SWyon Bi {
1031953e619SWyon Bi 	switch (type) {
1041953e619SWyon Bi 	case MIPI_DSI_NULL_PACKET:
1051953e619SWyon Bi 	case MIPI_DSI_BLANKING_PACKET:
1061953e619SWyon Bi 	case MIPI_DSI_GENERIC_LONG_WRITE:
1071953e619SWyon Bi 	case MIPI_DSI_DCS_LONG_WRITE:
108*a92bdaccSGuochun Huang 	case MIPI_DSI_PICTURE_PARAMETER_SET:
109*a92bdaccSGuochun Huang 	case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
1101953e619SWyon Bi 	case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
1111953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
1121953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
1131953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_30:
1141953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_36:
1151953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
1161953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_16:
1171953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
1181953e619SWyon Bi 	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
1191953e619SWyon Bi 	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
1201953e619SWyon Bi 		return true;
1211953e619SWyon Bi 	}
1221953e619SWyon Bi 
1231953e619SWyon Bi 	return false;
1241953e619SWyon Bi }
1251953e619SWyon Bi 
1261953e619SWyon Bi /**
1271953e619SWyon Bi  * mipi_dsi_create_packet - create a packet from a message according to the
1281953e619SWyon Bi  *	DSI protocol
1291953e619SWyon Bi  * @packet: pointer to a DSI packet structure
1301953e619SWyon Bi  * @msg: message to translate into a packet
1311953e619SWyon Bi  *
1321953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
1331953e619SWyon Bi  */
mipi_dsi_create_packet(struct mipi_dsi_packet * packet,const struct mipi_dsi_msg * msg)1341953e619SWyon Bi int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
1351953e619SWyon Bi 			   const struct mipi_dsi_msg *msg)
1361953e619SWyon Bi {
1371953e619SWyon Bi 	if (!packet || !msg)
1381953e619SWyon Bi 		return -EINVAL;
1391953e619SWyon Bi 
1401953e619SWyon Bi 	/* do some minimum sanity checking */
1411953e619SWyon Bi 	if (!mipi_dsi_packet_format_is_short(msg->type) &&
1421953e619SWyon Bi 	    !mipi_dsi_packet_format_is_long(msg->type))
1431953e619SWyon Bi 		return -EINVAL;
1441953e619SWyon Bi 
1451953e619SWyon Bi 	if (msg->channel > 3)
1461953e619SWyon Bi 		return -EINVAL;
1471953e619SWyon Bi 
1481953e619SWyon Bi 	memset(packet, 0, sizeof(*packet));
1491953e619SWyon Bi 	packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
1501953e619SWyon Bi 	if (mipi_dsi_packet_format_is_long(msg->type)) {
1511953e619SWyon Bi 		packet->header[1] = (msg->tx_len >> 0) & 0xff;
1521953e619SWyon Bi 		packet->header[2] = (msg->tx_len >> 8) & 0xff;
1531953e619SWyon Bi 
1541953e619SWyon Bi 		packet->payload_length = msg->tx_len;
1551953e619SWyon Bi 		packet->payload = msg->tx_buf;
1561953e619SWyon Bi 	} else {
1571953e619SWyon Bi 		const u8 *tx = msg->tx_buf;
1581953e619SWyon Bi 
1591953e619SWyon Bi 		packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
1601953e619SWyon Bi 		packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
1611953e619SWyon Bi 	}
1621953e619SWyon Bi 
1631953e619SWyon Bi 	packet->size = sizeof(packet->header) + packet->payload_length;
1641953e619SWyon Bi 
1651953e619SWyon Bi 	return 0;
1661953e619SWyon Bi }
1671953e619SWyon Bi 
1681953e619SWyon Bi /**
1691953e619SWyon Bi  * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
1701953e619SWyon Bi  * @dsi: DSI peripheral device
1711953e619SWyon Bi  *
1721953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
1731953e619SWyon Bi  */
mipi_dsi_shutdown_peripheral(struct mipi_dsi_device * dsi)1741953e619SWyon Bi int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
1751953e619SWyon Bi {
1761953e619SWyon Bi 	struct mipi_dsi_msg msg = {
1771953e619SWyon Bi 		.channel = dsi->channel,
1781953e619SWyon Bi 		.type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
1791953e619SWyon Bi 		.tx_buf = (u8 [2]) { 0, 0 },
1801953e619SWyon Bi 		.tx_len = 2,
1811953e619SWyon Bi 	};
1821953e619SWyon Bi 	int ret = mipi_dsi_device_transfer(dsi, &msg);
1831953e619SWyon Bi 
1841953e619SWyon Bi 	return (ret < 0) ? ret : 0;
1851953e619SWyon Bi }
1861953e619SWyon Bi 
1871953e619SWyon Bi /**
1881953e619SWyon Bi  * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
1891953e619SWyon Bi  * @dsi: DSI peripheral device
1901953e619SWyon Bi  *
1911953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
1921953e619SWyon Bi  */
mipi_dsi_turn_on_peripheral(struct mipi_dsi_device * dsi)1931953e619SWyon Bi int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
1941953e619SWyon Bi {
1951953e619SWyon Bi 	struct mipi_dsi_msg msg = {
1961953e619SWyon Bi 		.channel = dsi->channel,
1971953e619SWyon Bi 		.type = MIPI_DSI_TURN_ON_PERIPHERAL,
1981953e619SWyon Bi 		.tx_buf = (u8 [2]) { 0, 0 },
1991953e619SWyon Bi 		.tx_len = 2,
2001953e619SWyon Bi 	};
2011953e619SWyon Bi 	int ret = mipi_dsi_device_transfer(dsi, &msg);
2021953e619SWyon Bi 
2031953e619SWyon Bi 	return (ret < 0) ? ret : 0;
2041953e619SWyon Bi }
2051953e619SWyon Bi 
2061953e619SWyon Bi /*
2071953e619SWyon Bi  * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the
2081953e619SWyon Bi  *	the payload in a long packet transmitted from the peripheral back to the
2091953e619SWyon Bi  *	host processor
2101953e619SWyon Bi  * @dsi: DSI peripheral device
2111953e619SWyon Bi  * @value: the maximum size of the payload
2121953e619SWyon Bi  *
2131953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
2141953e619SWyon Bi  */
mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device * dsi,u16 value)2151953e619SWyon Bi int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
2161953e619SWyon Bi 					    u16 value)
2171953e619SWyon Bi {
2181953e619SWyon Bi 	u8 tx[2] = { value & 0xff, value >> 8 };
2191953e619SWyon Bi 	struct mipi_dsi_msg msg = {
2201953e619SWyon Bi 		.channel = dsi->channel,
2211953e619SWyon Bi 		.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
2221953e619SWyon Bi 		.tx_len = sizeof(tx),
2231953e619SWyon Bi 		.tx_buf = tx,
2241953e619SWyon Bi 	};
2251953e619SWyon Bi 	int ret = mipi_dsi_device_transfer(dsi, &msg);
2261953e619SWyon Bi 
2271953e619SWyon Bi 	return (ret < 0) ? ret : 0;
2281953e619SWyon Bi }
2291953e619SWyon Bi 
2301953e619SWyon Bi /**
231*a92bdaccSGuochun Huang  * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
232*a92bdaccSGuochun Huang  * @dsi: DSI peripheral device
233*a92bdaccSGuochun Huang  * @enable: Whether to enable or disable the DSC
234*a92bdaccSGuochun Huang  *
235*a92bdaccSGuochun Huang  * Enable or disable Display Stream Compression on the peripheral using the
236*a92bdaccSGuochun Huang  * default Picture Parameter Set and VESA DSC 1.1 algorithm.
237*a92bdaccSGuochun Huang  *
238*a92bdaccSGuochun Huang  * Return: 0 on success or a negative error code on failure.
239*a92bdaccSGuochun Huang  */
mipi_dsi_compression_mode(struct mipi_dsi_device * dsi,bool enable)240*a92bdaccSGuochun Huang ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
241*a92bdaccSGuochun Huang {
242*a92bdaccSGuochun Huang 	/* Note: Needs updating for non-default PPS or algorithm */
243*a92bdaccSGuochun Huang 	u8 tx[2] = { enable << 0, 0 };
244*a92bdaccSGuochun Huang 	struct mipi_dsi_msg msg = {
245*a92bdaccSGuochun Huang 		.channel = dsi->channel,
246*a92bdaccSGuochun Huang 		.type = MIPI_DSI_COMPRESSION_MODE,
247*a92bdaccSGuochun Huang 		.tx_len = sizeof(tx),
248*a92bdaccSGuochun Huang 		.tx_buf = tx,
249*a92bdaccSGuochun Huang 	};
250*a92bdaccSGuochun Huang 	int ret = mipi_dsi_device_transfer(dsi, &msg);
251*a92bdaccSGuochun Huang 
252*a92bdaccSGuochun Huang 	return (ret < 0) ? ret : 0;
253*a92bdaccSGuochun Huang }
254*a92bdaccSGuochun Huang 
255*a92bdaccSGuochun Huang /**
256*a92bdaccSGuochun Huang  * mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
257*a92bdaccSGuochun Huang  * @dsi: DSI peripheral device
258*a92bdaccSGuochun Huang  * @pps: VESA DSC 1.1 Picture Parameter Set
259*a92bdaccSGuochun Huang  *
260*a92bdaccSGuochun Huang  * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
261*a92bdaccSGuochun Huang  *
262*a92bdaccSGuochun Huang  * Return: 0 on success or a negative error code on failure.
263*a92bdaccSGuochun Huang  */
mipi_dsi_picture_parameter_set(struct mipi_dsi_device * dsi,const struct drm_dsc_picture_parameter_set * pps)264*a92bdaccSGuochun Huang ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
265*a92bdaccSGuochun Huang 				       const struct drm_dsc_picture_parameter_set *pps)
266*a92bdaccSGuochun Huang {
267*a92bdaccSGuochun Huang 	struct mipi_dsi_msg msg = {
268*a92bdaccSGuochun Huang 		.channel = dsi->channel,
269*a92bdaccSGuochun Huang 		.type = MIPI_DSI_PICTURE_PARAMETER_SET,
270*a92bdaccSGuochun Huang 		.tx_len = sizeof(*pps),
271*a92bdaccSGuochun Huang 		.tx_buf = pps,
272*a92bdaccSGuochun Huang 	};
273*a92bdaccSGuochun Huang 	int ret = mipi_dsi_device_transfer(dsi, &msg);
274*a92bdaccSGuochun Huang 
275*a92bdaccSGuochun Huang 	return (ret < 0) ? ret : 0;
276*a92bdaccSGuochun Huang }
277*a92bdaccSGuochun Huang 
278*a92bdaccSGuochun Huang /**
2791953e619SWyon Bi  * mipi_dsi_generic_write() - transmit data using a generic write packet
2801953e619SWyon Bi  * @dsi: DSI peripheral device
2811953e619SWyon Bi  * @payload: buffer containing the payload
2821953e619SWyon Bi  * @size: size of payload buffer
2831953e619SWyon Bi  *
2841953e619SWyon Bi  * This function will automatically choose the right data type depending on
2851953e619SWyon Bi  * the payload length.
2861953e619SWyon Bi  *
2871953e619SWyon Bi  * Return: The number of bytes transmitted on success or a negative error code
2881953e619SWyon Bi  * on failure.
2891953e619SWyon Bi  */
mipi_dsi_generic_write(struct mipi_dsi_device * dsi,const void * payload,size_t size)2901953e619SWyon Bi ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
2911953e619SWyon Bi 			       size_t size)
2921953e619SWyon Bi {
2931953e619SWyon Bi 	struct mipi_dsi_msg msg = {
2941953e619SWyon Bi 		.channel = dsi->channel,
2951953e619SWyon Bi 		.tx_buf = payload,
2961953e619SWyon Bi 		.tx_len = size
2971953e619SWyon Bi 	};
2981953e619SWyon Bi 
2991953e619SWyon Bi 	switch (size) {
3001953e619SWyon Bi 	case 0:
3011953e619SWyon Bi 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
3021953e619SWyon Bi 		break;
3031953e619SWyon Bi 	case 1:
3041953e619SWyon Bi 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
3051953e619SWyon Bi 		break;
3061953e619SWyon Bi 	case 2:
3071953e619SWyon Bi 		msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
3081953e619SWyon Bi 		break;
3091953e619SWyon Bi 	default:
3101953e619SWyon Bi 		msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
3111953e619SWyon Bi 		break;
3121953e619SWyon Bi 	}
3131953e619SWyon Bi 
3141953e619SWyon Bi 	return mipi_dsi_device_transfer(dsi, &msg);
3151953e619SWyon Bi }
3161953e619SWyon Bi 
3171953e619SWyon Bi /**
3181953e619SWyon Bi  * mipi_dsi_generic_read() - receive data using a generic read packet
3191953e619SWyon Bi  * @dsi: DSI peripheral device
3201953e619SWyon Bi  * @params: buffer containing the request parameters
3211953e619SWyon Bi  * @num_params: number of request parameters
3221953e619SWyon Bi  * @data: buffer in which to return the received data
3231953e619SWyon Bi  * @size: size of receive buffer
3241953e619SWyon Bi  *
3251953e619SWyon Bi  * This function will automatically choose the right data type depending on
3261953e619SWyon Bi  * the number of parameters passed in.
3271953e619SWyon Bi  *
3281953e619SWyon Bi  * Return: The number of bytes successfully read or a negative error code on
3291953e619SWyon Bi  * failure.
3301953e619SWyon Bi  */
mipi_dsi_generic_read(struct mipi_dsi_device * dsi,const void * params,size_t num_params,void * data,size_t size)3311953e619SWyon Bi ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
3321953e619SWyon Bi 			      size_t num_params, void *data, size_t size)
3331953e619SWyon Bi {
3341953e619SWyon Bi 	struct mipi_dsi_msg msg = {
3351953e619SWyon Bi 		.channel = dsi->channel,
3361953e619SWyon Bi 		.tx_len = num_params,
3371953e619SWyon Bi 		.tx_buf = params,
3381953e619SWyon Bi 		.rx_len = size,
3391953e619SWyon Bi 		.rx_buf = data
3401953e619SWyon Bi 	};
3411953e619SWyon Bi 
3421953e619SWyon Bi 	switch (num_params) {
3431953e619SWyon Bi 	case 0:
3441953e619SWyon Bi 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
3451953e619SWyon Bi 		break;
3461953e619SWyon Bi 
3471953e619SWyon Bi 	case 1:
3481953e619SWyon Bi 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
3491953e619SWyon Bi 		break;
3501953e619SWyon Bi 
3511953e619SWyon Bi 	case 2:
3521953e619SWyon Bi 		msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
3531953e619SWyon Bi 		break;
3541953e619SWyon Bi 
3551953e619SWyon Bi 	default:
3561953e619SWyon Bi 		return -EINVAL;
3571953e619SWyon Bi 	}
3581953e619SWyon Bi 
3591953e619SWyon Bi 	return mipi_dsi_device_transfer(dsi, &msg);
3601953e619SWyon Bi }
3611953e619SWyon Bi 
3621953e619SWyon Bi /**
3631953e619SWyon Bi  * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
3641953e619SWyon Bi  * @dsi: DSI peripheral device
3651953e619SWyon Bi  * @data: buffer containing data to be transmitted
3661953e619SWyon Bi  * @len: size of transmission buffer
3671953e619SWyon Bi  *
3681953e619SWyon Bi  * This function will automatically choose the right data type depending on
3691953e619SWyon Bi  * the command payload length.
3701953e619SWyon Bi  *
3711953e619SWyon Bi  * Return: The number of bytes successfully transmitted or a negative error
3721953e619SWyon Bi  * code on failure.
3731953e619SWyon Bi  */
mipi_dsi_dcs_write_buffer(struct mipi_dsi_device * dsi,const void * data,size_t len)3741953e619SWyon Bi ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
3751953e619SWyon Bi 				  const void *data, size_t len)
3761953e619SWyon Bi {
3771953e619SWyon Bi 	struct mipi_dsi_msg msg = {
3781953e619SWyon Bi 		.channel = dsi->channel,
3791953e619SWyon Bi 		.tx_buf = data,
3801953e619SWyon Bi 		.tx_len = len
3811953e619SWyon Bi 	};
3821953e619SWyon Bi 
3831953e619SWyon Bi 	switch (len) {
3841953e619SWyon Bi 	case 0:
3851953e619SWyon Bi 		return -EINVAL;
3861953e619SWyon Bi 
3871953e619SWyon Bi 	case 1:
3881953e619SWyon Bi 		msg.type = MIPI_DSI_DCS_SHORT_WRITE;
3891953e619SWyon Bi 		break;
3901953e619SWyon Bi 
3911953e619SWyon Bi 	case 2:
3921953e619SWyon Bi 		msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
3931953e619SWyon Bi 		break;
3941953e619SWyon Bi 
3951953e619SWyon Bi 	default:
3961953e619SWyon Bi 		msg.type = MIPI_DSI_DCS_LONG_WRITE;
3971953e619SWyon Bi 		break;
3981953e619SWyon Bi 	}
3991953e619SWyon Bi 
4001953e619SWyon Bi 	return mipi_dsi_device_transfer(dsi, &msg);
4011953e619SWyon Bi }
4021953e619SWyon Bi 
4031953e619SWyon Bi /**
4041953e619SWyon Bi  * mipi_dsi_dcs_write() - send DCS write command
4051953e619SWyon Bi  * @dsi: DSI peripheral device
4061953e619SWyon Bi  * @cmd: DCS command
4071953e619SWyon Bi  * @data: buffer containing the command payload
4081953e619SWyon Bi  * @len: command payload length
4091953e619SWyon Bi  *
4101953e619SWyon Bi  * This function will automatically choose the right data type depending on
4111953e619SWyon Bi  * the command payload length.
4121953e619SWyon Bi  *
4131953e619SWyon Bi  * Return: The number of bytes successfully transmitted or a negative error
4141953e619SWyon Bi  * code on failure.
4151953e619SWyon Bi  */
mipi_dsi_dcs_write(struct mipi_dsi_device * dsi,u8 cmd,const void * data,size_t len)4161953e619SWyon Bi ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
4171953e619SWyon Bi 			   const void *data, size_t len)
4181953e619SWyon Bi {
4191953e619SWyon Bi 	ssize_t err;
4201953e619SWyon Bi 	size_t size;
4211953e619SWyon Bi 	u8 *tx;
4221953e619SWyon Bi 
4231953e619SWyon Bi 	if (len > 0) {
4241953e619SWyon Bi 		size = 1 + len;
4251953e619SWyon Bi 
4261953e619SWyon Bi 		tx = malloc(size);
4271953e619SWyon Bi 		if (!tx)
4281953e619SWyon Bi 			return -ENOMEM;
4291953e619SWyon Bi 
4301953e619SWyon Bi 		/* concatenate the DCS command byte and the payload */
4311953e619SWyon Bi 		tx[0] = cmd;
4321953e619SWyon Bi 		memcpy(&tx[1], data, len);
4331953e619SWyon Bi 	} else {
4341953e619SWyon Bi 		tx = &cmd;
4351953e619SWyon Bi 		size = 1;
4361953e619SWyon Bi 	}
4371953e619SWyon Bi 
4381953e619SWyon Bi 	err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
4391953e619SWyon Bi 
4401953e619SWyon Bi 	if (len > 0)
4411953e619SWyon Bi 		free(tx);
4421953e619SWyon Bi 
4431953e619SWyon Bi 	return err;
4441953e619SWyon Bi }
4451953e619SWyon Bi 
4461953e619SWyon Bi /**
4471953e619SWyon Bi  * mipi_dsi_dcs_read() - send DCS read request command
4481953e619SWyon Bi  * @dsi: DSI peripheral device
4491953e619SWyon Bi  * @cmd: DCS command
4501953e619SWyon Bi  * @data: buffer in which to receive data
4511953e619SWyon Bi  * @len: size of receive buffer
4521953e619SWyon Bi  * Return: The number of bytes read or a negative error code on failure.
4531953e619SWyon Bi  */
mipi_dsi_dcs_read(struct mipi_dsi_device * dsi,u8 cmd,void * data,size_t len)4541953e619SWyon Bi ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
4551953e619SWyon Bi 			  size_t len)
4561953e619SWyon Bi {
4571953e619SWyon Bi 	struct mipi_dsi_msg msg = {
4581953e619SWyon Bi 		.channel = dsi->channel,
4591953e619SWyon Bi 		.type = MIPI_DSI_DCS_READ,
4601953e619SWyon Bi 		.tx_buf = &cmd,
4611953e619SWyon Bi 		.tx_len = 1,
4621953e619SWyon Bi 		.rx_buf = data,
4631953e619SWyon Bi 		.rx_len = len
4641953e619SWyon Bi 	};
4651953e619SWyon Bi 
4661953e619SWyon Bi 	return mipi_dsi_device_transfer(dsi, &msg);
4671953e619SWyon Bi }
4681953e619SWyon Bi 
4691953e619SWyon Bi /**
4701953e619SWyon Bi  * mipi_dsi_dcs_nop() - send DCS nop packet
4711953e619SWyon Bi  * @dsi: DSI peripheral device
4721953e619SWyon Bi  *
4731953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
4741953e619SWyon Bi  */
mipi_dsi_dcs_nop(struct mipi_dsi_device * dsi)4751953e619SWyon Bi int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
4761953e619SWyon Bi {
4771953e619SWyon Bi 	ssize_t err;
4781953e619SWyon Bi 
4791953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
4801953e619SWyon Bi 	if (err < 0)
4811953e619SWyon Bi 		return err;
4821953e619SWyon Bi 
4831953e619SWyon Bi 	return 0;
4841953e619SWyon Bi }
4851953e619SWyon Bi 
4861953e619SWyon Bi /**
4871953e619SWyon Bi  * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
4881953e619SWyon Bi  * @dsi: DSI peripheral device
4891953e619SWyon Bi  *
4901953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
4911953e619SWyon Bi  */
mipi_dsi_dcs_soft_reset(struct mipi_dsi_device * dsi)4921953e619SWyon Bi int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
4931953e619SWyon Bi {
4941953e619SWyon Bi 	ssize_t err;
4951953e619SWyon Bi 
4961953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
4971953e619SWyon Bi 	if (err < 0)
4981953e619SWyon Bi 		return err;
4991953e619SWyon Bi 
5001953e619SWyon Bi 	return 0;
5011953e619SWyon Bi }
5021953e619SWyon Bi 
5031953e619SWyon Bi /**
5041953e619SWyon Bi  * mipi_dsi_dcs_get_power_mode() - query the display module's current power
5051953e619SWyon Bi  *	mode
5061953e619SWyon Bi  * @dsi: DSI peripheral device
5071953e619SWyon Bi  * @mode: return location for the current power mode
5081953e619SWyon Bi  *
5091953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
5101953e619SWyon Bi  */
mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device * dsi,u8 * mode)5111953e619SWyon Bi int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
5121953e619SWyon Bi {
5131953e619SWyon Bi 	ssize_t err;
5141953e619SWyon Bi 
5151953e619SWyon Bi 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
5161953e619SWyon Bi 				sizeof(*mode));
5171953e619SWyon Bi 	if (err <= 0) {
5181953e619SWyon Bi 		if (err == 0)
5191953e619SWyon Bi 			err = -ENODATA;
5201953e619SWyon Bi 
5211953e619SWyon Bi 		return err;
5221953e619SWyon Bi 	}
5231953e619SWyon Bi 
5241953e619SWyon Bi 	return 0;
5251953e619SWyon Bi }
5261953e619SWyon Bi 
5271953e619SWyon Bi /**
5281953e619SWyon Bi  * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
5291953e619SWyon Bi  *	data used by the interface
5301953e619SWyon Bi  * @dsi: DSI peripheral device
5311953e619SWyon Bi  * @format: return location for the pixel format
5321953e619SWyon Bi  *
5331953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
5341953e619SWyon Bi  */
mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device * dsi,u8 * format)5351953e619SWyon Bi int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
5361953e619SWyon Bi {
5371953e619SWyon Bi 	ssize_t err;
5381953e619SWyon Bi 
5391953e619SWyon Bi 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
5401953e619SWyon Bi 				sizeof(*format));
5411953e619SWyon Bi 	if (err <= 0) {
5421953e619SWyon Bi 		if (err == 0)
5431953e619SWyon Bi 			err = -ENODATA;
5441953e619SWyon Bi 
5451953e619SWyon Bi 		return err;
5461953e619SWyon Bi 	}
5471953e619SWyon Bi 
5481953e619SWyon Bi 	return 0;
5491953e619SWyon Bi }
5501953e619SWyon Bi 
5511953e619SWyon Bi /**
5521953e619SWyon Bi  * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
5531953e619SWyon Bi  *	display module except interface communication
5541953e619SWyon Bi  * @dsi: DSI peripheral device
5551953e619SWyon Bi  *
5561953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
5571953e619SWyon Bi  */
mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device * dsi)5581953e619SWyon Bi int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
5591953e619SWyon Bi {
5601953e619SWyon Bi 	ssize_t err;
5611953e619SWyon Bi 
5621953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
5631953e619SWyon Bi 	if (err < 0)
5641953e619SWyon Bi 		return err;
5651953e619SWyon Bi 
5661953e619SWyon Bi 	return 0;
5671953e619SWyon Bi }
5681953e619SWyon Bi 
5691953e619SWyon Bi /**
5701953e619SWyon Bi  * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
5711953e619SWyon Bi  *	module
5721953e619SWyon Bi  * @dsi: DSI peripheral device
5731953e619SWyon Bi  *
5741953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
5751953e619SWyon Bi  */
mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device * dsi)5761953e619SWyon Bi int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
5771953e619SWyon Bi {
5781953e619SWyon Bi 	ssize_t err;
5791953e619SWyon Bi 
5801953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
5811953e619SWyon Bi 	if (err < 0)
5821953e619SWyon Bi 		return err;
5831953e619SWyon Bi 
5841953e619SWyon Bi 	return 0;
5851953e619SWyon Bi }
5861953e619SWyon Bi 
5871953e619SWyon Bi /**
5881953e619SWyon Bi  * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
5891953e619SWyon Bi  *	display device
5901953e619SWyon Bi  * @dsi: DSI peripheral device
5911953e619SWyon Bi  *
5921953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
5931953e619SWyon Bi  */
mipi_dsi_dcs_set_display_off(struct mipi_dsi_device * dsi)5941953e619SWyon Bi int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
5951953e619SWyon Bi {
5961953e619SWyon Bi 	ssize_t err;
5971953e619SWyon Bi 
5981953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
5991953e619SWyon Bi 	if (err < 0)
6001953e619SWyon Bi 		return err;
6011953e619SWyon Bi 
6021953e619SWyon Bi 	return 0;
6031953e619SWyon Bi }
6041953e619SWyon Bi 
6051953e619SWyon Bi /**
6061953e619SWyon Bi  * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
6071953e619SWyon Bi  *	display device
6081953e619SWyon Bi  * @dsi: DSI peripheral device
6091953e619SWyon Bi  *
6101953e619SWyon Bi  * Return: 0 on success or a negative error code on failure
6111953e619SWyon Bi  */
mipi_dsi_dcs_set_display_on(struct mipi_dsi_device * dsi)6121953e619SWyon Bi int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
6131953e619SWyon Bi {
6141953e619SWyon Bi 	ssize_t err;
6151953e619SWyon Bi 
6161953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
6171953e619SWyon Bi 	if (err < 0)
6181953e619SWyon Bi 		return err;
6191953e619SWyon Bi 
6201953e619SWyon Bi 	return 0;
6211953e619SWyon Bi }
6221953e619SWyon Bi 
6231953e619SWyon Bi /**
6241953e619SWyon Bi  * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
6251953e619SWyon Bi  *	memory accessed by the host processor
6261953e619SWyon Bi  * @dsi: DSI peripheral device
6271953e619SWyon Bi  * @start: first column of frame memory
6281953e619SWyon Bi  * @end: last column of frame memory
6291953e619SWyon Bi  *
6301953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
6311953e619SWyon Bi  */
mipi_dsi_dcs_set_column_address(struct mipi_dsi_device * dsi,u16 start,u16 end)6321953e619SWyon Bi int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
6331953e619SWyon Bi 				    u16 end)
6341953e619SWyon Bi {
6351953e619SWyon Bi 	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
6361953e619SWyon Bi 	ssize_t err;
6371953e619SWyon Bi 
6381953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
6391953e619SWyon Bi 				 sizeof(payload));
6401953e619SWyon Bi 	if (err < 0)
6411953e619SWyon Bi 		return err;
6421953e619SWyon Bi 
6431953e619SWyon Bi 	return 0;
6441953e619SWyon Bi }
6451953e619SWyon Bi 
6461953e619SWyon Bi /**
6471953e619SWyon Bi  * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
6481953e619SWyon Bi  *	memory accessed by the host processor
6491953e619SWyon Bi  * @dsi: DSI peripheral device
6501953e619SWyon Bi  * @start: first page of frame memory
6511953e619SWyon Bi  * @end: last page of frame memory
6521953e619SWyon Bi  *
6531953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
6541953e619SWyon Bi  */
mipi_dsi_dcs_set_page_address(struct mipi_dsi_device * dsi,u16 start,u16 end)6551953e619SWyon Bi int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
6561953e619SWyon Bi 				  u16 end)
6571953e619SWyon Bi {
6581953e619SWyon Bi 	u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
6591953e619SWyon Bi 	ssize_t err;
6601953e619SWyon Bi 
6611953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
6621953e619SWyon Bi 				 sizeof(payload));
6631953e619SWyon Bi 	if (err < 0)
6641953e619SWyon Bi 		return err;
6651953e619SWyon Bi 
6661953e619SWyon Bi 	return 0;
6671953e619SWyon Bi }
6681953e619SWyon Bi 
6691953e619SWyon Bi /**
6701953e619SWyon Bi  * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
6711953e619SWyon Bi  *	output signal on the TE signal line
6721953e619SWyon Bi  * @dsi: DSI peripheral device
6731953e619SWyon Bi  *
6741953e619SWyon Bi  * Return: 0 on success or a negative error code on failure
6751953e619SWyon Bi  */
mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device * dsi)6761953e619SWyon Bi int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
6771953e619SWyon Bi {
6781953e619SWyon Bi 	ssize_t err;
6791953e619SWyon Bi 
6801953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
6811953e619SWyon Bi 	if (err < 0)
6821953e619SWyon Bi 		return err;
6831953e619SWyon Bi 
6841953e619SWyon Bi 	return 0;
6851953e619SWyon Bi }
6861953e619SWyon Bi 
6871953e619SWyon Bi /**
6881953e619SWyon Bi  * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
6891953e619SWyon Bi  *	output signal on the TE signal line.
6901953e619SWyon Bi  * @dsi: DSI peripheral device
6911953e619SWyon Bi  * @mode: the Tearing Effect Output Line mode
6921953e619SWyon Bi  *
6931953e619SWyon Bi  * Return: 0 on success or a negative error code on failure
6941953e619SWyon Bi  */
mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device * dsi,enum mipi_dsi_dcs_tear_mode mode)6951953e619SWyon Bi int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
6961953e619SWyon Bi 			     enum mipi_dsi_dcs_tear_mode mode)
6971953e619SWyon Bi {
6981953e619SWyon Bi 	u8 value = mode;
6991953e619SWyon Bi 	ssize_t err;
7001953e619SWyon Bi 
7011953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
7021953e619SWyon Bi 				 sizeof(value));
7031953e619SWyon Bi 	if (err < 0)
7041953e619SWyon Bi 		return err;
7051953e619SWyon Bi 
7061953e619SWyon Bi 	return 0;
7071953e619SWyon Bi }
7081953e619SWyon Bi 
7091953e619SWyon Bi /**
7101953e619SWyon Bi  * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
7111953e619SWyon Bi  *	data used by the interface
7121953e619SWyon Bi  * @dsi: DSI peripheral device
7131953e619SWyon Bi  * @format: pixel format
7141953e619SWyon Bi  *
7151953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
7161953e619SWyon Bi  */
mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device * dsi,u8 format)7171953e619SWyon Bi int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
7181953e619SWyon Bi {
7191953e619SWyon Bi 	ssize_t err;
7201953e619SWyon Bi 
7211953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
7221953e619SWyon Bi 				 sizeof(format));
7231953e619SWyon Bi 	if (err < 0)
7241953e619SWyon Bi 		return err;
7251953e619SWyon Bi 
7261953e619SWyon Bi 	return 0;
7271953e619SWyon Bi }
7281953e619SWyon Bi 
7291953e619SWyon Bi /**
7301953e619SWyon Bi  * mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for
7311953e619SWyon Bi  *	the Tearing Effect output signal of the display module
7321953e619SWyon Bi  * @dsi: DSI peripheral device
7331953e619SWyon Bi  * @scanline: scanline to use as trigger
7341953e619SWyon Bi  *
7351953e619SWyon Bi  * Return: 0 on success or a negative error code on failure
7361953e619SWyon Bi  */
mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device * dsi,u16 scanline)7371953e619SWyon Bi int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)
7381953e619SWyon Bi {
7391953e619SWyon Bi 	u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8,
7401953e619SWyon Bi 				scanline & 0xff };
7411953e619SWyon Bi 	ssize_t err;
7421953e619SWyon Bi 
7431953e619SWyon Bi 	err = mipi_dsi_generic_write(dsi, payload, sizeof(payload));
7441953e619SWyon Bi 	if (err < 0)
7451953e619SWyon Bi 		return err;
7461953e619SWyon Bi 
7471953e619SWyon Bi 	return 0;
7481953e619SWyon Bi }
7491953e619SWyon Bi 
7501953e619SWyon Bi /**
7511953e619SWyon Bi  * mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the
7521953e619SWyon Bi  *	display
7531953e619SWyon Bi  * @dsi: DSI peripheral device
7541953e619SWyon Bi  * @brightness: brightness value
7551953e619SWyon Bi  *
7561953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
7571953e619SWyon Bi  */
mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device * dsi,u16 brightness)7581953e619SWyon Bi int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
7591953e619SWyon Bi 					u16 brightness)
7601953e619SWyon Bi {
7611953e619SWyon Bi 	u8 payload[2] = { brightness & 0xff, brightness >> 8 };
7621953e619SWyon Bi 	ssize_t err;
7631953e619SWyon Bi 
7641953e619SWyon Bi 	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
7651953e619SWyon Bi 				 payload, sizeof(payload));
7661953e619SWyon Bi 	if (err < 0)
7671953e619SWyon Bi 		return err;
7681953e619SWyon Bi 
7691953e619SWyon Bi 	return 0;
7701953e619SWyon Bi }
7711953e619SWyon Bi 
7721953e619SWyon Bi /**
7731953e619SWyon Bi  * mipi_dsi_dcs_get_display_brightness() - gets the current brightness value
7741953e619SWyon Bi  *	of the display
7751953e619SWyon Bi  * @dsi: DSI peripheral device
7761953e619SWyon Bi  * @brightness: brightness value
7771953e619SWyon Bi  *
7781953e619SWyon Bi  * Return: 0 on success or a negative error code on failure.
7791953e619SWyon Bi  */
mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device * dsi,u16 * brightness)7801953e619SWyon Bi int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
7811953e619SWyon Bi 					u16 *brightness)
7821953e619SWyon Bi {
7831953e619SWyon Bi 	ssize_t err;
7841953e619SWyon Bi 
7851953e619SWyon Bi 	err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
7861953e619SWyon Bi 				brightness, sizeof(*brightness));
7871953e619SWyon Bi 	if (err <= 0) {
7881953e619SWyon Bi 		if (err == 0)
7891953e619SWyon Bi 			err = -ENODATA;
7901953e619SWyon Bi 
7911953e619SWyon Bi 		return err;
7921953e619SWyon Bi 	}
7931953e619SWyon Bi 
7941953e619SWyon Bi 	return 0;
7951953e619SWyon Bi }
796