aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Shields <simon@lineageos.org>2019-07-04 18:46:47 +0200
committerDenis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>2021-03-01 16:37:33 +0100
commit08b0c4868a5cdcc1973cb7fdc6c62f0a88a7a262 (patch)
tree77bc1581c7feb3b3ec158a6c1138023c9c4c3169
parentff5e990d2031ccf69b478a4209405083ab90e4c7 (diff)
downloadhardware_replicant_libsamsung-ipc-08b0c4868a5cdcc1973cb7fdc6c62f0a88a7a262.tar.gz
hardware_replicant_libsamsung-ipc-08b0c4868a5cdcc1973cb7fdc6c62f0a88a7a262.tar.bz2
hardware_replicant_libsamsung-ipc-08b0c4868a5cdcc1973cb7fdc6c62f0a88a7a262.zip
Add generic device
Signed-off-by: Simon Shields <simon@lineageos.org> GNUtoo@cyberdimension.org: [rebase, fixes and cleanups] Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
-rw-r--r--Android.mk1
-rw-r--r--samsung-ipc/devices/Makefile.am2
-rw-r--r--samsung-ipc/devices/generic/generic.c665
-rw-r--r--samsung-ipc/devices/generic/generic.h (renamed from samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.h)36
-rw-r--r--samsung-ipc/devices/ipc_devices.c10
-rw-r--r--samsung-ipc/devices/ipc_devices.h1
-rw-r--r--samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.c247
7 files changed, 708 insertions, 254 deletions
diff --git a/Android.mk b/Android.mk
index c0a5d35..3b08853 100644
--- a/Android.mk
+++ b/Android.mk
@@ -70,6 +70,7 @@ libsamsung_ipc_local_src_files := \
samsung-ipc/devices/aries/aries.c \
samsung-ipc/devices/crespo/crespo.c \
samsung-ipc/devices/galaxys2/galaxys2.c \
+ samsung-ipc/devices/generic/generic.c \
samsung-ipc/devices/herolte/herolte.c \
samsung-ipc/devices/i9300/i9300.c \
samsung-ipc/devices/maguro/maguro.c \
diff --git a/samsung-ipc/devices/Makefile.am b/samsung-ipc/devices/Makefile.am
index 8257be3..ad3c7ba 100644
--- a/samsung-ipc/devices/Makefile.am
+++ b/samsung-ipc/devices/Makefile.am
@@ -22,4 +22,6 @@ libsamsung_ipc_la_SOURCES += \
devices/n5100/n5100.h \
devices/herolte/herolte.c \
devices/herolte/herolte.h \
+ devices/generic/generic.c \
+ devices/generic/generic.h \
$(NULL)
diff --git a/samsung-ipc/devices/generic/generic.c b/samsung-ipc/devices/generic/generic.c
new file mode 100644
index 0000000..dd1466c
--- /dev/null
+++ b/samsung-ipc/devices/generic/generic.c
@@ -0,0 +1,665 @@
+/*
+ * 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 /* See feature_test_macros(7) */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#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 "partitions/android/android.h"
+
+#include "generic.h"
+
+int xmm626_kernel_linux_modem_power(__attribute__((unused)) int device_fd,
+ int power)
+{
+ int rc;
+
+ rc = sysfs_value_write(XMM626_KERNEL_LINUX_POWER_PATH, !!power);
+ if (rc == -1)
+ return rc;
+
+ return 0;
+}
+
+int xmm626_kernel_linux_modem_hci_power(int power)
+{
+ int ehci_rc, ohci_rc = -1;
+
+ if (!!power) {
+ ohci_rc = sysfs_value_write(
+ XMM626_KERNEL_LINUX_PDA_ACTIVE_SYSFS, 1);
+ if (sysfs_value_read(XMM626_KERNEL_LINUX_HOSTWAKE_PATH)) {
+ ohci_rc |= sysfs_value_write(
+ XMM626_KERNEL_LINUX_SLAVEWAKE_SYSFS, 0);
+ usleep(10000);
+ ohci_rc |= sysfs_value_write(
+ XMM626_KERNEL_LINUX_SLAVEWAKE_SYSFS, 1);
+ }
+ ehci_rc = sysfs_value_write(
+ XMM626_KERNEL_LINUX_EHCI_POWER_SYSFS, !!power);
+ if (ehci_rc >= 0)
+ usleep(50000);
+
+ ohci_rc |= sysfs_value_write(
+ XMM626_KERNEL_LINUX_LINK_ACTIVE_PATH, 1);
+ } else {
+ ehci_rc = sysfs_value_write(
+ XMM626_KERNEL_LINUX_EHCI_POWER_SYSFS, !!power);
+ if (ehci_rc >= 0)
+ usleep(50000);
+
+ ohci_rc = sysfs_value_write(
+ XMM626_KERNEL_LINUX_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 xmm626_kernel_linux_modem_link_control_enable(
+ __attribute__((unused)) int device_fd, int enable)
+{
+ if (enable) {
+ }
+ return 0;
+}
+
+int xmm626_kernel_linux_modem_link_control_active(
+ __attribute__((unused)) int device_fd, int active)
+{
+ int rc;
+
+ rc = sysfs_value_write(XMM626_KERNEL_LINUX_LINK_ACTIVE_PATH, !!active);
+ if (rc < 0)
+ return -1;
+
+ return 0;
+}
+
+int xmm626_kernel_linux_modem_link_connected_wait(
+ __attribute__((unused)) int device_fd)
+{
+ int i;
+
+ i = 0;
+ for (i = 0; i < 10; i++) {
+
+ usleep(50000);
+ }
+
+ return 0;
+}
+
+int xmm626_kernel_linux_modem_link_get_hostwake_wait(
+ __attribute__((unused)) int device_fd)
+{
+ int i;
+
+ i = 0;
+ for (i = 0; i < 10; i++) {
+ /* TODO: read host wake GPIOs */
+ usleep(500000);
+ }
+
+ return 0;
+}
+
+int xmm626_kernel_linux_modem_open(int type)
+{
+ int fd = -2;
+ int i = 0;
+ int err = 0;
+
+ printf("ENTER %s\n", __func__);
+ while (fd < 0 && i < 30) {
+ i++;
+ usleep(30000);
+ printf("%s: type: %d\n", __func__, type);
+ switch (type) {
+ case IPC_CLIENT_TYPE_FMT:
+ err = 0;
+ fd = open(XMM626_KERNEL_LINUX_IPC0_DEVICE,
+ O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (fd < 0) {
+ err = errno;
+ printf("%s: open(%s, "
+ "O_RDWR | O_NOCTTY | O_NONBLOCK) => "
+ "%d errno: %d\n",
+ __func__,
+ XMM626_KERNEL_LINUX_IPC0_DEVICE, fd,
+ err);
+ }
+
+ break;
+ case IPC_CLIENT_TYPE_RFS:
+ err = 0;
+ fd = open(XMM626_KERNEL_LINUX_RFS0_DEVICE,
+ O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (fd < 0) {
+ err = errno;
+ printf("%s: open(%s, "
+ "O_RDWR | O_NOCTTY | O_NONBLOCK) => "
+ "%d errno: %d\n",
+ __func__,
+ XMM626_KERNEL_LINUX_RFS0_DEVICE,
+ fd, err);
+ }
+ break;
+ default:
+ printf("%s: unknown type\n", __func__);
+ return -1;
+ }
+ }
+
+ return fd;
+}
+
+int xmm626_kernel_linux_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 xmm626_kernel_linux_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;
+}
+
+char *xmm626_kernel_linux_modem_gprs_get_iface(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 generic_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;
+}
+
+int generic_boot(struct ipc_client *client)
+{
+ void *modem_image_data = NULL;
+ int modem_image_fd = -1;
+ int modem_boot_fd = -1;
+ int modem_link_fd = -1;
+ unsigned char *p;
+ char *path;
+ int rc;
+ int unused = 0;
+
+ if (client == NULL)
+ return -1;
+
+ ipc_client_log(client, "Starting generic modem boot");
+
+ modem_image_fd = open_android_modem_partition_by_name(client, "RADIO",
+ &path);
+ if (modem_image_fd == -1) {
+ rc = errno;
+ ipc_client_log(client,
+ "%s: open_android_modem_partition_by_name: "
+ "failed to open %s with error %d: %s",
+ __func__, path, rc, strerror(rc));
+ goto error;
+ }
+
+ modem_image_data = mmap(0, GENERIC_MODEM_IMAGE_SIZE, PROT_READ,
+ MAP_SHARED, modem_image_fd, 0);
+ if (modem_image_data == NULL ||
+ modem_image_data == (void *) 0xffffffff) {
+ ipc_client_log(client,
+ "Mapping modem image data to memory failed");
+ goto error;
+ }
+ ipc_client_log(client, "Mapped modem image data to memory");
+
+ rc = xmm626_kernel_linux_modem_power(unused, 0);
+ if (rc < 0) {
+ ipc_client_log(client,
+ "xmm626_kernel_linux_modem_power: "
+ "Turning the modem off failed with error %d",
+ rc);
+ goto error;
+ }
+ rc = xmm626_kernel_linux_modem_hci_power(0);
+ if (rc < 0) {
+ ipc_client_log(client,
+ "xmm626_kernel_linux_modem_hci_power: "
+ "Turning the modem off failed");
+ goto error;
+ }
+ ipc_client_log(client, "Turned the modem off");
+
+ rc = xmm626_kernel_linux_modem_power(unused, 1);
+ printf("%s: xmm626_kernel_linux_modem_power(NULL, 1) = %d\n",
+ __func__, rc);
+ if (rc < 0) {
+ ipc_client_log(client,
+ "xmm626_kernel_linux_modem_power "
+ "failed with error %d",
+ rc);
+ }
+
+ rc = xmm626_kernel_linux_modem_hci_power(1);
+ printf("%s: xmm626_kernel_linux_modem_hci_power(1) = %d\n",
+ __func__, rc);
+ if (rc < 0) {
+ ipc_client_log(client,
+ "xmm626_kernel_linux_modem_hci_power on failed");
+ goto error;
+ }
+ ipc_client_log(client, "Turned the modem on");
+
+ system("lsusb");
+
+ rc = 0;
+ do {
+ modem_boot_fd = open(XMM626_KERNEL_LINUX_BOOT0_DEVICE,
+ O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (modem_boot_fd >= 0) {
+ break;
+ }
+ usleep(5000);
+ rc++;
+ } while (rc < 10000);
+ if (modem_boot_fd < 0) {
+ ipc_client_log(client, "Failed to open boot device");
+ goto error;
+ }
+ ipc_client_log(client, "Opened modem boot device");
+ system("lsusb");
+
+ p = (unsigned char *) modem_image_data + GENERIC_PSI_OFFSET;
+
+ rc = xmm626_hsic_psi_send(client, modem_boot_fd, (void *) p,
+ GENERIC_PSI_SIZE);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM626 HSIC PSI failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC PSI");
+
+ p = (unsigned char *) modem_image_data + GENERIC_EBL_OFFSET;
+
+ rc = xmm626_hsic_ebl_send(client, modem_boot_fd, (void *) p,
+ GENERIC_EBL_SIZE);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM626 HSIC EBL failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC EBL");
+
+ rc = xmm626_hsic_port_config_send(client, modem_boot_fd);
+ if (rc < 0) {
+ ipc_client_log(client,
+ "Sending XMM626 HSIC port config failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC port config");
+ system("lsusb");
+
+ p = (unsigned char *) modem_image_data + GENERIC_SEC_START_OFFSET;
+
+ rc = xmm626_hsic_sec_start_send(client, modem_boot_fd, (void *) p,
+ GENERIC_SEC_START_SIZE);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM626 HSIC SEC start failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC SEC start");
+
+ p = (unsigned char *) modem_image_data + GENERIC_FIRMWARE_OFFSET;
+
+ rc = xmm626_hsic_firmware_send(client, modem_boot_fd, (void *) p,
+ GENERIC_FIRMWARE_SIZE);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM626 HSIC firmware failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC firmware");
+ system("lsusb");
+
+ rc = xmm626_hsic_nv_data_send(client, modem_boot_fd);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM626 HSIC nv_data failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC nv_data");
+
+ rc = xmm626_hsic_sec_end_send(client, modem_boot_fd);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM626 HSIC SEC end failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC SEC end");
+ system("lsusb");
+
+ rc = xmm626_hsic_hw_reset_send(client, modem_boot_fd);
+ if (rc < 0) {
+ ipc_client_log(client, "Sending XMM626 HSIC HW reset failed");
+ goto error;
+ }
+ ipc_client_log(client, "Sent XMM626 HSIC HW reset");
+ system("lsusb");
+
+ usleep(300000);
+
+ rc = xmm626_kernel_linux_modem_link_get_hostwake_wait(modem_link_fd);
+ if (rc < 0) {
+ ipc_client_log(client, "Waiting for host wake failed");
+ }
+ ipc_client_log(client, "Waited for host wake");
+ system("lsusb");
+
+ rc = xmm626_kernel_linux_modem_hci_power(0);
+
+ if (rc < 0) {
+ ipc_client_log(client, "Turning the modem off failed");
+ goto error;
+ }
+ ipc_client_log(client, "Turned off the modem");
+ system("lsusb");
+
+ rc = xmm626_kernel_linux_modem_link_get_hostwake_wait(modem_link_fd);
+ if (rc < 0) {
+ ipc_client_log(client, "Waiting for host wake failed");
+ }
+ ipc_client_log(client, "Waited for host wake");
+ system("lsusb");
+
+ rc = xmm626_kernel_linux_modem_hci_power(1);
+ if (rc < 0) {
+ ipc_client_log(client, "Turning the modem on failed");
+ goto error;
+ }
+ ipc_client_log(client, "Turned the modem on");
+ system("lsusb");
+ ipc_client_log(client, "Wait for the modem to come up again",
+ __func__);
+ sleep(10);
+
+ system("lsusb");
+
+ ipc_client_log(client, "%s complete", __func__);
+ sleep(7);
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+complete:
+ if (modem_image_data != NULL)
+ munmap(modem_image_data, GENERIC_MODEM_IMAGE_SIZE);
+
+ if (modem_image_fd >= 0)
+ close(modem_image_fd);
+
+ if (modem_boot_fd >= 0)
+ close(modem_boot_fd);
+
+ if (modem_link_fd >= 0)
+ close(modem_link_fd);
+
+ return rc;
+}
+
+int generic_open(__attribute__((unused)) struct ipc_client *client, void *data,
+ int type)
+{
+ struct generic_transport_data *transport_data;
+
+ if (data == NULL)
+ return -1;
+
+ transport_data = (struct generic_transport_data *) data;
+
+ transport_data->fd = xmm626_kernel_linux_modem_open(type);
+ if (transport_data->fd < 0)
+ return -1;
+
+ return 0;
+}
+
+int generic_close(__attribute__((unused)) struct ipc_client *client, void *data)
+{
+ struct generic_transport_data *transport_data;
+
+ if (data == NULL)
+ return -1;
+
+ transport_data = (struct generic_transport_data *) data;
+
+ xmm626_kernel_smdk4412_close(client, transport_data->fd);
+ transport_data->fd = -1;
+
+ return 0;
+}
+
+int generic_read(__attribute__((unused)) struct ipc_client *client,
+ void *data, void *buffer, size_t length)
+{
+ struct generic_transport_data *transport_data;
+ int rc;
+
+ if (data == NULL)
+ return -1;
+
+ transport_data = (struct generic_transport_data *) data;
+
+ rc = xmm626_kernel_linux_modem_read(transport_data->fd, buffer, length);
+
+ return rc;
+}
+
+int generic_write(__attribute__((unused)) struct ipc_client *client,
+ void *data, const void *buffer, size_t length)
+{
+ struct generic_transport_data *transport_data;
+ int rc;
+
+ if (data == NULL)
+ return -1;
+
+ transport_data = (struct generic_transport_data *) data;
+
+ rc = xmm626_kernel_linux_modem_write(transport_data->fd,
+ buffer, length);
+
+ return rc;
+}
+
+int generic_poll(__attribute__((unused)) struct ipc_client *client,
+ void *data, __attribute__((unused)) struct ipc_poll_fds *fds,
+ __attribute__((unused)) struct timeval *timeout)
+{
+ struct generic_transport_data *transport_data;
+ int rc;
+ struct pollfd fd;
+
+ if (data == NULL)
+ return -1;
+
+ transport_data = (struct generic_transport_data *) data;
+
+ fd.fd = transport_data->fd;
+ fd.events = POLLRDNORM | POLLIN;
+
+ rc = poll(&fd, 1, -1);
+
+ return rc - 1;
+}
+
+int generic_power_on(__attribute__((unused)) struct ipc_client *client,
+ __attribute__((unused)) void *data)
+{
+ return 0;
+}
+
+int generic_power_off(__attribute__((unused)) struct ipc_client *client,
+ __attribute__((unused)) void *data)
+{
+ int fd;
+ int rc;
+
+ fd = open(XMM626_KERNEL_LINUX_BOOT0_DEVICE,
+ O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (fd < 0)
+ return -1;
+
+ rc = xmm626_kernel_linux_modem_power(fd, 0);
+
+ close(fd);
+
+ if (rc < 0)
+ return -1;
+
+ return 0;
+}
+
+int generic_gprs_activate(__attribute__((unused)) struct ipc_client *client,
+ __attribute__((unused)) void *data,
+ __attribute__((unused)) unsigned int cid)
+{
+ return 0;
+}
+
+int generic_gprs_deactivate(__attribute__((unused)) struct ipc_client *client,
+ __attribute__((unused)) void *data,
+ __attribute__((unused)) unsigned int cid)
+{
+ return 0;
+}
+
+int generic_data_create(__attribute__((unused)) struct ipc_client *client,
+ void **transport_data,
+ __attribute__((unused)) void **power_data,
+ __attribute__((unused)) void **gprs_data)
+{
+ if (transport_data == NULL)
+ return -1;
+
+ *transport_data = calloc(1, sizeof(struct generic_transport_data));
+
+ return 0;
+}
+
+int generic_data_destroy(__attribute__((unused)) struct ipc_client *client,
+ void *transport_data,
+ __attribute__((unused)) void *power_data,
+ __attribute__((unused)) void *gprs_data)
+{
+ if (transport_data == NULL)
+ return -1;
+
+ free(transport_data);
+
+ return 0;
+}
+
+struct ipc_client_ops generic_fmt_ops = {
+ .boot = generic_boot,
+ .send = xmm626_kernel_smdk4412_fmt_send,
+ .recv = xmm626_kernel_smdk4412_fmt_recv,
+};
+
+struct ipc_client_ops generic_rfs_ops = {
+ .boot = NULL,
+ .send = xmm626_kernel_smdk4412_rfs_send,
+ .recv = xmm626_kernel_smdk4412_rfs_recv,
+};
+
+struct ipc_client_handlers generic_handlers = {
+ .read = generic_read,
+ .write = generic_write,
+ .open = generic_open,
+ .close = generic_close,
+ .poll = generic_poll,
+ .transport_data = NULL,
+ .power_on = generic_power_on,
+ .power_off = generic_power_off,
+ .power_data = NULL,
+ .gprs_activate = generic_gprs_activate,
+ .gprs_deactivate = generic_gprs_deactivate,
+ .gprs_data = NULL,
+ .data_create = generic_data_create,
+ .data_destroy = generic_data_destroy,
+};
+
+struct ipc_client_gprs_specs generic_gprs_specs = {
+ .gprs_get_iface = xmm626_kernel_smdk4412_gprs_get_iface,
+ .gprs_get_capabilities = generic_gprs_get_capabilities,
+};
+
+struct ipc_client_nv_data_specs generic_nv_data_specs = {
+ .nv_data_path = XMM626_NV_DATA_PATH,
+ .nv_data_md5_path = XMM626_NV_DATA_MD5_PATH,
+ .nv_data_backup_path = XMM626_NV_DATA_BACKUP_PATH,
+ .nv_data_backup_md5_path = XMM626_NV_DATA_BACKUP_MD5_PATH,
+ .nv_data_secret = XMM626_NV_DATA_SECRET,
+ .nv_data_size = XMM626_NV_DATA_SIZE,
+ .nv_data_chunk_size = XMM626_NV_DATA_CHUNK_SIZE,
+};
+
+// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.h b/samsung-ipc/devices/generic/generic.h
index 2b1d189..02412e6 100644
--- a/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.h
+++ b/samsung-ipc/devices/generic/generic.h
@@ -17,13 +17,25 @@
* along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __XMM626_KERNEL_LINUX_H__
-#define __XMM626_KERNEL_LINUX_H__
+#ifndef __GENERIC_H__
+#define __GENERIC_H__
-#define XMM626_KERNEL_LINUX_BOOT0_DEVICE "/dev/xmm6262_boot0"
+#define GENERIC_MODEM_IMAGE_SIZE 0x1000000
+#define GENERIC_PSI_OFFSET 0x0001000
+#define GENERIC_PSI_SIZE 0x000E000
+#define GENERIC_EBL_OFFSET 0x000F000
+#define GENERIC_EBL_SIZE 0x0019000
+#define GENERIC_SEC_START_OFFSET 0x09FF800
+#define GENERIC_SEC_START_SIZE 0x0000800
+#define GENERIC_FIRMWARE_OFFSET 0x0028000
+#define GENERIC_FIRMWARE_SIZE 0x09D7800
+#define GENERIC_NV_DATA_OFFSET 0x0A00000
+#define GENERIC_NV_DATA_SIZE 0x0200000
+
+#define XMM626_KERNEL_LINUX_BOOT0_DEVICE "/dev/xmm6262_boot0"
#define XMM626_KERNEL_LINUX_BOOT1_DEVICE "/dev/umts_boot1"
-#define XMM626_KERNEL_LINUX_IPC0_DEVICE "/dev/umts_ipc"
-#define XMM626_KERNEL_LINUX_RFS0_DEVICE "/dev/umts_rfs"
+#define XMM626_KERNEL_LINUX_IPC0_DEVICE "/dev/umts_ipc"
+#define XMM626_KERNEL_LINUX_RFS0_DEVICE "/dev/umts_rfs"
#define XMM626_KERNEL_LINUX_LINK_PM_DEVICE "/dev/link_pm"
#define XMM626_KERNEL_LINUX_EHCI_POWER_SYSFS "/sys/devices/platform/soc/12580000.ehci/ehci_power"
#define XMM626_KERNEL_LINUX_HOSTWAKE_PATH "/sys/devices/platform/xmm6262/hostwake"
@@ -33,8 +45,18 @@
#define XMM626_KERNEL_LINUX_SLAVEWAKE_SYSFS "/sys/devices/platform/xmm6262/slavewake"
//#define XMM626_KERNEL_LINUX_OHCI_POWER_SYSFS "/sys/devices/platform/s5p-ohci/ohci_power"
+
+struct generic_transport_data {
+ int fd;
+};
+
+extern struct ipc_client_ops generic_fmt_ops;
+extern struct ipc_client_ops generic_rfs_ops;
+extern struct ipc_client_handlers generic_handlers;
+extern struct ipc_client_gprs_specs generic_gprs_specs;
+extern struct ipc_client_nv_data_specs generic_nv_data_specs;
+
int xmm626_kernel_linux_modem_power(__attribute__((unused)) int device_fd, int power);
-int xmm626_kernel_linux_modem_boot_power(int device_fd, int power);
int xmm626_kernel_linux_modem_hci_power(int power);
int xmm626_kernel_linux_modem_link_connected_wait(__attribute__((unused)) int device_fd);
int xmm626_kernel_linux_modem_open(int type);
@@ -42,6 +64,6 @@ int xmm626_kernel_linux_modem_read(int fd, void *buffer, size_t length);
int xmm626_kernel_linux_modem_write(int fd, const void *buffer, size_t length);
int xmm626_kernel_linux_modem_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities);
-#endif /* __XMM626_KERNEL_LINUX_H__ */
+#endif /* __GENERIC_H__ */
// vim:ts=4:sw=4:expandtab
diff --git a/samsung-ipc/devices/ipc_devices.c b/samsung-ipc/devices/ipc_devices.c
index a0fe955..f30cc84 100644
--- a/samsung-ipc/devices/ipc_devices.c
+++ b/samsung-ipc/devices/ipc_devices.c
@@ -164,6 +164,16 @@ struct ipc_device_desc ipc_devices[] = {
.gprs_specs = &herolte_gprs_specs,
.nv_data_specs = &herolte_nv_data_specs,
},
+ {
+ .name = NULL,
+ .board_name = "samsung exynos (flattened device tree)",
+ .kernel_version = NULL,
+ .fmt_ops = &generic_fmt_ops,
+ .rfs_ops = &generic_rfs_ops,
+ .handlers = &generic_handlers,
+ .gprs_specs = &generic_gprs_specs,
+ .nv_data_specs = &generic_nv_data_specs,
+ },
};
unsigned int ipc_devices_count = sizeof(ipc_devices) /
diff --git a/samsung-ipc/devices/ipc_devices.h b/samsung-ipc/devices/ipc_devices.h
index 8160ee1..1226774 100644
--- a/samsung-ipc/devices/ipc_devices.h
+++ b/samsung-ipc/devices/ipc_devices.h
@@ -23,6 +23,7 @@
#include "devices/aries/aries.h"
#include "devices/crespo/crespo.h"
#include "devices/galaxys2/galaxys2.h"
+#include "devices/generic/generic.h"
#include "devices/herolte/herolte.h"
#include "devices/i9300/i9300.h"
#include "devices/maguro/maguro.h"
diff --git a/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.c b/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.c
deleted file mode 100644
index 57032e1..0000000
--- a/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * 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 <modem.h>
-#include <modem_prj.h>
-#include <modem_link_device_hsic.h>
-
-#include <xmm626.h>
-#include <xmm626_kernel_linux.h>
-#include <xmm626_sec_modem.h>
-
-int xmm626_kernel_linux_modem_power(__attribute__((unused)) int device_fd, int power)
-{
- int rc;
-
- rc = sysfs_value_write(XMM626_KERNEL_LINUX_POWER_PATH, !!power);
- if (rc < 0)
- return -99;
-
- return 0;
-}
-
-int xmm626_kernel_linux_modem_boot_power(int device_fd, int power)
-{
- int rc;
-
- if (device_fd < 0)
- return -1;
-
- rc = sysfs_value_write(XMM626_KERNEL_LINUX_POWER_PATH, !!power);
- if (rc < 0)
- return -1;
-
- return 0;
-}
-
-int xmm626_kernel_linux_modem_hci_power(int power)
-{
- int ehci_rc, ohci_rc = -1;
-
-
- /*ohci_rc = sysfs_value_write(XMM626_KERNEL_LINUX_OHCI_POWER_SYSFS, !!power);
- if (ohci_rc >= 0)
- usleep(50000);
-*/
-
- if (!!power) {
- ohci_rc = sysfs_value_write(XMM626_KERNEL_LINUX_PDA_ACTIVE_SYSFS, 1);
- if (sysfs_value_read(XMM626_KERNEL_LINUX_HOSTWAKE_PATH)) {
- ohci_rc |= sysfs_value_write(XMM626_KERNEL_LINUX_SLAVEWAKE_SYSFS, 0);
- usleep(10000);
- ohci_rc |= sysfs_value_write(XMM626_KERNEL_LINUX_SLAVEWAKE_SYSFS, 1);
- }
- ehci_rc = sysfs_value_write(XMM626_KERNEL_LINUX_EHCI_POWER_SYSFS, !!power);
- if (ehci_rc >= 0)
- usleep(50000);
-
- ohci_rc |= sysfs_value_write(XMM626_KERNEL_LINUX_LINK_ACTIVE_PATH, 1);
- } else {
- ehci_rc = sysfs_value_write(XMM626_KERNEL_LINUX_EHCI_POWER_SYSFS, !!power);
- if (ehci_rc >= 0)
- usleep(50000);
-
- //ohci_rc = sysfs_value_write(XMM626_KERNEL_LINUX_PDA_ACTIVE_SYSFS, 0);
- ohci_rc = sysfs_value_write(XMM626_KERNEL_LINUX_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 xmm626_kernel_linux_modem_link_control_enable(__attribute__((unused)) int device_fd,
- int enable)
-{
- if (enable) {
- }
- return 0;
-}
-
-int xmm626_kernel_linux_modem_link_control_active(__attribute__((unused)) int device_fd,
- int active)
-{
- int rc;
-
- rc = sysfs_value_write(XMM626_KERNEL_LINUX_LINK_ACTIVE_PATH, !!active);
- if (rc < 0)
- return -1;
-
- return 0;
-}
-
-int xmm626_kernel_linux_modem_link_connected_wait(__attribute__((unused)) int device_fd)
-{
- int i;
-
- i = 0;
- for (i = 0; i < 10; i++) {
-
- usleep(50000);
- }
-
- return 0;
-}
-
-int xmm626_kernel_linux_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(XMM626_KERNEL_LINUX_HOSTWAKE_PATH);
- printf("%s: i=%d read(%s) => status: %d\n", __FUNCTION__, i, XMM626_KERNEL_LINUX_HOSTWAKE_PATH, status);
-// if (status == 0) /* invert: return true when hostwake is low */
- // return 0;
-
- usleep(500000);
- }
-
- return 0;
-}
-
-int xmm626_kernel_linux_modem_open(int type)
-{
- int fd = -2;
- int i = 0;
- int err = 0;
-
- printf("ENTER %s\n", __FUNCTION__);
- while (fd < 0 && i < 30) {
- i++;
- usleep(30000);
- printf("%s: type: %d\n", __FUNCTION__, type);
- switch (type) {
- case IPC_CLIENT_TYPE_FMT:
- err = 0;
- fd = open(XMM626_KERNEL_LINUX_IPC0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
- if (fd < 0) {
- err = errno;
- printf("%s: open(%s, O_RDWR | O_NOCTTY | O_NONBLOCK) => %d errno: %d\n",
- __FUNCTION__, XMM626_KERNEL_LINUX_IPC0_DEVICE, fd, err);
- }
-
- break;
- case IPC_CLIENT_TYPE_RFS:
- err = 0;
- fd = open(XMM626_KERNEL_LINUX_RFS0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
- if (fd < 0) {
- err = errno;
- printf("%s: open(%s, O_RDWR | O_NOCTTY | O_NONBLOCK) => %d errno: %d\n",
- __FUNCTION__, XMM626_KERNEL_LINUX_RFS0_DEVICE, fd, err);
- }
- break;
- default:
- printf("%s: unknown type\n", __FUNCTION__);
- return -1;
- }
- }
-
- return fd;
-}
-
-int xmm626_kernel_linux_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 xmm626_kernel_linux_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;
-}
-
-char *xmm626_kernel_linux_modem_gprs_get_iface(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_linux_modem_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities)
-{
- if (capabilities == NULL)
- return -1;
-
- capabilities->cid_count = XMM626_SEC_MODEM_GPRS_IFACE_COUNT;
-
- return 0;
-}
-
-// vim:ts=4:sw=4:expandtab