Commit e4c6eb68 authored by Min Li's avatar Min Li Committed by Jakub Kicinski
Browse files

ptp: idt82p33: use i2c_master_send for bus write



Refactor idt82p33_xfer and use i2c_master_send for write operation.
Because some I2C controllers are only working with single-burst write
transaction.

Signed-off-by: default avatarMin Li <min.li.xe@renesas.com>
Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Link: https://lore.kernel.org/r/1604634729-24960-2-git-send-email-min.li.xe@renesas.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e014ae39
Loading
Loading
Loading
Loading
+36 −11
Original line number Diff line number Diff line
@@ -78,11 +78,10 @@ static void idt82p33_timespec_to_byte_array(struct timespec64 const *ts,
	}
}

static int idt82p33_xfer(struct idt82p33 *idt82p33,
static int idt82p33_xfer_read(struct idt82p33 *idt82p33,
			      unsigned char regaddr,
			      unsigned char *buf,
			 unsigned int count,
			 int write)
			      unsigned int count)
{
	struct i2c_client *client = idt82p33->client;
	struct i2c_msg msg[2];
@@ -94,7 +93,7 @@ static int idt82p33_xfer(struct idt82p33 *idt82p33,
	msg[0].buf = &regaddr;

	msg[1].addr = client->addr;
	msg[1].flags = write ? 0 : I2C_M_RD;
	msg[1].flags = I2C_M_RD;
	msg[1].len = count;
	msg[1].buf = buf;

@@ -110,6 +109,31 @@ static int idt82p33_xfer(struct idt82p33 *idt82p33,
	return 0;
}

static int idt82p33_xfer_write(struct idt82p33 *idt82p33,
			       u8 regaddr,
			       u8 *buf,
			       u16 count)
{
	struct i2c_client *client = idt82p33->client;
	/* we add 1 byte for device register */
	u8 msg[IDT82P33_MAX_WRITE_COUNT + 1];
	int err;

	if (count > IDT82P33_MAX_WRITE_COUNT)
		return -EINVAL;

	msg[0] = regaddr;
	memcpy(&msg[1], buf, count);

	err = i2c_master_send(client, msg, count + 1);
	if (err < 0) {
		dev_err(&client->dev, "i2c_master_send returned %d\n", err);
		return err;
	}

	return 0;
}

static int idt82p33_page_offset(struct idt82p33 *idt82p33, unsigned char val)
{
	int err;
@@ -117,7 +141,7 @@ static int idt82p33_page_offset(struct idt82p33 *idt82p33, unsigned char val)
	if (idt82p33->page_offset == val)
		return 0;

	err = idt82p33_xfer(idt82p33, PAGE_ADDR, &val, sizeof(val), 1);
	err = idt82p33_xfer_write(idt82p33, PAGE_ADDR, &val, sizeof(val));
	if (err)
		dev_err(&idt82p33->client->dev,
			"failed to set page offset %d\n", val);
@@ -138,11 +162,12 @@ static int idt82p33_rdwr(struct idt82p33 *idt82p33, unsigned int regaddr,

	err = idt82p33_page_offset(idt82p33, page);
	if (err)
		goto out;

	err = idt82p33_xfer(idt82p33, offset, buf, count, write);
out:
		return err;

	if (write)
		return idt82p33_xfer_write(idt82p33, offset, buf, count);

	return idt82p33_xfer_read(idt82p33, offset, buf, count);
}

static int idt82p33_read(struct idt82p33 *idt82p33, unsigned int regaddr,
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ enum hw_tod_trig_sel {
#define MAX_MEASURMENT_COUNT (5)
#define SNAP_THRESHOLD_NS (150000)
#define SYNC_TOD_TIMEOUT_SEC (5)
#define IDT82P33_MAX_WRITE_COUNT (512)

#define PLLMASK_ADDR_HI	0xFF
#define PLLMASK_ADDR_LO	0xA5