Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Copyright © 2009 Keith Packard
  3 *
  4 * Permission to use, copy, modify, distribute, and sell this software and its
  5 * documentation for any purpose is hereby granted without fee, provided that
  6 * the above copyright notice appear in all copies and that both that copyright
  7 * notice and this permission notice appear in supporting documentation, and
  8 * that the name of the copyright holders not be used in advertising or
  9 * publicity pertaining to distribution of the software without specific,
 10 * written prior permission.  The copyright holders make no representations
 11 * about the suitability of this software for any purpose.  It is provided "as
 12 * is" without express or implied warranty.
 13 *
 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 20 * OF THIS SOFTWARE.
 21 */
 22
 23#include <linux/kernel.h>
 24#include <linux/module.h>
 25#include <linux/delay.h>
 26#include <linux/init.h>
 27#include <linux/errno.h>
 28#include <linux/sched.h>
 29#include <linux/i2c.h>
 30#include <drm/drm_dp_helper.h>
 31#include <drm/drmP.h>
 32
 33/**
 34 * DOC: dp helpers
 35 *
 36 * These functions contain some common logic and helpers at various abstraction
 37 * levels to deal with Display Port sink devices and related things like DP aux
 38 * channel transfers, EDID reading over DP aux channels, decoding certain DPCD
 39 * blocks, ...
 40 */
 41
 42/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
 43static int
 44i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
 45			    uint8_t write_byte, uint8_t *read_byte)
 46{
 47	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
 48	int ret;
 49
 50	ret = (*algo_data->aux_ch)(adapter, mode,
 51				   write_byte, read_byte);
 52	return ret;
 53}
 54
 55/*
 56 * I2C over AUX CH
 57 */
 58
 59/*
 60 * Send the address. If the I2C link is running, this 'restarts'
 61 * the connection with the new address, this is used for doing
 62 * a write followed by a read (as needed for DDC)
 63 */
 64static int
 65i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
 66{
 67	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
 68	int mode = MODE_I2C_START;
 69	int ret;
 70
 71	if (reading)
 72		mode |= MODE_I2C_READ;
 73	else
 74		mode |= MODE_I2C_WRITE;
 75	algo_data->address = address;
 76	algo_data->running = true;
 77	ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
 78	return ret;
 79}
 80
 81/*
 82 * Stop the I2C transaction. This closes out the link, sending
 83 * a bare address packet with the MOT bit turned off
 84 */
 85static void
 86i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
 87{
 88	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
 89	int mode = MODE_I2C_STOP;
 90
 91	if (reading)
 92		mode |= MODE_I2C_READ;
 93	else
 94		mode |= MODE_I2C_WRITE;
 95	if (algo_data->running) {
 96		(void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
 97		algo_data->running = false;
 98	}
 99}
100
101/*
102 * Write a single byte to the current I2C address, the
103 * the I2C link must be running or this returns -EIO
104 */
105static int
106i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
107{
108	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
109	int ret;
110
111	if (!algo_data->running)
112		return -EIO;
113
114	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
115	return ret;
116}
117
118/*
119 * Read a single byte from the current I2C address, the
120 * I2C link must be running or this returns -EIO
121 */
122static int
123i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
124{
125	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
126	int ret;
127
128	if (!algo_data->running)
129		return -EIO;
130
131	ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
132	return ret;
133}
134
135static int
136i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
137		     struct i2c_msg *msgs,
138		     int num)
139{
140	int ret = 0;
141	bool reading = false;
142	int m;
143	int b;
144
145	for (m = 0; m < num; m++) {
146		u16 len = msgs[m].len;
147		u8 *buf = msgs[m].buf;
148		reading = (msgs[m].flags & I2C_M_RD) != 0;
149		ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
150		if (ret < 0)
151			break;
152		if (reading) {
153			for (b = 0; b < len; b++) {
154				ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
155				if (ret < 0)
156					break;
157			}
158		} else {
159			for (b = 0; b < len; b++) {
160				ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
161				if (ret < 0)
162					break;
163			}
164		}
165		if (ret < 0)
166			break;
167	}
168	if (ret >= 0)
169		ret = num;
170	i2c_algo_dp_aux_stop(adapter, reading);
171	DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
172	return ret;
173}
174
175static u32
176i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
177{
178	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
179	       I2C_FUNC_SMBUS_READ_BLOCK_DATA |
180	       I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
181	       I2C_FUNC_10BIT_ADDR;
182}
183
184static const struct i2c_algorithm i2c_dp_aux_algo = {
185	.master_xfer	= i2c_algo_dp_aux_xfer,
186	.functionality	= i2c_algo_dp_aux_functionality,
187};
188
189static void
190i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
191{
192	(void) i2c_algo_dp_aux_address(adapter, 0, false);
193	(void) i2c_algo_dp_aux_stop(adapter, false);
194}
195
196static int
197i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
198{
199	adapter->algo = &i2c_dp_aux_algo;
200	adapter->retries = 3;
201	i2c_dp_aux_reset_bus(adapter);
202	return 0;
203}
204
205/**
206 * i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper
207 * @adapter: i2c adapter to register
208 *
209 * This registers an i2c adapater that uses dp aux channel as it's underlaying
210 * transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure
211 * and store it in the algo_data member of the @adapter argument. This will be
212 * used by the i2c over dp aux algorithm to drive the hardware.
213 *
214 * RETURNS:
215 * 0 on success, -ERRNO on failure.
216 */
217int
218i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
219{
220	int error;
221
222	error = i2c_dp_aux_prepare_bus(adapter);
223	if (error)
224		return error;
225	error = i2c_add_adapter(adapter);
226	return error;
227}
228EXPORT_SYMBOL(i2c_dp_aux_add_bus);
229
230/* Helpers for DP link training */
231static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
232{
233	return link_status[r - DP_LANE0_1_STATUS];
234}
235
236static u8 dp_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
237			     int lane)
238{
239	int i = DP_LANE0_1_STATUS + (lane >> 1);
240	int s = (lane & 1) * 4;
241	u8 l = dp_link_status(link_status, i);
242	return (l >> s) & 0xf;
243}
244
245bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
246			  int lane_count)
247{
248	u8 lane_align;
249	u8 lane_status;
250	int lane;
251
252	lane_align = dp_link_status(link_status,
253				    DP_LANE_ALIGN_STATUS_UPDATED);
254	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
255		return false;
256	for (lane = 0; lane < lane_count; lane++) {
257		lane_status = dp_get_lane_status(link_status, lane);
258		if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
259			return false;
260	}
261	return true;
262}
263EXPORT_SYMBOL(drm_dp_channel_eq_ok);
264
265bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
266			      int lane_count)
267{
268	int lane;
269	u8 lane_status;
270
271	for (lane = 0; lane < lane_count; lane++) {
272		lane_status = dp_get_lane_status(link_status, lane);
273		if ((lane_status & DP_LANE_CR_DONE) == 0)
274			return false;
275	}
276	return true;
277}
278EXPORT_SYMBOL(drm_dp_clock_recovery_ok);
279
280u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
281				     int lane)
282{
283	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
284	int s = ((lane & 1) ?
285		 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
286		 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
287	u8 l = dp_link_status(link_status, i);
288
289	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
290}
291EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage);
292
293u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
294					  int lane)
295{
296	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
297	int s = ((lane & 1) ?
298		 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
299		 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
300	u8 l = dp_link_status(link_status, i);
301
302	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
303}
304EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
305
306void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
307	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
308		udelay(100);
309	else
310		mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
311}
312EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
313
314void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
315	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
316		udelay(400);
317	else
318		mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
319}
320EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay);
321
322u8 drm_dp_link_rate_to_bw_code(int link_rate)
323{
324	switch (link_rate) {
325	case 162000:
326	default:
327		return DP_LINK_BW_1_62;
328	case 270000:
329		return DP_LINK_BW_2_7;
330	case 540000:
331		return DP_LINK_BW_5_4;
332	}
333}
334EXPORT_SYMBOL(drm_dp_link_rate_to_bw_code);
335
336int drm_dp_bw_code_to_link_rate(u8 link_bw)
337{
338	switch (link_bw) {
339	case DP_LINK_BW_1_62:
340	default:
341		return 162000;
342	case DP_LINK_BW_2_7:
343		return 270000;
344	case DP_LINK_BW_5_4:
345		return 540000;
346	}
347}
348EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate);
349
350/**
351 * DOC: dp helpers
352 *
353 * The DisplayPort AUX channel is an abstraction to allow generic, driver-
354 * independent access to AUX functionality. Drivers can take advantage of
355 * this by filling in the fields of the drm_dp_aux structure.
356 *
357 * Transactions are described using a hardware-independent drm_dp_aux_msg
358 * structure, which is passed into a driver's .transfer() implementation.
359 * Both native and I2C-over-AUX transactions are supported.
360 */
361
362static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
363			      unsigned int offset, void *buffer, size_t size)
364{
365	struct drm_dp_aux_msg msg;
366	unsigned int retry;
367	int err;
368
369	memset(&msg, 0, sizeof(msg));
370	msg.address = offset;
371	msg.request = request;
372	msg.buffer = buffer;
373	msg.size = size;
374
375	/*
376	 * The specification doesn't give any recommendation on how often to
377	 * retry native transactions, so retry 7 times like for I2C-over-AUX
378	 * transactions.
379	 */
380	for (retry = 0; retry < 7; retry++) {
381		err = aux->transfer(aux, &msg);
382		if (err < 0) {
383			if (err == -EBUSY)
384				continue;
385
386			return err;
387		}
388
389
390		switch (msg.reply & DP_AUX_NATIVE_REPLY_MASK) {
391		case DP_AUX_NATIVE_REPLY_ACK:
392			if (err < size)
393				return -EPROTO;
394			return err;
395
396		case DP_AUX_NATIVE_REPLY_NACK:
397			return -EIO;
398
399		case DP_AUX_NATIVE_REPLY_DEFER:
400			usleep_range(400, 500);
401			break;
402		}
403	}
404
405	DRM_DEBUG_KMS("too many retries, giving up\n");
406	return -EIO;
407}
408
409/**
410 * drm_dp_dpcd_read() - read a series of bytes from the DPCD
411 * @aux: DisplayPort AUX channel
412 * @offset: address of the (first) register to read
413 * @buffer: buffer to store the register values
414 * @size: number of bytes in @buffer
415 *
416 * Returns the number of bytes transferred on success, or a negative error
417 * code on failure. -EIO is returned if the request was NAKed by the sink or
418 * if the retry count was exceeded. If not all bytes were transferred, this
419 * function returns -EPROTO. Errors from the underlying AUX channel transfer
420 * function, with the exception of -EBUSY (which causes the transaction to
421 * be retried), are propagated to the caller.
422 */
423ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
424			 void *buffer, size_t size)
425{
426	return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, offset, buffer,
427				  size);
428}
429EXPORT_SYMBOL(drm_dp_dpcd_read);
430
431/**
432 * drm_dp_dpcd_write() - write a series of bytes to the DPCD
433 * @aux: DisplayPort AUX channel
434 * @offset: address of the (first) register to write
435 * @buffer: buffer containing the values to write
436 * @size: number of bytes in @buffer
437 *
438 * Returns the number of bytes transferred on success, or a negative error
439 * code on failure. -EIO is returned if the request was NAKed by the sink or
440 * if the retry count was exceeded. If not all bytes were transferred, this
441 * function returns -EPROTO. Errors from the underlying AUX channel transfer
442 * function, with the exception of -EBUSY (which causes the transaction to
443 * be retried), are propagated to the caller.
444 */
445ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
446			  void *buffer, size_t size)
447{
448	return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_WRITE, offset, buffer,
449				  size);
450}
451EXPORT_SYMBOL(drm_dp_dpcd_write);
452
453/**
454 * drm_dp_dpcd_read_link_status() - read DPCD link status (bytes 0x202-0x207)
455 * @aux: DisplayPort AUX channel
456 * @status: buffer to store the link status in (must be at least 6 bytes)
457 *
458 * Returns the number of bytes transferred on success or a negative error
459 * code on failure.
460 */
461int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
462				 u8 status[DP_LINK_STATUS_SIZE])
463{
464	return drm_dp_dpcd_read(aux, DP_LANE0_1_STATUS, status,
465				DP_LINK_STATUS_SIZE);
466}
467EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
468
469/**
470 * drm_dp_link_probe() - probe a DisplayPort link for capabilities
471 * @aux: DisplayPort AUX channel
472 * @link: pointer to structure in which to return link capabilities
473 *
474 * The structure filled in by this function can usually be passed directly
475 * into drm_dp_link_power_up() and drm_dp_link_configure() to power up and
476 * configure the link based on the link's capabilities.
477 *
478 * Returns 0 on success or a negative error code on failure.
479 */
480int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link)
481{
482	u8 values[3];
483	int err;
484
485	memset(link, 0, sizeof(*link));
486
487	err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values));
488	if (err < 0)
489		return err;
490
491	link->revision = values[0];
492	link->rate = drm_dp_bw_code_to_link_rate(values[1]);
493	link->num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
494
495	if (values[2] & DP_ENHANCED_FRAME_CAP)
496		link->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
497
498	return 0;
499}
500EXPORT_SYMBOL(drm_dp_link_probe);
501
502/**
503 * drm_dp_link_power_up() - power up a DisplayPort link
504 * @aux: DisplayPort AUX channel
505 * @link: pointer to a structure containing the link configuration
506 *
507 * Returns 0 on success or a negative error code on failure.
508 */
509int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link)
510{
511	u8 value;
512	int err;
513
514	/* DP_SET_POWER register is only available on DPCD v1.1 and later */
515	if (link->revision < 0x11)
516		return 0;
517
518	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
519	if (err < 0)
520		return err;
521
522	value &= ~DP_SET_POWER_MASK;
523	value |= DP_SET_POWER_D0;
524
525	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
526	if (err < 0)
527		return err;
528
529	/*
530	 * According to the DP 1.1 specification, a "Sink Device must exit the
531	 * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
532	 * Control Field" (register 0x600).
533	 */
534	usleep_range(1000, 2000);
535
536	return 0;
537}
538EXPORT_SYMBOL(drm_dp_link_power_up);
539
540/**
541 * drm_dp_link_configure() - configure a DisplayPort link
542 * @aux: DisplayPort AUX channel
543 * @link: pointer to a structure containing the link configuration
544 *
545 * Returns 0 on success or a negative error code on failure.
546 */
547int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
548{
549	u8 values[2];
550	int err;
551
552	values[0] = drm_dp_link_rate_to_bw_code(link->rate);
553	values[1] = link->num_lanes;
554
555	if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
556		values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
557
558	err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values));
559	if (err < 0)
560		return err;
561
562	return 0;
563}
564EXPORT_SYMBOL(drm_dp_link_configure);
565
566/*
567 * I2C-over-AUX implementation
568 */
569
570static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
571{
572	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
573	       I2C_FUNC_SMBUS_READ_BLOCK_DATA |
574	       I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
575	       I2C_FUNC_10BIT_ADDR;
576}
577
578/*
579 * Transfer a single I2C-over-AUX message and handle various error conditions,
580 * retrying the transaction as appropriate.  It is assumed that the
581 * aux->transfer function does not modify anything in the msg other than the
582 * reply field.
583 */
584static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
585{
586	unsigned int retry;
587	int err;
588
589	/*
590	 * DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device
591	 * is required to retry at least seven times upon receiving AUX_DEFER
592	 * before giving up the AUX transaction.
593	 */
594	for (retry = 0; retry < 7; retry++) {
595		err = aux->transfer(aux, msg);
596		if (err < 0) {
597			if (err == -EBUSY)
598				continue;
599
600			DRM_DEBUG_KMS("transaction failed: %d\n", err);
601			return err;
602		}
603
604
605		switch (msg->reply & DP_AUX_NATIVE_REPLY_MASK) {
606		case DP_AUX_NATIVE_REPLY_ACK:
607			/*
608			 * For I2C-over-AUX transactions this isn't enough, we
609			 * need to check for the I2C ACK reply.
610			 */
611			break;
612
613		case DP_AUX_NATIVE_REPLY_NACK:
614			DRM_DEBUG_KMS("native nack\n");
615			return -EREMOTEIO;
616
617		case DP_AUX_NATIVE_REPLY_DEFER:
618			DRM_DEBUG_KMS("native defer");
619			/*
620			 * We could check for I2C bit rate capabilities and if
621			 * available adjust this interval. We could also be
622			 * more careful with DP-to-legacy adapters where a
623			 * long legacy cable may force very low I2C bit rates.
624			 *
625			 * For now just defer for long enough to hopefully be
626			 * safe for all use-cases.
627			 */
628			usleep_range(500, 600);
629			continue;
630
631		default:
632			DRM_ERROR("invalid native reply %#04x\n", msg->reply);
633			return -EREMOTEIO;
634		}
635
636		switch (msg->reply & DP_AUX_I2C_REPLY_MASK) {
637		case DP_AUX_I2C_REPLY_ACK:
638			/*
639			 * Both native ACK and I2C ACK replies received. We
640			 * can assume the transfer was successful.
641			 */
642			if (err < msg->size)
643				return -EPROTO;
644			return 0;
645
646		case DP_AUX_I2C_REPLY_NACK:
647			DRM_DEBUG_KMS("I2C nack\n");
648			return -EREMOTEIO;
649
650		case DP_AUX_I2C_REPLY_DEFER:
651			DRM_DEBUG_KMS("I2C defer\n");
652			usleep_range(400, 500);
653			continue;
654
655		default:
656			DRM_ERROR("invalid I2C reply %#04x\n", msg->reply);
657			return -EREMOTEIO;
658		}
659	}
660
661	DRM_DEBUG_KMS("too many retries, giving up\n");
662	return -EREMOTEIO;
663}
664
665static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
666			   int num)
667{
668	struct drm_dp_aux *aux = adapter->algo_data;
669	unsigned int i, j;
670	struct drm_dp_aux_msg msg;
671	int err = 0;
672
673	memset(&msg, 0, sizeof(msg));
674
675	for (i = 0; i < num; i++) {
676		msg.address = msgs[i].addr;
677		msg.request = (msgs[i].flags & I2C_M_RD) ?
678			DP_AUX_I2C_READ :
679			DP_AUX_I2C_WRITE;
680		msg.request |= DP_AUX_I2C_MOT;
681		/* Send a bare address packet to start the transaction.
682		 * Zero sized messages specify an address only (bare
683		 * address) transaction.
684		 */
685		msg.buffer = NULL;
686		msg.size = 0;
687		err = drm_dp_i2c_do_msg(aux, &msg);
688		if (err < 0)
689			break;
690		/*
691		 * Many hardware implementations support FIFOs larger than a
692		 * single byte, but it has been empirically determined that
693		 * transferring data in larger chunks can actually lead to
694		 * decreased performance. Therefore each message is simply
695		 * transferred byte-by-byte.
696		 */
697		for (j = 0; j < msgs[i].len; j++) {
698			msg.buffer = msgs[i].buf + j;
699			msg.size = 1;
700
701			err = drm_dp_i2c_do_msg(aux, &msg);
702			if (err < 0)
703				break;
704		}
705		if (err < 0)
706			break;
707	}
708	if (err >= 0)
709		err = num;
710	/* Send a bare address packet to close out the transaction.
711	 * Zero sized messages specify an address only (bare
712	 * address) transaction.
713	 */
714	msg.request &= ~DP_AUX_I2C_MOT;
715	msg.buffer = NULL;
716	msg.size = 0;
717	(void)drm_dp_i2c_do_msg(aux, &msg);
718
719	return err;
720}
721
722static const struct i2c_algorithm drm_dp_i2c_algo = {
723	.functionality = drm_dp_i2c_functionality,
724	.master_xfer = drm_dp_i2c_xfer,
725};
726
727/**
728 * drm_dp_aux_register_i2c_bus() - register an I2C adapter for I2C-over-AUX
729 * @aux: DisplayPort AUX channel
730 *
731 * Returns 0 on success or a negative error code on failure.
732 */
733int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux)
734{
735	aux->ddc.algo = &drm_dp_i2c_algo;
736	aux->ddc.algo_data = aux;
737	aux->ddc.retries = 3;
738
739	aux->ddc.class = I2C_CLASS_DDC;
740	aux->ddc.owner = THIS_MODULE;
741	aux->ddc.dev.parent = aux->dev;
742	aux->ddc.dev.of_node = aux->dev->of_node;
743
744	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
745		sizeof(aux->ddc.name));
746
747	return i2c_add_adapter(&aux->ddc);
748}
749EXPORT_SYMBOL(drm_dp_aux_register_i2c_bus);
750
751/**
752 * drm_dp_aux_unregister_i2c_bus() - unregister an I2C-over-AUX adapter
753 * @aux: DisplayPort AUX channel
754 */
755void drm_dp_aux_unregister_i2c_bus(struct drm_dp_aux *aux)
756{
757	i2c_del_adapter(&aux->ddc);
758}
759EXPORT_SYMBOL(drm_dp_aux_unregister_i2c_bus);