2 * This file is part of libsamsung-ipc.
4 * Copyright (C) 2011-2013 Paul Kocialkowski <contact@paulk.fr>
6 * libsamsung-ipc is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * libsamsung-ipc is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/select.h>
27 #include <samsung-ipc.h>
32 int xmm6160_psi_send(struct ipc_client *client, int serial_fd,
33 void *psi_data, unsigned short psi_size)
35 char at[] = XMM6160_AT;
36 unsigned char version;
38 unsigned char psi_magic;
39 unsigned char psi_crc;
40 unsigned char psi_ack;
42 struct termios termios;
43 struct timeval timeout;
51 if (client == NULL || serial_fd < 0 || psi_data == NULL || psi_size <= 0)
54 tcgetattr(serial_fd, &termios);
57 cfsetispeed(&termios, B115200);
58 cfsetospeed(&termios, B115200);
60 tcsetattr(serial_fd, TCSANOW, &termios);
63 for (i = 0; i < XMM6160_AT_COUNT; i++) {
64 rc = write(serial_fd, at, length);
66 ipc_client_log(client, "Writing AT in ASCII failed");
72 ipc_client_log(client, "Wrote AT in ASCII");
78 rc = read(serial_fd, &version, sizeof(version));
79 if (rc < (int) sizeof(version)) {
80 ipc_client_log(client, "Reading bootcore version failed");
84 if (version != XMM6160_BOOTCORE_VERSION) {
85 ipc_client_log(client, "Read wrong bootcore version (0x%x)", version);
89 ipc_client_log(client, "Read bootcore version (0x%x)", version);
91 rc = read(serial_fd, &info, sizeof(info));
92 if (rc < (int) sizeof(info)) {
93 ipc_client_log(client, "Reading info size failed");
96 ipc_client_log(client, "Read info size (0x%x)", info);
98 psi_magic = XMM6160_PSI_MAGIC;
100 rc = write(serial_fd, &psi_magic, sizeof(psi_magic));
101 if (rc < (int) sizeof(psi_magic)) {
102 ipc_client_log(client, "Writing PSI magic failed");
105 ipc_client_log(client, "Wrote PSI magic (0x%x)", psi_magic);
107 rc = write(serial_fd, &psi_size, sizeof(psi_size));
108 if (rc < (int) sizeof(psi_size)) {
109 ipc_client_log(client, "Writing PSI size failed");
112 ipc_client_log(client, "Wrote PSI size (0x%x)", psi_size);
115 FD_SET(serial_fd, &fds);
120 p = (unsigned char *) psi_data;
123 for (i = 0; i < psi_size; i++) {
124 rc = select(serial_fd + 1, NULL, &fds, NULL, &timeout);
126 ipc_client_log(client, "Writing PSI failed");
130 rc = write(serial_fd, p, 1);
132 ipc_client_log(client, "Writing PSI failed");
138 ipc_client_log(client, "Wrote PSI, CRC is 0x%x", psi_crc);
140 rc = select(serial_fd + 1, NULL, &fds, NULL, &timeout);
142 ipc_client_log(client, "Writing PSI crc failed");
146 rc = write(serial_fd, &psi_crc, sizeof(psi_crc));
147 if (rc < (int) sizeof(psi_crc)) {
148 ipc_client_log(client, "Writing PSI crc failed");
151 ipc_client_log(client, "Wrote PSI CRC (0x%x)", psi_crc);
158 rc = select(serial_fd + 1, &fds, NULL, NULL, &timeout);
160 ipc_client_log(client, "Reading PSI ACK failed");
164 rc = read(serial_fd, &psi_ack, sizeof(psi_ack));
165 if (rc < (int) sizeof(psi_ack)) {
166 ipc_client_log(client, "Reading PSI ACK failed");
171 ipc_client_log(client, "Reading PSI ACK failed");
174 } while (psi_ack != XMM6160_PSI_ACK);
175 ipc_client_log(client, "Read PSI ACK (0x%x)", psi_ack);
187 int xmm6160_firmware_send(struct ipc_client *client, int device_fd,
188 void *device_address, void *firmware_data, int firmware_size)
196 if (client == NULL || (device_fd < 0 && device_address == NULL) || firmware_data == NULL || firmware_size <= 0)
199 p = (unsigned char *) firmware_data;
201 if (device_address != NULL) {
202 memcpy(device_address, (void *) p, firmware_size);
205 while (wc < firmware_size) {
206 rc = write(device_fd, (void *) p, firmware_size - wc);
208 ipc_client_log(client, "Writing firmware failed");
216 ipc_client_log(client, "Wrote firmware");
228 int xmm6160_nv_data_send(struct ipc_client *client, int device_fd,
229 void *device_address)
231 void *nv_data = NULL;
238 if (client == NULL || (device_fd < 0 && device_address == NULL))
241 nv_size = ipc_client_nv_data_size(client);
243 nv_data = ipc_nv_data_load(client);
244 if (nv_data == NULL) {
245 ipc_client_log(client, "Loading nv_data failed");
248 ipc_client_log(client, "Loaded nv_data");
250 p = (unsigned char *) nv_data;
252 if (device_address != NULL) {
253 memcpy(device_address, p, nv_size);
256 while (wc < nv_size) {
257 rc = write(device_fd, p, nv_size - wc);
259 ipc_client_log(client, "Writing modem image failed");
281 // vim:ts=4:sw=4:expandtab