diff options
Diffstat (limited to 'samsung-ipc/modems/xmm626/os_partitions.c')
-rw-r--r-- | samsung-ipc/modems/xmm626/os_partitions.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/samsung-ipc/modems/xmm626/os_partitions.c b/samsung-ipc/modems/xmm626/os_partitions.c new file mode 100644 index 0000000..04aa1a4 --- /dev/null +++ b/samsung-ipc/modems/xmm626/os_partitions.c @@ -0,0 +1,126 @@ +/* + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2012 Alexander Tarasikov <alexander.tarasikov@gmail.com> + * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr> + * + * Based on the incomplete C++ implementation which is: + * Copyright (C) 2012 Sergey Gridasov <grindars@gmail.com> + * + * libsamsung-ipc is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libsamsung-ipc is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> + +#include "ipc.h" +#include "modems/modem.h" +#include "modems/xmm626/os_partitions.h" +#include "modems/xmm626/xmm626.h" + +int xmm626_load_os_subpartition(struct ipc_client *client, + enum ipc_client_modem_os_partition type, int fd, + void *data, size_t data_size) +{ + int rc; + + switch (partition->type) { + case MODEM_OS_PARTITION_PSIRAM: + // TODO: MIPI/HSIC + return xmm626_psi_send(client, fd, + data, + data_size); + case MODEM_OS_PARTITION_EBL: + // TODO: MIPI/HSIC + return xmm626_hsic_ebl_send(client, fd, data, data_size); + + case MODEM_OS_PARTITION_MAIN: + rc = xmm626_send_main_partition(client, device_fd, data, + data_size); + case MODEM_OS_PARTITION_SECPACK: + /* TODO */ + break; + case MODEM_OS_PARTITION_NV: + rc = xmm626_nv_data_send(client, device_fd); + } + + if (rc < 0) + ipc_client_log( + client, + "Loading %s partition into the XMM626 modem failed", + modem_os_subpartition(type)); + else + ipc_client_log( + client, + "Loading %s partition into the XMM626 modem failed", + modem_os_subpartition(type)); + + return rc; +} + + +int xmm626_send_main_partition(struct ipc_client *client, int device_fd, + const void *firmware_data, size_t firmware_size) +{ + int rc; + + if (client == NULL || device_fd < 0 || firmware_data == NULL || + firmware_size == 0) { + return -1; + } + + rc = modem_data_send(client, device_fd, firmware_data, firmware_size, + XMM626_FIRMWARE_ADDRESS); + if (rc < 0) + return -1; + + return 0; +} + +int xmm626_nv_data_send(struct ipc_client *client, int device_fd) +{ + void *nv_data = NULL; + size_t nv_size; + int rc; + + if (client == NULL || device_fd < 0) + return -1; + + nv_size = ipc_client_nv_data_size(client); + if (nv_size == 0) + return -1; + + nv_data = ipc_nv_data_load(client); + if (nv_data == NULL) { + ipc_client_log(client, "Loading nv_data failed"); + goto error; + } + ipc_client_log(client, "Loaded nv_data"); + + rc = modem_data_send(client, device_fd, nv_data, nv_size, + XMM626_NV_DATA_ADDRESS); + if (rc < 0) + goto error; + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (nv_data != NULL) + free(nv_data); + + return rc; +} |