aboutsummaryrefslogtreecommitdiffstats
path: root/samsung-ipc/modems/generic-xmm626/generic-xmm626_sec_modem.c
diff options
context:
space:
mode:
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.c258
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;
+}