#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))
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)
{
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,