From 08b0c4868a5cdcc1973cb7fdc6c62f0a88a7a262 Mon Sep 17 00:00:00 2001 From: Simon Shields Date: Thu, 4 Jul 2019 18:46:47 +0200 Subject: Add generic device Signed-off-by: Simon Shields GNUtoo@cyberdimension.org: [rebase, fixes and cleanups] Signed-off-by: Denis 'GNUtoo' Carikli --- Android.mk | 1 + samsung-ipc/devices/Makefile.am | 2 + samsung-ipc/devices/generic/generic.c | 665 +++++++++++++++++++++ samsung-ipc/devices/generic/generic.h | 69 +++ samsung-ipc/devices/ipc_devices.c | 10 + samsung-ipc/devices/ipc_devices.h | 1 + .../xmm626/kernel/linux/xmm626_kernel_linux.c | 247 -------- .../xmm626/kernel/linux/xmm626_kernel_linux.h | 47 -- 8 files changed, 748 insertions(+), 294 deletions(-) create mode 100644 samsung-ipc/devices/generic/generic.c create mode 100644 samsung-ipc/devices/generic/generic.h delete mode 100644 samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.c delete mode 100644 samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.h 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 + * Copyright (C) 2013-2014 Paul Kocialkowski + * + * 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 . + */ +#define _GNU_SOURCE /* See feature_test_macros(7) */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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/devices/generic/generic.h b/samsung-ipc/devices/generic/generic.h new file mode 100644 index 0000000..02412e6 --- /dev/null +++ b/samsung-ipc/devices/generic/generic.h @@ -0,0 +1,69 @@ +/* + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2013-2014 Paul Kocialkowski + * + * 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 . + */ + +#ifndef __GENERIC_H__ +#define __GENERIC_H__ + +#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_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" +#define XMM626_KERNEL_LINUX_LINK_ACTIVE_PATH "/sys/devices/platform/xmm6262/link_active" +#define XMM626_KERNEL_LINUX_POWER_PATH "/sys/devices/platform/xmm6262/modem_power" +#define XMM626_KERNEL_LINUX_PDA_ACTIVE_SYSFS "/sys/devices/platform/xmm6262/pda_active" +#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_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); +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 /* __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 - * Copyright (C) 2013-2014 Paul Kocialkowski - * - * 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 . - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -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 diff --git a/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.h b/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.h deleted file mode 100644 index 2b1d189..0000000 --- a/samsung-ipc/modems/xmm626/kernel/linux/xmm626_kernel_linux.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of libsamsung-ipc. - * - * Copyright (C) 2013-2014 Paul Kocialkowski - * - * 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 . - */ - -#ifndef __XMM626_KERNEL_LINUX_H__ -#define __XMM626_KERNEL_LINUX_H__ - -#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_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" -#define XMM626_KERNEL_LINUX_LINK_ACTIVE_PATH "/sys/devices/platform/xmm6262/link_active" -#define XMM626_KERNEL_LINUX_POWER_PATH "/sys/devices/platform/xmm6262/modem_power" -#define XMM626_KERNEL_LINUX_PDA_ACTIVE_SYSFS "/sys/devices/platform/xmm6262/pda_active" -#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" - -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); -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__ */ - -// vim:ts=4:sw=4:expandtab -- cgit v1.2.3