diff options
author | Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> | 2020-02-21 05:24:36 +0100 |
---|---|---|
committer | Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> | 2020-07-16 16:48:44 +0200 |
commit | cf8ea3d14f425112990dcb94d0878fab9c767aa3 (patch) | |
tree | 29e45d1d9ecc836bfe23d54422e1c7b4406a0c61 | |
parent | d0c4082f93f857efa8e937f8bec9c4257f0ee784 (diff) | |
download | hardware_replicant_libsamsung-ipc-cf8ea3d14f425112990dcb94d0878fab9c767aa3.tar.gz hardware_replicant_libsamsung-ipc-cf8ea3d14f425112990dcb94d0878fab9c767aa3.tar.bz2 hardware_replicant_libsamsung-ipc-cf8ea3d14f425112990dcb94d0878fab9c767aa3.zip |
Add a modem abstraction
Some xmm626_kernel_smdk4412 functions are present for all devices:
- open|close|read|write|poll
- fmt/rfs
- gprs
- power
Thses are not
+----------+
| galaxys2 | | hci_power | link_control_enable | link_control_active | link_connected_wait | link_get_hostwake_wait | |
| i9300 | | hci_power | link_control_enable | link_control_active | link_connected_wait | link_get_hostwake_wait | |
| maguro | boot_power | | | | | | status_online_wait |
| n5100 | | hci_power | link_control_enable | link_control_active | link_connected_wait | link_get_hostwake_wait | |
| n7100 | | hci_power | link_control_enable | link_control_active | link_connected_wait | link_get_hostwake_wait | |
| piranha | | | | | | | |
+----------+
TODO:
- don't add the python script to this commit or clean it up
- cleanup style
- Verify if we need to convert all boards in this commit
- Look if i9300 changes should go in this commit
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
22 files changed, 1168 insertions, 132 deletions
@@ -52,6 +52,7 @@ endif libsamsung_ipc_local_src_files := \ samsung-ipc/ipc.c \ samsung-ipc/ipc_utils.c \ + samsung-ipc/modems/modem.c \ samsung-ipc/modems/xmm616/xmm616.c \ samsung-ipc/modems/xmm626/xmm626.c \ samsung-ipc/modems/xmm626/xmm626_hsic.c \ diff --git a/samsung-ipc/Makefile.am b/samsung-ipc/Makefile.am index f71e396..8c8e5bd 100644 --- a/samsung-ipc/Makefile.am +++ b/samsung-ipc/Makefile.am @@ -18,19 +18,22 @@ libsamsung_ipc_la_SOURCES = \ ipc.c \ ipc.h \ ipc_utils.c \ + modems/modem.c \ + modems/modem.h \ modems/xmm616/xmm616.c \ modems/xmm616/xmm616.h \ modems/xmm626/xmm626.c \ modems/xmm626/xmm626.h \ - modems/xmm626/xmm626_hsic.c \ - modems/xmm626/xmm626_hsic.h \ - modems/xmm626/xmm626_kernel_smdk4412.c \ - modems/xmm626/xmm626_kernel_smdk4412.h \ - modems/xmm626/xmm626_mipi.c \ - modems/xmm626/xmm626_mipi.h \ + modems/xmm626/firmware.c \ + modems/xmm626/kernel_smdk4412.c \ modems/xmm626/xmm626_modem.h \ modems/xmm626/xmm626_modem_link_device_hsic.h \ modems/xmm626/xmm626_modem_prj.h \ + modems/xmm626/xmm626_kernel_smdk4412.h \ + modems/xmm626/hsic/hsic.c \ + modems/xmm626/hsic/xmm626_hsic.h \ + modems/xmm626/mipi/mipi.c \ + modems/xmm626/mipi/xmm626_mipi.h \ devices/ipc_devices.c \ devices/ipc_devices.h \ devices/crespo/crespo.c \ diff --git a/samsung-ipc/devices/galaxys2/galaxys2.c b/samsung-ipc/devices/galaxys2/galaxys2.c index cdfe20c..296feac 100644 --- a/samsung-ipc/devices/galaxys2/galaxys2.c +++ b/samsung-ipc/devices/galaxys2/galaxys2.c @@ -28,7 +28,7 @@ #include "ipc.h" #include "devices/galaxys2/galaxys2.h" #include "modems/xmm626/xmm626.h" -#include "modems/xmm626/xmm626_hsic.h" +#include "modems/xmm626/hsic/hsic.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" int galaxys2_boot(struct ipc_client *client) diff --git a/samsung-ipc/devices/i9300/i9300.c b/samsung-ipc/devices/i9300/i9300.c index 85709a8..355ff62 100644 --- a/samsung-ipc/devices/i9300/i9300.c +++ b/samsung-ipc/devices/i9300/i9300.c @@ -28,7 +28,7 @@ #include "ipc.h" #include "devices/i9300/i9300.h" #include "modems/xmm626/xmm626.h" -#include "modems/xmm626/xmm626_hsic.h" +#include "modems/xmm626/hsic/hsic.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" int i9300_boot(struct ipc_client *client) diff --git a/samsung-ipc/devices/ipc_devices.h b/samsung-ipc/devices/ipc_devices.h index 176607c..17a40b8 100644 --- a/samsung-ipc/devices/ipc_devices.h +++ b/samsung-ipc/devices/ipc_devices.h @@ -42,6 +42,7 @@ struct ipc_device_desc { struct ipc_client_handlers *handlers; struct ipc_client_gprs_specs *gprs_specs; struct ipc_client_nv_data_specs *nv_data_specs; + struct ipc_client_modem_driver_ops *modem_driver_ops; }; extern struct ipc_device_desc ipc_devices[]; diff --git a/samsung-ipc/devices/maguro/maguro.c b/samsung-ipc/devices/maguro/maguro.c index a2db5fc..e6cd191 100644 --- a/samsung-ipc/devices/maguro/maguro.c +++ b/samsung-ipc/devices/maguro/maguro.c @@ -30,7 +30,7 @@ #include "devices/maguro/maguro.h" #include "modems/xmm626/xmm626.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" -#include "modems/xmm626/xmm626_mipi.h" +#include "modems/xmm626/mipi/xmm626_mipi.h" int maguro_boot(struct ipc_client *client) { diff --git a/samsung-ipc/devices/n5100/n5100.c b/samsung-ipc/devices/n5100/n5100.c index 0abe896..5489fb6 100644 --- a/samsung-ipc/devices/n5100/n5100.c +++ b/samsung-ipc/devices/n5100/n5100.c @@ -29,7 +29,7 @@ #include "ipc.h" #include "devices/n5100/n5100.h" #include "modems/xmm626/xmm626.h" -#include "modems/xmm626/xmm626_hsic.h" +#include "modems/xmm626/hsic/hsic.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" int n5100_boot(struct ipc_client *client) diff --git a/samsung-ipc/devices/n7100/n7100.c b/samsung-ipc/devices/n7100/n7100.c index d5091a2..4713e00 100644 --- a/samsung-ipc/devices/n7100/n7100.c +++ b/samsung-ipc/devices/n7100/n7100.c @@ -28,7 +28,7 @@ #include "ipc.h" #include "devices/n7100/n7100.h" #include "modems/xmm626/xmm626.h" -#include "modems/xmm626/xmm626_hsic.h" +#include "modems/xmm626/hsic/hsic.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" int n7100_boot(struct ipc_client *client) diff --git a/samsung-ipc/devices/piranha/piranha.c b/samsung-ipc/devices/piranha/piranha.c index 839b3ce..a98e1cb 100644 --- a/samsung-ipc/devices/piranha/piranha.c +++ b/samsung-ipc/devices/piranha/piranha.c @@ -29,7 +29,7 @@ #include "devices/piranha/piranha.h" #include "modems/xmm626/xmm626.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" -#include "modems/xmm626/xmm626_mipi.h" +#include "modems/xmm626/mipi/xmm626_mipi.h" int piranha_boot(struct ipc_client *client) { diff --git a/samsung-ipc/ipc.c b/samsung-ipc/ipc.c index c116fbb..efdd5d2 100644 --- a/samsung-ipc/ipc.c +++ b/samsung-ipc/ipc.c @@ -214,6 +214,7 @@ static struct ipc_client *ipc_transport_client_create(int type) client->gprs_specs = ipc_devices[device_index].gprs_specs; client->nv_data_specs = ipc_devices[device_index].nv_data_specs; + client->modem_driver_ops = ipc_devices[device_index].modem_driver_ops; /* Handlers can be modified */ client->handlers = (struct ipc_client_handlers *) calloc( diff --git a/samsung-ipc/ipc.h b/samsung-ipc/ipc.h index 1cfa757..dfeea11 100644 --- a/samsung-ipc/ipc.h +++ b/samsung-ipc/ipc.h @@ -78,6 +78,49 @@ struct ipc_client_gprs_specs { struct ipc_client_gprs_capabilities *capabilities); }; +struct ipc_client_modem_driver_ops { + int (*power)(struct ipc_client *client, int device_fd, int power); + int (*download_enable)(struct ipc_client *client, int device_fd, + int enable); + int (*bus_power)(struct ipc_client *client, int power); + int (*link_control_enable)(struct ipc_client *client, int device_fd, + int enable); + int (*link_control_active)(struct ipc_client *client, int device_fd, + int active); + int (*link_connected_wait)(struct ipc_client *client, int device_fd); + int (*link_get_hostwake_wait)(struct ipc_client *client, int device_fd); + int (*wait_status_online)( + __attribute__((unused)) struct ipc_client *client, + int device_fd); + int (*open)(struct ipc_client *client, int type); + int (*close)(struct ipc_client *client, int fd); + int (*read)(struct ipc_client *client, int fd, void *buffer, + size_t length); + int (*write)(struct ipc_client *client, int fd, const void *buffer, + size_t length); + int (*poll)(struct ipc_client *client, int fd, struct ipc_poll_fds *fds, + struct timeval *timeout); + + int (*fmt_send)(struct ipc_client *client, struct ipc_message *message); + int (*fmt_recv)(struct ipc_client *client, struct ipc_message *message); + int (*rfs_send)(struct ipc_client *client, struct ipc_message *message); + int (*rfs_recv)(struct ipc_client *client, struct ipc_message *message); + //TODO: find a better name not to conflict with fmt/rfs send + // like block-data send (used for firmware) + // what about firmware->MAIN + // and data_send firmware_send + // or send_partition + // or send_block + int (*data_send)(struct ipc_client *client, int device_fd, const void *data, + size_t size, int address); + + char * (*gprs_get_iface)(struct ipc_client *client, unsigned int cid); + int (*gprs_get_capabilities)( + struct ipc_client *client, + struct ipc_client_gprs_capabilities *capabilities); +}; + + struct ipc_client_nv_data_specs { char *nv_data_path; char *nv_data_md5_path; @@ -98,6 +141,7 @@ struct ipc_client { struct ipc_client_handlers *handlers; struct ipc_client_gprs_specs *gprs_specs; struct ipc_client_nv_data_specs *nv_data_specs; + struct ipc_client_modem_driver_ops *modem_driver_ops; }; /* diff --git a/samsung-ipc/modems/modem.c b/samsung-ipc/modems/modem.c new file mode 100644 index 0000000..82a6ca7 --- /dev/null +++ b/samsung-ipc/modems/modem.c @@ -0,0 +1,194 @@ +/* + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2020 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> + * + * 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 <ipc.h> + +/* Set the modem into download mode */ +int modem_download_enable(struct ipc_client *client, int device_fd, int enable) +{ + return client->modem_driver_ops->download_enable(client, device_fd, + enable); +} + +/* Power on/off the modem */ +int modem_power(struct ipc_client *client, int device_fd, int power) +{ + return client->modem_driver_ops->power(client, device_fd, power); +} + +/* Power on/off the modem bus (HSIC, MIPI, etc) */ +int modem_bus_power(struct ipc_client *client, int power) +{ + return client->modem_driver_ops->bus_power(client, power); +} + +// TODO +int modem_link_control_enable(struct ipc_client *client, int device_fd, + int enable) +{ + return client->modem_driver_ops->link_control_enable(client, device_fd, + enable); +} + +//TODO +//0: HSIC is low power +//1: HSIC is back +int modem_link_control_active(struct ipc_client *client, int device_fd, + int active) +{ + return client->modem_driver_ops->link_control_active(client, device_fd, + active); +} + +//TODO: +int modem_link_connected_wait(struct ipc_client *client, int device_fd) +{ + return client->modem_driver_ops->link_connected_wait(client, device_fd); +} + +// TODO +int modem_link_get_hostwake_wait(struct ipc_client *client, int device_fd) +{ + return client->modem_driver_ops->link_get_hostwake_wait(client, + device_fd); +} + +/* Wait for the modem driver to report the ONLINE status */ +int modem_wait_status_online(__attribute__((unused)) struct ipc_client *client, + int device_fd) +{ + return client->modem_driver_ops->wait_status_online(client, device_fd); +} + +int modem_open(struct ipc_client *client, int type) +{ + return client->modem_driver_ops->open(client, type); +} + +int modem_close(struct ipc_client *client, int fd) +{ + return client->modem_driver_ops->close(client, fd); +} + +int modem_read(struct ipc_client *client, int fd, void *buffer, size_t length) +{ + return client->modem_driver_ops->read(client, fd, buffer, length); +} + +int modem_write(struct ipc_client *client, int fd, const void *buffer, + size_t length) +{ + return client->modem_driver_ops->write(client, fd, buffer, length); +} + +int modem_poll(struct ipc_client *client, int fd, struct ipc_poll_fds *fds, + struct timeval *timeout) +{ + return client->modem_driver_ops->poll(client, fd, fds, timeout); +} + +int modem_fmt_send(struct ipc_client *client, struct ipc_message *message) +{ + return client->modem_driver_ops->fmt_send(client, message); +} + +int modem_fmt_recv(struct ipc_client *client, struct ipc_message *message) +{ + return client->modem_driver_ops->fmt_recv(client, message); +} + +int modem_rfs_send(struct ipc_client *client, struct ipc_message *message) +{ + return client->modem_driver_ops->rfs_send(client, message); +} + +int modem_rfs_recv(struct ipc_client *client, struct ipc_message *message) +{ + return client->modem_driver_ops->rfs_recv(client, message); +} + +// TODO +char *modem_gprs_get_iface(struct ipc_client *client, unsigned int cid) +{ + return client->modem_driver_ops->gprs_get_iface(client, cid); +} + +// TODO +int modem_gprs_get_capabilities(struct ipc_client *client, + struct ipc_client_gprs_capabilities *capabilities) +{ + return client->modem_driver_ops->gprs_get_capabilities(client, + capabilities); +} + +// TODO: make it more generic: +// - get rid of device_fd +// - we have many <modem>_<firmware_partition>_send +// functions for partitions: +// | Function | Partition | +// | psi | PSIRAM | +// | ebl | EBL | +// | firmware | MAIN | +// | sec_start | SECPACK | +// | device specific | NV | + +// int modem_psi_send(struct ipc_client *client, int serial_fd, +// const void *psi_data, unsigned short psi_size); +// { +// /* TODO: get rid of serial_fd */ +// return client->modem_driver_ops->psi_send(client, serial_fd, psi_data, +// psi_size); +// } +// +// int modem_firmware_send(struct ipc_client *client, int device_fd, +// void *device_address, const void *firmware_data, +// size_t firmware_size) +// { +// /* TODO: get rid of device_fd */ +// return client->modem_driver_ops->firmware_send(client, device_fd, +// device_address, +// firmware_data, +// firmware_size); +// } +// +// int modem_nv_data_send(struct ipc_client *client, int device_fd, +// void *device_address) +// { +// /* TODO: get rid of device_fd */ +// return client->modem_driver_ops->firmware_send(client, device_fd, +// device_address); +// } +// +// +// int modem_psi_send(struct ipc_client *client, int serial_fd, +// const void *psi_data, unsigned short psi_size); +// { +// /* TODO: get rid of serial_fd */ +// return client->modem_driver_ops->psi_send(client, serial_fd, psi_data, +// psi_size); +// } +// + +// TODO: find a better name like block data (used for fimrware partitions) +int modem_data_send(struct ipc_client *client, int device_fd, const void *data, + size_t size, int address) +{ + return client->modem_driver_ops->data_send(client, device_fd, data, + size, address); +} diff --git a/samsung-ipc/modems/modem.h b/samsung-ipc/modems/modem.h new file mode 100644 index 0000000..b8119ce --- /dev/null +++ b/samsung-ipc/modems/modem.h @@ -0,0 +1,35 @@ +#ifndef __SAMSUNG_IPC_MODEM_H__ +#define __SAMSUNG_IPC_MODEM_H__ +int modem_download_enable(__attribute__((unused)) struct ipc_client *client, + int device_fd, int enable); +int modem_power(struct ipc_client *client, int device_fd, int power); +int modem_bus_power(struct ipc_client *client, int power); +int modem_link_control_enable(struct ipc_client *client, int device_fd, + int enable); +int modem_link_control_active(struct ipc_client *client, int device_fd, + int active); +int modem_link_connected_wait(struct ipc_client *client, int device_fd); +int modem_link_get_hostwake_wait(struct ipc_client *client, int device_fd); +int modem_wait_status(__attribute__((unused)) struct ipc_client *client, + int device_fd); +int modem_open(struct ipc_client *client, int type); +int modem_close(struct ipc_client *client, int fd); +int modem_read(struct ipc_client *client, int fd, void *buffer, size_t length); +int modem_write(struct ipc_client *client, int fd, const void *buffer, + size_t length); +int modem_poll(struct ipc_client *client, int fd, struct ipc_poll_fds *fds, + struct timeval *timeout); + +int modem_fmt_send(struct ipc_client *client, struct ipc_message *message); +int modem_fmt_recv(struct ipc_client *client, struct ipc_message *message); +int modem_rfs_send(struct ipc_client *client, struct ipc_message *message); +int modem_rfs_recv(struct ipc_client *client, struct ipc_message *message); +// TODO: find a better name like block data (used for fimrware partitions) +int modem_data_send(struct ipc_client *client, int device_fd, const void *data, + size_t size, int address); + +char *modem_gprs_get_iface(struct ipc_client *client, unsigned int cid); +int modem_gprs_get_capabilities(struct ipc_client *client, + struct ipc_client_gprs_capabilities *capabilities); + +#endif /* __SAMSUNG_IPC_MODEM_H__ */ diff --git a/samsung-ipc/modems/xmm626/firmware.c b/samsung-ipc/modems/xmm626/firmware.c new file mode 100644 index 0000000..a7d5f5c --- /dev/null +++ b/samsung-ipc/modems/xmm626/firmware.c @@ -0,0 +1,84 @@ +/* + * 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/xmm626.h" + +int xmm626_firmware_send(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; +} diff --git a/samsung-ipc/modems/xmm626/xmm626_hsic.c b/samsung-ipc/modems/xmm626/hsic/hsic.c index 6e7126c..b195753 100644 --- a/samsung-ipc/modems/xmm626/xmm626_hsic.c +++ b/samsung-ipc/modems/xmm626/hsic/hsic.c @@ -29,8 +29,10 @@ #include <samsung-ipc.h> +#include "ipc.h" #include "modems/xmm626/xmm626.h" -#include "modems/xmm626/xmm626_hsic.h" +#include "modems/xmm626/xmm626_kernel_smdk4412.h" +#include "modems/xmm626/hsic/hsic.h" int xmm626_hsic_ack_read(int device_fd, unsigned short ack) { @@ -391,8 +393,8 @@ complete: return rc; } -int xmm626_hsic_modem_data_send(int device_fd, const void *data, size_t size, - int address) +int xmm626_hsic_modem_data_send(struct ipc_client *client, int device_fd, + const void *data, size_t size, int address) { size_t chunk; size_t count; @@ -533,62 +535,6 @@ int xmm626_hsic_sec_end_send(struct ipc_client *client, int device_fd) return 0; } -int xmm626_hsic_firmware_send(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 = xmm626_hsic_modem_data_send(device_fd, firmware_data, - firmware_size, - XMM626_FIRMWARE_ADDRESS); - if (rc < 0) - return -1; - - return 0; -} - -int xmm626_hsic_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 = xmm626_hsic_modem_data_send(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; -} int xmm626_hsic_hw_reset_send(struct ipc_client *client, int device_fd) { @@ -610,3 +556,33 @@ int xmm626_hsic_hw_reset_send(struct ipc_client *client, int device_fd) return 0; } + +struct ipc_client_modem_driver_ops smdk4412_xmm626_hsic_modem_driver_ops = { + .download_enable = xmm626_kernel_smdk4412_boot_power, + .power = xmm626_kernel_smdk4412_power, + .bus_power = xmm626_kernel_smdk4412_hci_power, + .link_control_enable = xmm626_kernel_smdk4412_link_control_enable, + .link_control_active = xmm626_kernel_smdk4412_link_control_active, + .link_connected_wait = xmm626_kernel_smdk4412_link_connected_wait, + .link_get_hostwake_wait = xmm626_kernel_smdk4412_link_get_hostwake_wait, + .wait_status_online = xmm626_kernel_smdk4412_status_online_wait, + + .open = xmm626_kernel_smdk4412_open, + .close = xmm626_kernel_smdk4412_close, + .read = xmm626_kernel_smdk4412_read, + .write = xmm626_kernel_smdk4412_write, + .poll = xmm626_kernel_smdk4412_poll, + + .fmt_send = xmm626_kernel_smdk4412_fmt_send, + .fmt_recv = xmm626_kernel_smdk4412_fmt_recv, + .rfs_send = xmm626_kernel_smdk4412_rfs_send, + .rfs_recv = xmm626_kernel_smdk4412_rfs_recv, + + // TODO: find a better name for data_send + .data_send = xmm626_hsic_modem_data_send, + + // TODO + // .gprs_get_iface = xmm626_kernel_smdk4412_gprs_get_iface, + // .modem_gprs_get_capabilities = xmm626_kernel_smdk4412_modem_gprs_get_capabilities, +}; + diff --git a/samsung-ipc/modems/xmm626/xmm626_hsic.h b/samsung-ipc/modems/xmm626/hsic/hsic.h index 6385cdc..fc172d5 100644 --- a/samsung-ipc/modems/xmm626/xmm626_hsic.h +++ b/samsung-ipc/modems/xmm626/hsic/hsic.h @@ -63,5 +63,8 @@ int xmm626_hsic_firmware_send(struct ipc_client *client, int device_fd, const void *firmware_data, size_t firmware_size); int xmm626_hsic_nv_data_send(struct ipc_client *client, int device_fd); int xmm626_hsic_hw_reset_send(struct ipc_client *client, int device_fd); +int xmm626_hsic_modem_data_send(struct ipc_client *client, int device_fd, + const void *data, size_t size, int address); + #endif /* __XMM626_HSIC_H__ */ diff --git a/samsung-ipc/modems/xmm626/hsic/xmm626_kernel_smdk4412.c b/samsung-ipc/modems/xmm626/hsic/xmm626_kernel_smdk4412.c new file mode 100644 index 0000000..ef8e975 --- /dev/null +++ b/samsung-ipc/modems/xmm626/hsic/xmm626_kernel_smdk4412.c @@ -0,0 +1,634 @@ +/* + * 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> + * + * 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/>. + */ + +#define _GNU_SOURCE +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/select.h> + +#include <samsung-ipc.h> +#include <ipc.h> + +#include "xmm626_modem_if.h" +#include "xmm626_modem_prj.h" +#include "xmm626_modem_link_device_hsic.h" + +#include "xmm626.h" +#include "xmm626_kernel_smdk4412.h" + +int xmm626_kernel_smdk4412_power( + __attribute__((unused)) struct ipc_client *client, int device_fd, + int power) +{ + int rc; + + if (device_fd < 0) + return -1; + + rc = ioctl(device_fd, power ? IOCTL_MODEM_ON : IOCTL_MODEM_OFF, 0); + if (rc < 0) + return -1; + + return 0; +} + +int xmm626_kernel_smdk4412_boot_power( + __attribute__((unused)) struct ipc_client *client, int device_fd, + int power) +{ + int rc; + + if (device_fd < 0) + return -1; + + rc = ioctl(device_fd, power ? + IOCTL_MODEM_BOOT_ON : IOCTL_MODEM_BOOT_OFF, + 0); + if (rc < 0) + return -1; + + return 0; +} + +int xmm626_kernel_smdk4412_status_online_wait( + __attribute__((unused)) struct ipc_client *client, int device_fd) +{ + int status; + int i; + + if (device_fd < 0) + return -1; + + i = 0; + for (i = 0; i < 100; i++) { + status = ioctl(device_fd, IOCTL_MODEM_STATUS, 0); + if (status == STATE_ONLINE) + return 0; + + usleep(50000); + } + + return -1; +} + +int xmm626_kernel_smdk4412_hci_power( + __attribute__((unused)) struct ipc_client *client, int power) +{ + int ehci_rc, ohci_rc; + + ehci_rc = sysfs_value_write(XMM626_SEC_MODEM_EHCI_POWER_SYSFS, !!power); + if (ehci_rc >= 0) + usleep(50000); + + ohci_rc = sysfs_value_write(XMM626_SEC_MODEM_OHCI_POWER_SYSFS, !!power); + if (ohci_rc >= 0) + usleep(50000); + + if (ehci_rc < 0 && ohci_rc < 0) + return -1; + + return 0; +} + +int xmm626_kernel_smdk4412_link_control_enable( + __attribute__((unused)) struct ipc_client *client, + int device_fd, int enable) +{ + int rc; + + if (device_fd < 0) + return -1; + + rc = ioctl(device_fd, IOCTL_LINK_CONTROL_ENABLE, &enable); + if (rc < 0) + return -1; + + return 0; +} + +int xmm626_kernel_smdk4412_link_control_active( + __attribute__((unused)) struct ipc_client *client, int device_fd, + int active) +{ + int rc; + + if (device_fd < 0) + return -1; + + rc = ioctl(device_fd, IOCTL_LINK_CONTROL_ACTIVE, &active); + if (rc < 0) + return -1; + + return 0; +} + +int xmm626_kernel_smdk4412_link_connected_wait( + __attribute__((unused)) struct ipc_client *client, int device_fd) +{ + int status; + int i; + + if (device_fd < 0) + return -1; + + i = 0; + for (i = 0; i < 100; i++) { + status = ioctl(device_fd, IOCTL_LINK_CONNECTED, 0); + if (status) + return 0; + + usleep(50000); + } + + return -1; +} + +int xmm626_kernel_smdk4412_link_get_hostwake_wait( + __attribute__((unused)) struct ipc_client *client, int device_fd) +{ + int status; + int i; + + if (device_fd < 0) + return -1; + + i = 0; + for (i = 0; i < 10; i++) { + status = ioctl(device_fd, IOCTL_LINK_GET_HOSTWAKE, 0); + if (status) + return 0; + + usleep(50000); + } + + return -1; +} + +int xmm626_kernel_smdk4412_fmt_send(struct ipc_client *client, + struct ipc_message *message) +{ + struct ipc_fmt_header header; + void *buffer; + size_t length; + size_t count; + unsigned char *p; + int rc; + + if (client == NULL || client->handlers == NULL || + client->handlers->write == NULL || message == NULL) { + return -1; + } + + ipc_fmt_header_setup(&header, message); + + length = header.length; + buffer = calloc(1, length); + + memcpy(buffer, &header, sizeof(struct ipc_fmt_header)); + if (message->data != NULL && message->size > 0) { + memcpy((void *) ((unsigned char *) buffer + + sizeof(struct ipc_fmt_header)), + message->data, message->size); + } + + ipc_client_log_send(client, message, __func__); + + p = (unsigned char *) buffer; + + count = 0; + while (count < length) { + rc = client->handlers->write(client, + client->handlers->transport_data, + p, length - count); + if (rc <= 0) { + ipc_client_log(client, "Writing FMT data failed"); + goto error; + } + + count += rc; + p += rc; + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (buffer != NULL) + free(buffer); + + return rc; +} + +int xmm626_kernel_smdk4412_fmt_recv(struct ipc_client *client, + struct ipc_message *message) +{ + struct ipc_fmt_header *header; + void *buffer = NULL; + size_t length; + size_t count; + unsigned char *p; + int rc; + + if (client == NULL || client->handlers == NULL || + client->handlers->read == NULL || message == NULL) { + return -1; + } + + length = XMM626_DATA_SIZE; + buffer = calloc(1, length); + + rc = client->handlers->read(client, client->handlers->transport_data, + buffer, length); + if (rc < (int) sizeof(struct ipc_fmt_header)) { + ipc_client_log(client, "Reading FMT header failed"); + goto error; + } + + header = (struct ipc_fmt_header *) buffer; + + ipc_fmt_message_setup(header, message); + + if (header->length > sizeof(struct ipc_fmt_header)) { + message->size = header->length - sizeof(struct ipc_fmt_header); + message->data = calloc(1, message->size); + + p = (unsigned char *) message->data; + + count = rc - sizeof(struct ipc_fmt_header); + if (count > 0) { + memcpy(p, + (void *) ((unsigned char *) buffer + + sizeof(struct ipc_fmt_header)), + count); + p += count; + } + + while (count < message->size) { + rc = client->handlers->read( + client, client->handlers->transport_data, p, + message->size - count); + if (rc <= 0) { + ipc_client_log(client, + "Reading FMT data failed"); + goto error; + } + + count += rc; + p += rc; + } + } + + ipc_client_log_recv(client, message, __func__); + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (buffer != NULL) + free(buffer); + + return rc; +} + +int xmm626_kernel_smdk4412_rfs_send(struct ipc_client *client, + struct ipc_message *message) +{ + struct ipc_rfs_header header; + void *buffer; + size_t length; + size_t count; + unsigned char *p; + int rc; + + if (client == NULL || client->handlers == NULL || + client->handlers->write == NULL || message == NULL) { + return -1; + } + + ipc_rfs_header_setup(&header, message); + + length = header.length; + buffer = calloc(1, length); + + memcpy(buffer, &header, sizeof(struct ipc_rfs_header)); + if (message->data != NULL && message->size > 0) { + memcpy((void *) ( + (unsigned char *) buffer + + sizeof(struct ipc_rfs_header)), + message->data, + message->size); + } + + ipc_client_log_send(client, message, __func__); + + p = (unsigned char *) buffer; + + count = 0; + while (count < length) { + rc = client->handlers->write(client, + client->handlers->transport_data, + p, length - count); + if (rc <= 0) { + ipc_client_log(client, "Writing RFS data failed"); + goto error; + } + + count += rc; + p += rc; + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (buffer != NULL) + free(buffer); + + return rc; +} + +int xmm626_kernel_smdk4412_rfs_recv(struct ipc_client *client, + struct ipc_message *message) +{ + struct ipc_rfs_header *header; + void *buffer = NULL; + size_t length; + size_t count; + unsigned char *p; + int rc; + + if (client == NULL || client->handlers == NULL || + client->handlers->read == NULL || message == NULL) { + return -1; + } + + length = XMM626_DATA_SIZE; + buffer = calloc(1, length); + + rc = client->handlers->read(client, client->handlers->transport_data, + buffer, length); + if (rc < (int) sizeof(struct ipc_rfs_header)) { + ipc_client_log(client, "Reading RFS header failed"); + goto error; + } + + header = (struct ipc_rfs_header *) buffer; + if (header->length > XMM626_DATA_SIZE_LIMIT) { + ipc_client_log(client, "Invalid RFS header length: %u", + header->length); + goto error; + } + + ipc_rfs_message_setup(header, message); + + if (header->length > sizeof(struct ipc_rfs_header)) { + message->size = header->length - sizeof(struct ipc_rfs_header); + message->data = calloc(1, message->size); + + p = (unsigned char *) message->data; + + count = rc - sizeof(struct ipc_rfs_header); + if (count > 0) { + memcpy(p, + (void *) ((unsigned char *) buffer + + sizeof(struct ipc_rfs_header)), + count); + p += count; + } + + while (count < message->size) { + rc = client->handlers->read( + client, client->handlers->transport_data, p, + message->size - count); + if (rc <= 0) { + ipc_client_log(client, + "Reading RFS data failed"); + goto error; + } + + count += rc; + p += rc; + } + } + + ipc_client_log_recv(client, message, __func__); + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (buffer != NULL) + free(buffer); + + return rc; +} + +int xmm626_kernel_smdk4412_open( + __attribute__((unused)) struct ipc_client *client, int type) +{ + int fd; + + switch (type) { + case IPC_CLIENT_TYPE_FMT: + fd = open(XMM626_SEC_MODEM_IPC0_DEVICE, + O_RDWR | O_NOCTTY | O_NONBLOCK); + break; + case IPC_CLIENT_TYPE_RFS: + fd = open(XMM626_SEC_MODEM_RFS0_DEVICE, + O_RDWR | O_NOCTTY | O_NONBLOCK); + break; + default: + return -1; + } + + return fd; +} + +int xmm626_kernel_smdk4412_close( + __attribute__((unused)) struct ipc_client *client, int fd) +{ + if (fd < 0) + return -1; + + close(fd); + + return 0; +} + +int xmm626_kernel_smdk4412_read( + __attribute__((unused)) struct ipc_client *client, int fd, void *buffer, + size_t length) +{ + int status; + int rc; + + if (fd < 0 || buffer == NULL || length <= 0) + return -1; + + status = ioctl(fd, IOCTL_MODEM_STATUS, 0); + if (status != STATE_ONLINE && status != STATE_BOOTING) + return -1; + + rc = read(fd, buffer, length); + + return rc; +} + +int xmm626_kernel_smdk4412_write( + __attribute__((unused)) struct ipc_client *client, int fd, + const void *buffer, size_t length) +{ + int status; + int rc; + + if (fd < 0 || buffer == NULL || length <= 0) + return -1; + + status = ioctl(fd, IOCTL_MODEM_STATUS, 0); + if (status != STATE_ONLINE && status != STATE_BOOTING) + return -1; + + rc = write(fd, buffer, length); + + return rc; +} + +int xmm626_kernel_smdk4412_poll( + __attribute__((unused)) struct ipc_client *client, + int fd, struct ipc_poll_fds *fds, struct timeval *timeout) +{ + int status; + fd_set set; + int fd_max; + unsigned int i; + unsigned int count; + int rc; + + if (fd < 0) + return -1; + + FD_ZERO(&set); + FD_SET(fd, &set); + + fd_max = fd; + + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + for (i = 0; i < fds->count; i++) { + if (fds->fds[i] >= 0) { + FD_SET(fds->fds[i], &set); + + if (fds->fds[i] > fd_max) + fd_max = fds->fds[i]; + } + } + } + + rc = select(fd_max + 1, &set, NULL, NULL, timeout); + + if (FD_ISSET(fd, &set)) { + status = ioctl(fd, IOCTL_MODEM_STATUS, 0); + if (status != STATE_ONLINE && status != STATE_BOOTING) + return -1; + } + + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + count = fds->count; + + for (i = 0; i < fds->count; i++) { + if (!FD_ISSET(fds->fds[i], &set)) { + fds->fds[i] = -1; + count--; + } + } + + fds->count = count; + } + + return rc; +} + +char *xmm626_kernel_smdk4412_gprs_get_iface( + __attribute__((unused)) struct ipc_client *client, unsigned int cid) +{ + char *iface = NULL; + + if (cid > XMM626_SEC_MODEM_GPRS_IFACE_COUNT) + return NULL; + + asprintf(&iface, "%s%d", XMM626_SEC_MODEM_GPRS_IFACE_PREFIX, cid - 1); + + return iface; +} + +int xmm626_kernel_smdk4412_gprs_get_capabilities( + __attribute__((unused)) struct ipc_client *client, + struct ipc_client_gprs_capabilities *capabilities) +{ + if (capabilities == NULL) + return -1; + + capabilities->cid_count = XMM626_SEC_MODEM_GPRS_IFACE_COUNT; + + return 0; +} + +struct ipc_client_modem_driver_ops smdk4412_xmm626_modem_driver_ops = { +#if 0 + .download_enable = xmm626_kernel_smdk4412_boot_power, + .power = xmm626_kernel_smdk4412_power, + .bus_power = xmm626_kernel_smdk4412_hci_power, + .link_control_enable = xmm626_kernel_smdk4412_link_control_enable, + .link_control_active = xmm626_kernel_smdk4412_link_control_active, + .link_connected_wait = xmm626_kernel_smdk4412_link_connected_wait, + .link_get_hostwake_wait = xmm626_kernel_smdk4412_link_get_hostwake_wait, + .wait_status_online = xmm626_kernel_smdk4412_status_online_wait, + + .open = xmm626_kernel_smdk4412_open, + .close = xmm626_kernel_smdk4412_close, + .read = xmm626_kernel_smdk4412_read, + .write = xmm626_kernel_smdk4412_write, + .poll = xmm626_kernel_smdk4412_poll, + + .fmt_send = xmm626_kernel_smdk4412_fmt_send, + .fmt_recv = xmm626_kernel_smdk4412_fmt_recv, + .rfs_send = xmm626_kernel_smdk4412_rfs_send, + .rfs_recv = xmm626_kernel_smdk4412_rfs_recv, + + // TODO + // .gprs_get_iface = xmm626_kernel_smdk4412_gprs_get_iface, + // .modem_gprs_get_capabilities = xmm626_kernel_smdk4412_modem_gprs_get_capabilities, +#endif +}; diff --git a/samsung-ipc/modems/xmm626/xmm626_modem_link_device_hsic.h b/samsung-ipc/modems/xmm626/hsic/xmm626_modem_link_device_hsic.h index f2421e0..f2421e0 100644 --- a/samsung-ipc/modems/xmm626/xmm626_modem_link_device_hsic.h +++ b/samsung-ipc/modems/xmm626/hsic/xmm626_modem_link_device_hsic.h diff --git a/samsung-ipc/modems/xmm626/xmm626_kernel_smdk4412.c b/samsung-ipc/modems/xmm626/kernel_smdk4412.c index c6b1578..d9c7620 100644 --- a/samsung-ipc/modems/xmm626/xmm626_kernel_smdk4412.c +++ b/samsung-ipc/modems/xmm626/kernel_smdk4412.c @@ -32,7 +32,7 @@ #include "ipc.h" #include "modems/xmm626/xmm626.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" -#include "modems/xmm626/xmm626_modem_link_device_hsic.h" +#include "modems/xmm626/hsic/xmm626_modem_link_device_hsic.h" #include "modems/xmm626/xmm626_modem_prj.h" int xmm626_kernel_smdk4412_power( @@ -602,3 +602,4 @@ int xmm626_kernel_smdk4412_gprs_get_capabilities( return 0; } + diff --git a/samsung-ipc/modems/xmm626/xmm626_mipi.c b/samsung-ipc/modems/xmm626/mipi/mipi.c index 375ded0..c356d5a 100644 --- a/samsung-ipc/modems/xmm626/xmm626_mipi.c +++ b/samsung-ipc/modems/xmm626/mipi/mipi.c @@ -29,8 +29,10 @@ #include <samsung-ipc.h> +#include "ipc.h" #include "modems/xmm626/xmm626.h" -#include "modems/xmm626/xmm626_mipi.h" +#include "modems/xmm626/xmm626_kernel_smdk4412.h" +#include "modems/xmm626/mipi/xmm626_mipi.h" int xmm626_mipi_crc_calculate(const void *data, size_t size) { @@ -419,8 +421,8 @@ complete: return rc; } -int xmm626_mipi_modem_data_send(int device_fd, const void *data, size_t size, - int address) +int xmm626_mipi_modem_data_send(struct ipc_client *client, int device_fd, + const void *data, size_t size, int address) { size_t chunk; size_t count; @@ -578,62 +580,6 @@ int xmm626_mipi_sec_end_send(struct ipc_client *client, int device_fd) return 0; } -int xmm626_mipi_firmware_send(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 = xmm626_mipi_modem_data_send(device_fd, firmware_data, - firmware_size, - XMM626_FIRMWARE_ADDRESS); - if (rc < 0) - return -1; - - return 0; -} - -int xmm626_mipi_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 = xmm626_mipi_modem_data_send(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; -} int xmm626_mipi_mps_data_send(struct ipc_client *client, int device_fd, const void *mps_data, size_t mps_size) @@ -645,7 +591,7 @@ int xmm626_mipi_mps_data_send(struct ipc_client *client, int device_fd, return -1; } - rc = xmm626_mipi_modem_data_send(device_fd, mps_data, mps_size, + rc = xmm626_mipi_modem_data_send(client, device_fd, mps_data, mps_size, XMM626_MPS_DATA_ADDRESS); if (rc < 0) return -1; @@ -672,3 +618,29 @@ int xmm626_mipi_hw_reset_send(struct ipc_client *client, int device_fd) return 0; } + +struct ipc_client_modem_driver_ops smdk4412_xmm626_mipi_modem_driver_ops = { + .download_enable = xmm626_kernel_smdk4412_boot_power, //TODO + .power = xmm626_kernel_smdk4412_power, //TODO + .bus_power = xmm626_kernel_smdk4412_hci_power, //TODO + .link_control_enable = xmm626_kernel_smdk4412_link_control_enable, //TODO + .link_control_active = xmm626_kernel_smdk4412_link_control_active, //TODO + .link_connected_wait = xmm626_kernel_smdk4412_link_connected_wait, //TODO + .link_get_hostwake_wait = xmm626_kernel_smdk4412_link_get_hostwake_wait, //TODO + .wait_status_online = xmm626_kernel_smdk4412_status_online_wait, //TODO + + .open = xmm626_kernel_smdk4412_open, //TODO + .close = xmm626_kernel_smdk4412_close, //TODO + .read = xmm626_kernel_smdk4412_read, //TODO + .write = xmm626_kernel_smdk4412_write, //TODO + .poll = xmm626_kernel_smdk4412_poll, //TODO + + .fmt_send = xmm626_kernel_smdk4412_fmt_send, //TODO + .fmt_recv = xmm626_kernel_smdk4412_fmt_recv, //TODO + .rfs_send = xmm626_kernel_smdk4412_rfs_send, //TODO + .rfs_recv = xmm626_kernel_smdk4412_rfs_recv, //TODO + .data_send = xmm626_mipi_modem_data_send, + + // .gprs_get_iface = xmm626_kernel_smdk4412_gprs_get_iface, + // .modem_gprs_get_capabilities = xmm626_kernel_smdk4412_modem_gprs_get_capabilities, +}; diff --git a/samsung-ipc/modems/xmm626/xmm626_mipi.h b/samsung-ipc/modems/xmm626/mipi/xmm626_mipi.h index 1545a3e..67b35ba 100644 --- a/samsung-ipc/modems/xmm626/xmm626_mipi.h +++ b/samsung-ipc/modems/xmm626/mipi/xmm626_mipi.h @@ -67,5 +67,7 @@ int xmm626_mipi_nv_data_send(struct ipc_client *client, int device_fd); int xmm626_mipi_mps_data_send(struct ipc_client *client, int device_fd, const void *mps_data, size_t mps_size); int xmm626_mipi_hw_reset_send(struct ipc_client *client, int device_fd); +int xmm626_mipi_modem_data_send(struct ipc_client *client, int device_fd, + const void *data, size_t size, int address); #endif /* __XMM626_MIPI_H__ */ diff --git a/scripts/smdk4412_func_usage.py b/scripts/smdk4412_func_usage.py new file mode 100755 index 0000000..fe54f66 --- /dev/null +++ b/scripts/smdk4412_func_usage.py @@ -0,0 +1,85 @@ +#!/bin/env python + +import os +import re +from sh import git + +funcs = [ + 'xmm626_kernel_smdk4412_power', + 'xmm626_kernel_smdk4412_boot_power', + 'xmm626_kernel_smdk4412_hci_power', + 'xmm626_kernel_smdk4412_link_control_enable', + 'xmm626_kernel_smdk4412_link_control_active', + 'xmm626_kernel_smdk4412_link_connected_wait', + 'xmm626_kernel_smdk4412_link_get_hostwake_wait', + 'xmm626_kernel_smdk4412_status_online_wait', + 'xmm626_kernel_smdk4412_open', + 'xmm626_kernel_smdk4412_close', + 'xmm626_kernel_smdk4412_read', + 'xmm626_kernel_smdk4412_write', + 'xmm626_kernel_smdk4412_poll', + 'xmm626_kernel_smdk4412_fmt_send', + 'xmm626_kernel_smdk4412_fmt_recv', + 'xmm626_kernel_smdk4412_rfs_send', + 'xmm626_kernel_smdk4412_rfs_recv', + 'xmm626_kernel_smdk4412_gprs_get_iface', + 'xmm626_kernel_smdk4412_gprs_get_capabilities', +] + +results = {} + +def func_usage(func): + output = "" + try: + output = git('--no-pager', 'grep', '--color=never', func) + except: + pass + + for line in output: + filepath = line.split(":")[0] + content = line.split(":")[1] + + device = None + if re.match('samsung-ipc/devices/.*/*\.c$', filepath): + device = re.sub('\.c', '', os.path.basename(filepath)) + if device not in results: + results[device] = {} + results[device][func] = True + +def print_func_group(device, device_data, device_maxlen, funcs, regex): + print ("| {}{} |".format(device, " " * (device_maxlen - len(device))), + end='') + for func in funcs: + if re.search(regex, func): + func_name = re.sub('xmm626_kernel_smdk4412_','', func) + if func in device_data: + print (" {} |".format(func_name), end='') + else: + print (" {} |".format(" " * len(func_name)), end='') + print() + +def report_results(results): + device_maxlen = 0 + for key in results.keys(): + if len(key) > device_maxlen: + device_maxlen = len(key) + + + print ("+{}+".format("-" * (device_maxlen + 2))) + for device, device_data in results.items(): + # All: + # print_func_group(device, device_data, device_maxlen, funcs, + # "open|close|read|write|poll") + # print_func_group(device, device_data, device_maxlen, funcs, "fmt|rfs") + # print_func_group(device, device_data, device_maxlen, funcs, "gprs") + + + print_func_group(device, device_data, device_maxlen, funcs, + "power|link|status") + + print ("+{}+".format("-" * (device_maxlen + 2))) + +for func in funcs: + func_usage(func) + +report_results(results) |