int stm_lpm_get_version(struct stm_lpm_version *driver_version, struct stm_lpm_version *fw_version) { int err = 0; struct stm_lpm_message response = {0}; struct stlpm_internal_send_msg send_msg; /* check paramters */ if ((driver_version == NULL) || (fw_version == NULL)) return -EINVAL; /*fill data into internal message*/ LPM_FILL_MSG(send_msg, STM_LPM_MSG_VER, NULL, MSG_ZERO_SIZE); /*fill transaction ID and reply type*/ LPM_FILL_ID_REPLY(send_msg, MSG_ID_AUTO, SBC_REPLY_YES); err = lpm_exchange_msg(&send_msg, &response); /* check we got no error from SBC and response is as expected */ if (err >= 0 && (response.command_id & STM_LPM_MSG_REPLY)) { /*Copy the received data to user space */ fw_version->major_comm_protocol = response.msg_data[0] >> 4; fw_version->minor_comm_protocol = response.msg_data[0] & 0x0F; fw_version->major_soft = response.msg_data[1] >> 4; fw_version->minor_soft = response.msg_data[1] & 0x0F; fw_version->patch_soft = response.msg_data[2] >> 4; fw_version->month = response.msg_data[2] & 0x0F; memcpy(&fw_version->day, &response.msg_data[3], 2); driver_version->major_comm_protocol = STM_LPM_MAJOR_PROTO_VER; driver_version->minor_comm_protocol = STM_LPM_MINOR_PROTO_VER; driver_version->major_soft = STM_LPM_MAJOR_SOFT_VER; driver_version->minor_soft = STM_LPM_MINOR_SOFT_VER; driver_version->patch_soft = STM_LPM_PATCH_SOFT_VER; driver_version->month = STM_LPM_BUILD_MONTH; driver_version->day = STM_LPM_BUILD_DAY; driver_version->year = STM_LPM_BUILD_YEAR; }
static int lpm_enter_passive_standby(void) { struct lpm_internal_send_msg send_msg = { .command_id = LPM_MSG_ENTER_PASSIVE, .msg_size = 0 }; return lpm_exchange_msg(&send_msg, NULL); } /** * lpm_fw_proto_version() - To get firmware major protocol version * * return major protocol version of firmware */ char lpm_fw_proto_version(void) { return lpm_drv->fw_major_ver; } /** * stm_lpm_probe() - Probe function of driver * @client_data: i2c client data * @id: 2c device id * * Return - 0 on success * Return - negative error on failure */ static int __init stm_lpm_probe(struct i2c_client *client_data, const struct i2c_device_id *id) { struct stm_lpm_i2c_data *i2c_data; int err = 0; struct stm_lpm_version driver_ver, fw_ver; lpm_debug("stm lpm probe \n"); /* Allocate data structure */ lpm_drv = kzalloc(sizeof(struct stm_lpm_driver_data), GFP_KERNEL); if (unlikely(lpm_drv == NULL)) { pr_err("%s: Request memory not done\n", __func__); return -ENOMEM; } i2c_data = i2c_get_clientdata(client_data); if (unlikely(i2c_data == NULL)) { pr_err("No i2c_bus data\n"); err = -ENOENT; goto exit; } lpm_drv->i2c_sbc_adapter = i2c_data->i2c_adap; if (lpm_drv->i2c_sbc_adapter == NULL) { pr_err("i2c adapter not found \n"); err = -ENODEV; goto exit; } lpm_debug("stm lpm i2c adapter found at %d i2c is %x \n", i2c_data->number_i2c, (unsigned int)lpm_drv->i2c_sbc_adapter); /* Mark parent */ client_data->dev.parent = &lpm_drv->i2c_sbc_adapter->dev; /* Mutex initialization */ mutex_init(&lpm_drv->msg_protection_mutex); err = stm_lpm_get_version(&driver_ver, &fw_ver); if (unlikely(err < 0)) { pr_err("No SBC firmware available \n"); goto exit; } lpm_drv->fw_major_ver = fw_ver.major_comm_protocol; #ifdef CONFIG_STM_LPM_RD_MONITOR /* Start monitor front panel power key */ err = lpm_start_power_monitor(client_data); #endif return err; exit: kfree(lpm_drv); return err; } /** * stm_lpm_remove() - To free used resources * @client: i2c client data * Return code 0 */ static int stm_lpm_remove(struct i2c_client *client) { lpm_debug("stm_lpm_remove \n"); #ifdef CONFIG_STM_LPM_RD_MONITOR lpm_stop_power_monitor(client); #endif kfree(lpm_drv); return 0; }