2 * This file is part of libsamsung-ipc.
4 * Copyright (C) 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/>.
26 #include <samsung-ipc.h>
30 #include "xmm6260_hsic.h"
31 #include "xmm6260_sec_modem.h"
32 #include "i9300_ipc.h"
34 int i9300_ipc_bootstrap(struct ipc_client *client)
36 void *modem_image_data = NULL;
37 int modem_image_fd = -1;
38 int modem_boot_fd = -1;
39 int modem_link_fd = -1;
47 ipc_client_log(client, "Starting i9300 modem bootstrap");
49 modem_image_fd = open(I9300_MODEM_IMAGE_DEVICE, O_RDONLY);
50 if (modem_image_fd < 0) {
51 ipc_client_log(client, "Opening modem image device failed");
54 ipc_client_log(client, "Opened modem image device");
56 modem_image_data = mmap(0, I9300_MODEM_IMAGE_SIZE, PROT_READ, MAP_SHARED, modem_image_fd, 0);
57 if (modem_image_data == NULL || modem_image_data == (void *) 0xffffffff) {
58 ipc_client_log(client, "Mapping modem image data to memory failed");
61 ipc_client_log(client, "Mapped modem image data to memory");
63 modem_boot_fd = open(XMM6260_SEC_MODEM_BOOT0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
64 if (modem_boot_fd < 0) {
65 ipc_client_log(client, "Opening modem boot device failed");
68 ipc_client_log(client, "Opened modem boot device");
70 modem_link_fd = open(XMM6260_SEC_MODEM_LINK_PM_DEVICE, O_RDWR);
71 if (modem_link_fd < 0) {
72 ipc_client_log(client, "Opening modem link device failed");
75 ipc_client_log(client, "Opened modem link device");
77 rc = xmm6260_sec_modem_hci_power(0);
79 ipc_client_log(client, "Turning the modem off failed");
82 ipc_client_log(client, "Turned the modem off");
84 rc = xmm6260_sec_modem_power(modem_boot_fd, 1);
85 rc |= xmm6260_sec_modem_hci_power(1);
88 ipc_client_log(client, "Turning the modem on failed");
91 ipc_client_log(client, "Turned the modem on");
93 rc = xmm6260_sec_modem_link_connected_wait(modem_link_fd);
95 ipc_client_log(client, "Waiting for link connected failed");
98 ipc_client_log(client, "Waited for link connected");
100 p = (unsigned char *) modem_image_data + I9300_PSI_OFFSET;
102 rc = xmm6260_hsic_psi_send(client, modem_boot_fd, (void *) p, I9300_PSI_SIZE);
104 ipc_client_log(client, "Sending XMM6260 HSIC PSI failed");
107 ipc_client_log(client, "Sent XMM6260 HSIC PSI");
109 p = (unsigned char *) modem_image_data + I9300_EBL_OFFSET;
111 rc = xmm6260_hsic_ebl_send(client, modem_boot_fd, (void *) p, I9300_EBL_SIZE);
113 ipc_client_log(client, "Sending XMM6260 HSIC EBL failed");
116 ipc_client_log(client, "Sent XMM6260 HSIC EBL");
118 rc = xmm6260_hsic_port_config_send(client, modem_boot_fd);
120 ipc_client_log(client, "Sending XMM6260 HSIC port config failed");
123 ipc_client_log(client, "Sent XMM6260 HSIC port config");
125 p = (unsigned char *) modem_image_data + I9300_SEC_START_OFFSET;
127 rc = xmm6260_hsic_sec_start_send(client, modem_boot_fd, (void *) p, I9300_SEC_START_SIZE);
129 ipc_client_log(client, "Sending XMM6260 HSIC SEC start failed");
132 ipc_client_log(client, "Sent XMM6260 HSIC SEC start");
134 p = (unsigned char *) modem_image_data + I9300_FIRMWARE_OFFSET;
136 rc = xmm6260_hsic_firmware_send(client, modem_boot_fd, (void *) p, I9300_FIRMWARE_SIZE);
138 ipc_client_log(client, "Sending XMM6260 HSIC firmware failed");
141 ipc_client_log(client, "Sent XMM6260 HSIC firmware");
143 rc = xmm6260_hsic_nv_data_send(client, modem_boot_fd);
145 ipc_client_log(client, "Sending XMM6260 HSIC nv_data failed");
148 ipc_client_log(client, "Sent XMM6260 HSIC nv_data");
150 rc = xmm6260_hsic_sec_end_send(client, modem_boot_fd);
152 ipc_client_log(client, "Sending XMM6260 HSIC SEC end failed");
155 ipc_client_log(client, "Sent XMM6260 HSIC SEC end");
157 rc = xmm6260_hsic_hw_reset_send(client, modem_boot_fd);
159 ipc_client_log(client, "Sending XMM6260 HSIC HW reset failed");
162 ipc_client_log(client, "Sent XMM6260 HSIC HW reset");
166 rc = xmm6260_sec_modem_link_get_hostwake_wait(modem_link_fd);
168 ipc_client_log(client, "Waiting for host wake failed");
171 rc = xmm6260_sec_modem_link_control_enable(modem_link_fd, 0);
172 rc |= xmm6260_sec_modem_hci_power(0);
173 rc |= xmm6260_sec_modem_link_control_active(modem_link_fd, 0);
176 ipc_client_log(client, "Turning the modem off failed");
180 rc = xmm6260_sec_modem_link_get_hostwake_wait(modem_link_fd);
182 ipc_client_log(client, "Waiting for host wake failed");
185 ipc_client_log(client, "Waited for host wake");
187 rc = xmm6260_sec_modem_link_control_enable(modem_link_fd, 1);
188 rc |= xmm6260_sec_modem_hci_power(1);
189 rc |= xmm6260_sec_modem_link_control_active(modem_link_fd, 1);
192 ipc_client_log(client, "Turning the modem on failed");
196 rc = xmm6260_sec_modem_link_connected_wait(modem_link_fd);
198 ipc_client_log(client, "Waiting for link connected failed");
201 ipc_client_log(client, "Waited for link connected");
212 if (modem_image_data != NULL)
213 munmap(modem_image_data, I9300_MODEM_IMAGE_SIZE);
215 if (modem_image_fd >= 0)
216 close(modem_image_fd);
218 if (modem_boot_fd >= 0)
219 close(modem_boot_fd);
221 if (modem_link_fd >= 0)
222 close(modem_link_fd);
228 int i9300_ipc_fmt_send(struct ipc_client *client, struct ipc_message_info *request)
230 return xmm6260_sec_modem_ipc_fmt_send(client, request);
233 int i9300_ipc_fmt_recv(struct ipc_client *client, struct ipc_message_info *response)
235 return xmm6260_sec_modem_ipc_fmt_recv(client, response);
238 int i9300_ipc_rfs_send(struct ipc_client *client, struct ipc_message_info *request)
240 return xmm6260_sec_modem_ipc_rfs_send(client, request);
243 int i9300_ipc_rfs_recv(struct ipc_client *client, struct ipc_message_info *response)
245 return xmm6260_sec_modem_ipc_rfs_recv(client, response);
248 int i9300_ipc_open(void *data, int type)
250 struct i9300_ipc_transport_data *transport_data;
255 transport_data = (struct i9300_ipc_transport_data *) data;
257 transport_data->fd = xmm6260_sec_modem_ipc_open(type);
258 if (transport_data->fd < 0)
264 int i9300_ipc_close(void *data)
266 struct i9300_ipc_transport_data *transport_data;
271 transport_data = (struct i9300_ipc_transport_data *) data;
273 xmm6260_sec_modem_ipc_close(transport_data->fd);
274 transport_data->fd = -1;
279 int i9300_ipc_read(void *data, void *buffer, unsigned int length)
281 struct i9300_ipc_transport_data *transport_data;
287 transport_data = (struct i9300_ipc_transport_data *) data;
289 rc = xmm6260_sec_modem_ipc_read(transport_data->fd, buffer, length);
293 int i9300_ipc_write(void *data, void *buffer, unsigned int length)
295 struct i9300_ipc_transport_data *transport_data;
301 transport_data = (struct i9300_ipc_transport_data *) data;
303 rc = xmm6260_sec_modem_ipc_write(transport_data->fd, buffer, length);
307 int i9300_ipc_poll(void *data, struct timeval *timeout)
309 struct i9300_ipc_transport_data *transport_data;
315 transport_data = (struct i9300_ipc_transport_data *) data;
317 rc = xmm6260_sec_modem_ipc_poll(transport_data->fd, timeout);
321 int i9300_ipc_power_on(void *data)
326 int i9300_ipc_power_off(void *data)
331 fd = open(XMM6260_SEC_MODEM_BOOT0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
335 rc = xmm6260_sec_modem_power(fd, 0);
345 int i9300_ipc_data_create(void **transport_data, void **power_data, void **gprs_data)
347 if (transport_data == NULL)
350 *transport_data = (void *) malloc(sizeof(struct i9300_ipc_transport_data));
351 memset(*transport_data, 0, sizeof(struct i9300_ipc_transport_data));
356 int i9300_ipc_data_destroy(void *transport_data, void *power_data, void *gprs_data)
358 if (transport_data == NULL)
361 free(transport_data);
366 char *i9300_ipc_gprs_get_iface(int cid)
368 return xmm6260_sec_modem_ipc_gprs_get_iface(cid);
372 int i9300_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities)
374 return xmm6260_sec_modem_ipc_gprs_get_capabilities(capabilities);
377 struct ipc_ops i9300_ipc_fmt_ops = {
378 .bootstrap = i9300_ipc_bootstrap,
379 .send = i9300_ipc_fmt_send,
380 .recv = i9300_ipc_fmt_recv,
383 struct ipc_ops i9300_ipc_rfs_ops = {
385 .send = i9300_ipc_rfs_send,
386 .recv = i9300_ipc_rfs_recv,
389 struct ipc_handlers i9300_ipc_handlers = {
390 .read = i9300_ipc_read,
391 .write = i9300_ipc_write,
392 .open = i9300_ipc_open,
393 .close = i9300_ipc_close,
394 .poll = i9300_ipc_poll,
395 .transport_data = NULL,
396 .power_on = i9300_ipc_power_on,
397 .power_off = i9300_ipc_power_off,
399 .gprs_activate = NULL,
400 .gprs_deactivate = NULL,
402 .data_create = i9300_ipc_data_create,
403 .data_destroy = i9300_ipc_data_destroy,
406 struct ipc_gprs_specs i9300_ipc_gprs_specs = {
407 .gprs_get_iface = i9300_ipc_gprs_get_iface,
408 .gprs_get_capabilities = i9300_ipc_gprs_get_capabilities,
411 // vim:ts=4:sw=4:expandtab