* System Control and Power Interface (SCPI) Message Protocol driver
*
* Copyright (C) 2014 ARM Ltd.
- * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/mailbox_client.h>
-#include <linux/scpi_protocol.h>
#include <linux/slab.h>
-#include <linux/rockchip-mailbox.h>
-#include <linux/rockchip/common.h>
+#include <soc/rockchip/scpi.h>
+#include <soc/rockchip/rk3368-mailbox.h>
-#include "scpi_cmd.h"
+#define SCPI_VERSION 0x01000002 /* version: 1.0.0.2 */
#define CMD_ID_SHIFT 0
#define CMD_ID_MASK 0xff
((((cmd) & CMD_ID_MASK) << CMD_ID_SHIFT) | \
(((sender) & CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) | \
(((txsz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
+#define SCPI_CMD_DEFAULT_TIMEOUT_MS 1000
#define MAX_DVFS_DOMAINS 3
#define MAX_DVFS_OPPS 8
#define DVFS_LATENCY(hdr) ((hdr) >> 16)
#define DVFS_OPP_COUNT(hdr) (((hdr) >> 8) & 0xff)
-struct scpi_data_buf {
- int client_id;
- struct rockchip_mbox_msg *data;
- struct completion complete;
+static int max_chan_num = 0;
+static DECLARE_BITMAP(bm_mbox_chans, 4);
+static DEFINE_MUTEX(scpi_mtx);
+
+enum scpi_error_codes {
+ SCPI_SUCCESS = 0, /* Success */
+ SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
+ SCPI_ERR_ALIGN = 2, /* Invalid alignment */
+ SCPI_ERR_SIZE = 3, /* Invalid size */
+ SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
+ SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
+ SCPI_ERR_RANGE = 6, /* Value out of range */
+ SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
+ SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
+ SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
+ SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
+ SCPI_ERR_DEVICE = 11, /* Device error */
+ SCPI_ERR_MAX
+};
+
+enum scpi_client_id {
+ SCPI_CL_NONE,
+ SCPI_CL_CLOCKS,
+ SCPI_CL_DVFS,
+ SCPI_CL_POWER,
+ SCPI_CL_THERMAL,
+ SCPI_CL_DDR,
+ SCPI_CL_SYS,
+ SCPI_MAX,
+};
+
+enum scpi_ddr_cmd {
+ SCPI_DDR_INIT,
+ SCPI_DDR_SET_FREQ,
+ SCPI_DDR_ROUND_RATE,
+ SCPI_DDR_AUTO_SELF_REFRESH,
+ SCPI_DDR_BANDWIDTH_GET,
+ SCPI_DDR_GET_FREQ,
+ SCPI_DDR_SEND_TIMING,
+ SCPI_DDR_DCLK_MODE,
+};
+
+enum scpi_sys_cmd {
+ SCPI_SYS_GET_VERSION,
+ SCPI_SYS_REFRESH_MCU_FREQ,
+ SCPI_SYS_SET_MCU_STATE_SUSPEND,
+ SCPI_SYS_SET_MCU_STATE_RESUME,
+ SCPI_SYS_SET_JTAGMUX_ON_OFF,
+};
+
+enum scpi_std_cmd {
+ SCPI_CMD_INVALID = 0x00,
+ SCPI_CMD_SCPI_READY = 0x01,
+ SCPI_CMD_SCPI_CAPABILITIES = 0x02,
+ SCPI_CMD_EVENT = 0x03,
+ SCPI_CMD_SET_CSS_PWR_STATE = 0x04,
+ SCPI_CMD_GET_CSS_PWR_STATE = 0x05,
+ SCPI_CMD_CFG_PWR_STATE_STAT = 0x06,
+ SCPI_CMD_GET_PWR_STATE_STAT = 0x07,
+ SCPI_CMD_SYS_PWR_STATE = 0x08,
+ SCPI_CMD_L2_READY = 0x09,
+ SCPI_CMD_SET_AP_TIMER = 0x0a,
+ SCPI_CMD_CANCEL_AP_TIME = 0x0b,
+ SCPI_CMD_DVFS_CAPABILITIES = 0x0c,
+ SCPI_CMD_GET_DVFS_INFO = 0x0d,
+ SCPI_CMD_SET_DVFS = 0x0e,
+ SCPI_CMD_GET_DVFS = 0x0f,
+ SCPI_CMD_GET_DVFS_STAT = 0x10,
+ SCPI_CMD_SET_RTC = 0x11,
+ SCPI_CMD_GET_RTC = 0x12,
+ SCPI_CMD_CLOCK_CAPABILITIES = 0x13,
+ SCPI_CMD_SET_CLOCK_INDEX = 0x14,
+ SCPI_CMD_SET_CLOCK_VALUE = 0x15,
+ SCPI_CMD_GET_CLOCK_VALUE = 0x16,
+ SCPI_CMD_PSU_CAPABILITIES = 0x17,
+ SCPI_CMD_SET_PSU = 0x18,
+ SCPI_CMD_GET_PSU = 0x19,
+ SCPI_CMD_SENSOR_CAPABILITIES = 0x1a,
+ SCPI_CMD_SENSOR_INFO = 0x1b,
+ SCPI_CMD_SENSOR_VALUE = 0x1c,
+ SCPI_CMD_SENSOR_CFG_PERIODIC = 0x1d,
+ SCPI_CMD_SENSOR_CFG_BOUNDS = 0x1e,
+ SCPI_CMD_SENSOR_ASYNC_VALUE = 0x1f,
+ SCPI_CMD_COUNT
+};
+
+enum scpi_thermal_cmd {
+ SCPI_THERMAL_GET_TSADC_DATA,
+ SCPI_THERMAL_SET_TSADC_CYCLE,
+ SCPI_THERMAL_COUNT
};
static int high_priority_cmds[] = {
SCPI_CMD_SENSOR_CFG_BOUNDS,
};
+struct scpi_data_buf {
+ int client_id;
+ struct rk3368_mbox_msg *data;
+ struct completion complete;
+ int timeout_ms;
+};
+
+struct scpi_mcu_ver {
+ u32 scpi_ver;
+ char mcu_ver[16];
+};
+
static struct scpi_opp *scpi_opps[MAX_DVFS_DOMAINS];
static struct device *the_scpi_device;
return -EIO;
}
-static bool high_priority_chan_supported(int cmd)
+static bool __maybe_unused high_priority_chan_supported(int cmd)
{
int idx;
return false;
}
+static int scpi_alloc_mbox_chan(void)
+{
+ int index;
+
+ mutex_lock(&scpi_mtx);
+
+ index = find_first_zero_bit(bm_mbox_chans, max_chan_num);
+ if (index >= max_chan_num) {
+ pr_err("alloc mailbox channel failed\n");
+ mutex_unlock(&scpi_mtx);
+ return -EBUSY;
+ }
+
+ set_bit(index, bm_mbox_chans);
+
+ mutex_unlock(&scpi_mtx);
+ return index;
+}
+
+static void scpi_free_mbox_chan(int chan)
+{
+ int index = chan;
+
+ mutex_lock(&scpi_mtx);
+
+ if (index < max_chan_num && index >= 0)
+ clear_bit(index, bm_mbox_chans);
+
+ mutex_unlock(&scpi_mtx);
+}
+
static void scpi_rx_callback(struct mbox_client *cl, void *msg)
{
- struct rockchip_mbox_msg *data = (struct rockchip_mbox_msg *)msg;
+ struct rk3368_mbox_msg *data = (struct rk3368_mbox_msg *)msg;
struct scpi_data_buf *scpi_buf = data->cl_data;
complete(&scpi_buf->complete);
}
-static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, bool high_priority)
+static int send_scpi_cmd(struct scpi_data_buf *scpi_buf, int index)
{
struct mbox_chan *chan;
struct mbox_client cl;
- struct rockchip_mbox_msg *data = scpi_buf->data;
+ struct rk3368_mbox_msg *data = scpi_buf->data;
u32 status;
int ret;
+ int timeout = msecs_to_jiffies(scpi_buf->timeout_ms);
if (!the_scpi_device) {
pr_err("Scpi initializes unsuccessfully\n");
cl.dev = the_scpi_device;
cl.rx_callback = scpi_rx_callback;
cl.tx_done = NULL;
+ cl.tx_prepare = NULL;
cl.tx_block = false;
cl.knows_txdone = false;
- chan = mbox_request_channel(&cl, high_priority);
- if (IS_ERR(chan))
+ chan = mbox_request_channel(&cl, index);
+ if (IS_ERR(chan)) {
+ scpi_free_mbox_chan(index);
return PTR_ERR(chan);
+ }
init_completion(&scpi_buf->complete);
if (mbox_send_message(chan, (void *)data) < 0) {
goto free_channel;
}
- ret = wait_for_completion_timeout(&scpi_buf->complete,
- msecs_to_jiffies(1000));
+ ret = wait_for_completion_timeout(&scpi_buf->complete, timeout);
if (ret == 0) {
status = SCPI_ERR_TIMEOUT;
goto free_channel;
free_channel:
mbox_free_channel(chan);
+ scpi_free_mbox_chan(index);
return scpi_to_linux_errno(status);
}
#define SCPI_SETUP_DBUF(scpi_buf, mbox_buf, _client_id,\
_cmd, _tx_buf, _rx_buf) \
do { \
- struct rockchip_mbox_msg *pdata = &mbox_buf; \
+ struct rk3368_mbox_msg *pdata = &mbox_buf; \
pdata->cmd = _cmd; \
pdata->tx_buf = &_tx_buf; \
pdata->tx_size = sizeof(_tx_buf); \
pdata->rx_size = sizeof(_rx_buf); \
scpi_buf.client_id = _client_id; \
scpi_buf.data = pdata; \
+ scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
+} while (0)
+
+#define SCPI_SETUP_DBUF_BY_SIZE(scpi_buf, mbox_buf, _client_id, \
+ _cmd, _tx_buf, _tx_size, _rx_buf) \
+do { \
+ struct rk3368_mbox_msg *pdata = &mbox_buf; \
+ pdata->cmd = _cmd; \
+ pdata->tx_buf = _tx_buf; \
+ pdata->tx_size = _tx_size; \
+ pdata->rx_buf = &_rx_buf; \
+ pdata->rx_size = sizeof(_rx_buf); \
+ scpi_buf.client_id = _client_id; \
+ scpi_buf.data = pdata; \
+ scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \
} while (0)
static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf)
{
- struct rockchip_mbox_msg *data;
- bool high_priority;
+ struct rk3368_mbox_msg *data;
+ int index;
if (!scpi_buf || !scpi_buf->data)
return -EINVAL;
+ index = scpi_alloc_mbox_chan();
+ if (index < 0)
+ return -EBUSY;
+
data = scpi_buf->data;
- high_priority = high_priority_chan_supported(data->cmd);
data->cmd = PACK_SCPI_CMD(data->cmd, scpi_buf->client_id,
data->tx_size);
data->cl_data = scpi_buf;
- return send_scpi_cmd(scpi_buf, high_priority);
+ return send_scpi_cmd(scpi_buf, index);
}
unsigned long scpi_clk_get_val(u16 clk_id)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed {
u32 status;
u32 clk_rate;
int scpi_clk_set_val(u16 clk_id, unsigned long rate)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
int stat;
struct __packed {
u32 clk_rate;
struct scpi_opp *scpi_dvfs_get_opps(u8 domain)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed {
u32 status;
u32 header;
int scpi_dvfs_get_idx(u8 domain)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed {
u32 status;
u8 dvfs_idx;
int scpi_dvfs_set_idx(u8 domain, u8 idx)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed {
u8 dvfs_domain;
u8 dvfs_idx;
int scpi_get_sensor(char *name)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed {
u32 status;
u16 sensors;
/* This should be handled by a generic macro */
do {
- struct rockchip_mbox_msg *pdata = &mdata;
+ struct rk3368_mbox_msg *pdata = &mdata;
pdata->cmd = SCPI_CMD_SENSOR_CAPABILITIES;
pdata->tx_size = 0;
int scpi_get_sensor_value(u16 sensor, u32 *val)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed {
u32 status;
u32 val;
}
EXPORT_SYMBOL_GPL(scpi_get_sensor_value);
-static int scpi_get_version(u32 old, u32 *ver)
+static int scpi_get_version(u32 old, struct scpi_mcu_ver *ver)
{
+ int ret;
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed {
u32 status;
- u32 ver;
+ struct scpi_mcu_ver version;
} buf;
- int ret;
+ memset(&buf, 0, sizeof(buf));
SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS, SCPI_SYS_GET_VERSION,
old, buf);
+ ret = scpi_execute_cmd(&sdata);
+ if (ret) {
+ pr_err("get scpi version from MCU failed, ret=%d\n", ret);
+ goto OUT;
+ }
+
+ memcpy(ver, &(buf.version), sizeof(*ver));
+
+OUT:
+ return ret;
+}
+
+int scpi_sys_set_mcu_state_suspend(void)
+{
+ struct scpi_data_buf sdata;
+ struct rk3368_mbox_msg mdata;
+ struct __packed1 {
+ u32 status;
+ } tx_buf;
+ struct __packed2 {
+ u32 status;
+ } rx_buf;
+
+ tx_buf.status = 0;
+ SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
+ SCPI_SYS_SET_MCU_STATE_SUSPEND, tx_buf, rx_buf);
+ return scpi_execute_cmd(&sdata);
+}
+EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
+
+int scpi_sys_set_mcu_state_resume(void)
+{
+ struct scpi_data_buf sdata;
+ struct rk3368_mbox_msg mdata;
+ struct __packed1 {
+ u32 status;
+ } tx_buf;
+ struct __packed2 {
+ u32 status;
+ } rx_buf;
+
+ tx_buf.status = 0;
+
+ SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
+ SCPI_SYS_SET_MCU_STATE_RESUME, tx_buf, rx_buf);
+ return scpi_execute_cmd(&sdata);
+}
+EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
+
+int scpi_sys_set_jtagmux_on_off(u32 en)
+{
+ int ret;
+ struct scpi_data_buf sdata;
+ struct rk3368_mbox_msg mdata;
+ struct __packed1 {
+ u32 enable;
+ } tx_buf;
+
+ struct __packed2 {
+ u32 status;
+ } rx_buf;
+
+ tx_buf.enable = en;
+ SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
+ SCPI_SYS_SET_JTAGMUX_ON_OFF, tx_buf, rx_buf);
+
ret = scpi_execute_cmd(&sdata);
if (ret)
- *ver = buf.ver;
+ pr_err("set jtagmux on-off failed, ret=%d\n", ret);
+ else
+ ret = rx_buf.status;
return ret;
}
+EXPORT_SYMBOL_GPL(scpi_sys_set_jtagmux_on_off);
+
+int scpi_ddr_dclk_mode(u32 dclk_mode)
+{
+ struct scpi_data_buf sdata;
+ struct rk3368_mbox_msg mdata;
+ struct __packed1 {
+ u32 dclk_mode;
+ } tx_buf;
+ struct __packed2 {
+ u32 status;
+ } rx_buf;
+
+ tx_buf.dclk_mode = (u32)dclk_mode;
+ SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
+ SCPI_DDR_DCLK_MODE, tx_buf, rx_buf);
+ return scpi_execute_cmd(&sdata);
+}
+EXPORT_SYMBOL_GPL(scpi_ddr_dclk_mode);
-int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type)
+int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed1 {
u32 dram_speed_bin;
u32 freq;
u32 lcdc_type;
+ u32 addr_mcu_el3;
} tx_buf;
struct __packed2 {
u32 status;
tx_buf.dram_speed_bin = (u32)dram_speed_bin;
tx_buf.freq = (u32)freq;
tx_buf.lcdc_type = (u32)lcdc_type;
-
+ tx_buf.addr_mcu_el3 = addr_mcu_el3;
SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
SCPI_DDR_INIT, tx_buf, rx_buf);
return scpi_execute_cmd(&sdata);
}
EXPORT_SYMBOL_GPL(scpi_ddr_init);
-int scpi_ddr_set_clk_rate(u32 rate)
+int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type)
{
+ int ret;
+
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed1 {
u32 clk_rate;
+ u32 lcdc_type;
} tx_buf;
struct __packed2 {
u32 status;
+ u32 freq;
} rx_buf;
tx_buf.clk_rate = (u32)rate;
-
+ tx_buf.lcdc_type = (u32)lcdc_type;
SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
SCPI_DDR_SET_FREQ, tx_buf, rx_buf);
- return scpi_execute_cmd(&sdata);
+ ret = scpi_execute_cmd(&sdata);
+
+ if ((!ret) && (!rx_buf.status))
+ ret = rx_buf.freq;
+ else
+ ret = 0;
+
+ return ret;
}
EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate);
+int scpi_ddr_send_timing(u32 *p, u32 size)
+{
+ struct scpi_data_buf sdata;
+ struct rk3368_mbox_msg mdata;
+ struct __packed2 {
+ u32 status;
+ } rx_buf;
+ SCPI_SETUP_DBUF_BY_SIZE(sdata, mdata, SCPI_CL_DDR,
+ SCPI_DDR_SEND_TIMING, p, size, rx_buf);
+ return scpi_execute_cmd(&sdata);
+}
+EXPORT_SYMBOL_GPL(scpi_ddr_send_timing);
+
int scpi_ddr_round_rate(u32 m_hz)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed1 {
u32 clk_rate;
} tx_buf;
int scpi_ddr_set_auto_self_refresh(u32 en)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed1 {
u32 enable;
} tx_buf;
struct ddr_bw_info *ddr_bw_ch1)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed1 {
u32 status;
} tx_buf;
int scpi_ddr_get_clk_rate(void)
{
struct scpi_data_buf sdata;
- struct rockchip_mbox_msg mdata;
+ struct rk3368_mbox_msg mdata;
struct __packed1 {
u32 status;
} tx_buf;
}
EXPORT_SYMBOL_GPL(scpi_ddr_get_clk_rate);
+int scpi_thermal_get_temperature(void)
+{
+ int ret;
+ struct scpi_data_buf sdata;
+ struct rk3368_mbox_msg mdata;
+ struct __packed1 {
+ u32 status;
+ } tx_buf;
+
+ struct __packed2 {
+ u32 status;
+ u32 tsadc_data;
+ } rx_buf;
+
+ tx_buf.status = 0;
+ SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
+ SCPI_THERMAL_GET_TSADC_DATA, tx_buf, rx_buf);
+
+ ret = scpi_execute_cmd(&sdata);
+ if (ret) {
+ pr_err("get temperature from MCU failed, ret=%d\n", ret);
+ return ret;
+ }
+
+ return rx_buf.tsadc_data;
+}
+EXPORT_SYMBOL_GPL(scpi_thermal_get_temperature);
+
+int scpi_thermal_set_clk_cycle(u32 cycle)
+{
+ struct scpi_data_buf sdata;
+ struct rk3368_mbox_msg mdata;
+ struct __packed1 {
+ u32 clk_cycle;
+ } tx_buf;
+
+ struct __packed2 {
+ u32 status;
+ } rx_buf;
+
+ tx_buf.clk_cycle = cycle;
+ SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_THERMAL,
+ SCPI_THERMAL_SET_TSADC_CYCLE, tx_buf, rx_buf);
+
+ return scpi_execute_cmd(&sdata);
+}
+EXPORT_SYMBOL_GPL(scpi_thermal_set_clk_cycle);
+
static struct of_device_id mobx_scpi_of_match[] = {
- { .compatible = "rockchip,mbox-scpi"},
+ { .compatible = "rockchip,rk3368-scpi-legacy"},
{ },
};
MODULE_DEVICE_TABLE(of, mobx_scpi_of_match);
{
int ret = 0;
int retry = 3;
- u32 ver = 0;
- int check_version = 0; /*0: not check version, 1: check version*/
+ int val = 0;
+ struct scpi_mcu_ver mcu_ver;
+ int check_version = 1; /*0: not check version, 1: check version*/
the_scpi_device = &pdev->dev;
+ /* try to get mboxes chan nums from DT */
+ if (of_property_read_u32((&pdev->dev)->of_node, "chan-nums", &val)) {
+ dev_err(&pdev->dev, "parse mboxes chan-nums failed\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ max_chan_num = val;
+
+ /* try to check up with SCPI version from MCU */
while ((retry--) && (check_version != 0)) {
- ret = scpi_get_version(SCPI_VERSION, &ver);
- if ((ret == 0) && (ver == SCPI_VERSION))
+ memset(&mcu_ver, 0, sizeof(mcu_ver));
+
+ ret = scpi_get_version(SCPI_VERSION, &mcu_ver);
+ if ((ret == 0) && (mcu_ver.scpi_ver == SCPI_VERSION))
break;
}
if ((retry <= 0) && (check_version != 0)) {
- dev_err(&pdev->dev, "Failed to get scpi version\n");
+ dev_err(&pdev->dev,
+ "Scpi verison not match:kernel ver:0x%x, MCU ver:0x%x, ret=%d\n",
+ SCPI_VERSION, mcu_ver.scpi_ver, ret);
ret = -EIO;
goto exit;
}
- dev_info(&pdev->dev,
- "Scpi initialize, version: 0x%x\n", ver);
+ dev_info(&pdev->dev, "Scpi initialize, version: 0x%x, chan nums: %d\n",
+ SCPI_VERSION, val);
+
+ if (check_version)
+ dev_info(&pdev->dev, "MCU version: %s\n", mcu_ver.mcu_ver);
+
return 0;
exit:
the_scpi_device = NULL;