Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d438e20 authored by Ajay Gupta's avatar Ajay Gupta Committed by Greg Kroah-Hartman
Browse files

usb: typec: ucsi: ccg: add get_fw_info function



Function is to get the details of ccg firmware and device version.
It will be useful in debugging and also during firmware update.

Signed-off-by: default avatarAjay Gupta <ajayg@nvidia.com>
Signed-off-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6e3c8beb
Loading
Loading
Loading
Loading
+64 −2
Original line number Diff line number Diff line
@@ -17,15 +17,54 @@
#include <asm/unaligned.h>
#include "ucsi.h"

enum enum_fw_mode {
	BOOT,   /* bootloader */
	FW1,    /* FW partition-1 (contains secondary fw) */
	FW2,    /* FW partition-2 (contains primary fw) */
	FW_INVALID,
};

struct ccg_dev_info {
#define CCG_DEVINFO_FWMODE_SHIFT (0)
#define CCG_DEVINFO_FWMODE_MASK (0x3 << CCG_DEVINFO_FWMODE_SHIFT)
#define CCG_DEVINFO_PDPORTS_SHIFT (2)
#define CCG_DEVINFO_PDPORTS_MASK (0x3 << CCG_DEVINFO_PDPORTS_SHIFT)
	u8 mode;
	u8 bl_mode;
	__le16 silicon_id;
	__le16 bl_last_row;
} __packed;

struct version_format {
	__le16 build;
	u8 patch;
	u8 ver;
#define CCG_VERSION_MIN_SHIFT (0)
#define CCG_VERSION_MIN_MASK (0xf << CCG_VERSION_MIN_SHIFT)
#define CCG_VERSION_MAJ_SHIFT (4)
#define CCG_VERSION_MAJ_MASK (0xf << CCG_VERSION_MAJ_SHIFT)
} __packed;

struct version_info {
	struct version_format base;
	struct version_format app;
};

struct ucsi_ccg {
	struct device *dev;
	struct ucsi *ucsi;
	struct ucsi_ppm ppm;
	struct i2c_client *client;
	struct ccg_dev_info info;
	/* version info for boot, primary and secondary */
	struct version_info version[FW2 + 1];
};

#define CCGX_RAB_INTR_REG			0x06
#define CCGX_RAB_UCSI_CONTROL			0x39
#define CCGX_RAB_DEVICE_MODE			0x0000
#define CCGX_RAB_INTR_REG			0x0006
#define CCGX_RAB_READ_ALL_VER			0x0010
#define CCGX_RAB_READ_FW2_VER			0x0020
#define CCGX_RAB_UCSI_CONTROL			0x0039
#define CCGX_RAB_UCSI_CONTROL_START		BIT(0)
#define CCGX_RAB_UCSI_CONTROL_STOP		BIT(1)
#define CCGX_RAB_UCSI_DATA_BLOCK(offset)	(0xf000 | ((offset) & 0xff))
@@ -220,6 +259,23 @@ static irqreturn_t ccg_irq_handler(int irq, void *data)
	return IRQ_HANDLED;
}

static int get_fw_info(struct ucsi_ccg *uc)
{
	int err;

	err = ccg_read(uc, CCGX_RAB_READ_ALL_VER, (u8 *)(&uc->version),
		       sizeof(uc->version));
	if (err < 0)
		return err;

	err = ccg_read(uc, CCGX_RAB_DEVICE_MODE, (u8 *)(&uc->info),
		       sizeof(uc->info));
	if (err < 0)
		return err;

	return 0;
}

static int ucsi_ccg_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
@@ -248,6 +304,12 @@ static int ucsi_ccg_probe(struct i2c_client *client,
		return status;
	}

	status = get_fw_info(uc);
	if (status < 0) {
		dev_err(uc->dev, "get_fw_info failed - %d\n", status);
		return status;
	}

	status = devm_request_threaded_irq(dev, client->irq, NULL,
					   ccg_irq_handler,
					   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,