diff options
Diffstat (limited to 'samsung-ipc/modems/generic-xmm626/generic-xmm626_sec_modem.c')
-rw-r--r-- | samsung-ipc/modems/generic-xmm626/generic-xmm626_sec_modem.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/samsung-ipc/modems/generic-xmm626/generic-xmm626_sec_modem.c b/samsung-ipc/modems/generic-xmm626/generic-xmm626_sec_modem.c new file mode 100644 index 0000000..b2dfc7c --- /dev/null +++ b/samsung-ipc/modems/generic-xmm626/generic-xmm626_sec_modem.c @@ -0,0 +1,258 @@ +/* + * 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 <errno.h> +#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.h" +#include "../xmm626/modem_prj.h" +#include "../xmm626/modem_link_device_hsic.h" +#include "../xmm626/xmm626.h" + +#include "generic-xmm626_sec_modem.h" + +int generic_xmm626_sec_modem_power(__attribute__((unused)) int device_fd, int power) +{ + int rc; + + rc = sysfs_value_write(GENERIC_XMM626_SEC_MODEM_POWER_PATH, !!power); + if (rc < 0) + return -1; + + return 0; +} + +int generic_xmm626_sec_modem_boot_power(int device_fd, int power) +{ + int rc; + + if (device_fd < 0) + return -1; + + rc = sysfs_value_write(GENERIC_XMM626_SEC_MODEM_POWER_PATH, !!power); + if (rc < 0) + return -1; + + return 0; +} + +int generic_xmm626_sec_modem_hci_power(int power) +{ + int ehci_rc, ohci_rc = -1; + + + /*ohci_rc = sysfs_value_write(XMM626_SEC_MODEM_OHCI_POWER_SYSFS, !!power); + if (ohci_rc >= 0) + usleep(50000); +*/ + + if (!!power) { + ohci_rc = sysfs_value_write(GENERIC_XMM626_SEC_MODEM_PDA_ACTIVE_SYSFS, 1); + if (sysfs_value_read(GENERIC_XMM626_SEC_HOSTWAKE_PATH)) { + ohci_rc |= sysfs_value_write(GENERIC_XMM626_SEC_MODEM_SLAVEWAKE_SYSFS, 0); + usleep(10000); + ohci_rc |= sysfs_value_write(GENERIC_XMM626_SEC_MODEM_SLAVEWAKE_SYSFS, 1); + } + ehci_rc = sysfs_value_write(GENERIC_XMM626_SEC_MODEM_EHCI_POWER_SYSFS, !!power); + if (ehci_rc >= 0) + usleep(50000); + + ohci_rc |= sysfs_value_write(GENERIC_XMM626_SEC_LINK_ACTIVE_PATH, 1); + } else { + ehci_rc = sysfs_value_write(GENERIC_XMM626_SEC_MODEM_EHCI_POWER_SYSFS, !!power); + if (ehci_rc >= 0) + usleep(50000); + + //ohci_rc = sysfs_value_write(GENERIC_XMM626_SEC_MODEM_PDA_ACTIVE_SYSFS, 0); + ohci_rc = sysfs_value_write(GENERIC_XMM626_SEC_LINK_ACTIVE_PATH, 0); + } + + + if (ohci_rc < 0) { + printf("ohci_rc < 0\n"); + } + if (ehci_rc < 0 && ohci_rc < 0) + return -1; + + return 0; +} + +int generic_xmm626_sec_modem_link_control_enable(__attribute__((unused)) int device_fd, + int enable) +{ + if (enable) { + } + return 0; +} + +int generic_xmm626_sec_modem_link_control_active(__attribute__((unused)) int device_fd, + int active) +{ + int rc; + + rc = sysfs_value_write(GENERIC_XMM626_SEC_LINK_ACTIVE_PATH, !!active); + if (rc < 0) + return -1; + + return 0; +} + +int generic_xmm626_sec_modem_link_connected_wait(__attribute__((unused)) int device_fd) +{ + int i; + + i = 0; + for (i = 0; i < 10; i++) { + + usleep(50000); + } + + return 0; +} + +int generic_xmm626_sec_modem_link_get_hostwake_wait( + __attribute__((unused)) int device_fd) +{ + int status; + int i; + + i = 0; + for (i = 0; i < 10; i++) { + /* !gpio_get_value (hostwake) */ + status = sysfs_value_read(GENERIC_XMM626_SEC_HOSTWAKE_PATH); + if (status == 0) /* invert: return true when hostwake is low */ + return 0; + + usleep(50000); + } + + return -1; +} + +int generic_xmm626_sec_modem_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->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 generic_xmm626_sec_modem_open(int type) +{ + int fd = -1; + int i = 0; + + while (fd < 0 && i < 30) { + i++; + usleep(30000); + switch (type) { + case IPC_CLIENT_TYPE_FMT: + printf("%s: %d %d\n", GENERIC_XMM626_SEC_MODEM_IPC0_DEVICE, fd, errno); + fd = open(GENERIC_XMM626_SEC_MODEM_IPC0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); + break; + case IPC_CLIENT_TYPE_RFS: + fd = open(GENERIC_XMM626_SEC_MODEM_RFS0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); + printf("%s: %d %d\n", GENERIC_XMM626_SEC_MODEM_RFS0_DEVICE, fd, errno); + break; + default: + printf("unknown type\n"); + return -1; + } + } + + return fd; +} + +int generic_xmm626_sec_modem_read(int fd, void *buffer, size_t length) +{ + int rc; + + if (fd < 0 || buffer == NULL || length <= 0) + return -1; + + rc = read(fd, buffer, length); + + return rc; +} + +int generic_xmm626_sec_modem_write(int fd, const void *buffer, size_t length) +{ + int rc; + + if (fd < 0 || buffer == NULL || length <= 0) + return -1; + + rc = write(fd, buffer, length); + + return rc; +} |