From b1feb0ae7e349118409101de5bcbdca441e363ae Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Wed, 3 Jul 2013 22:20:54 +0200 Subject: Samsung Galaxy S3 (galaxys3) support Change-Id: If37a94d07129c37b8e4f647b479552dc60de90a3 Signed-off-by: Paul Kocialkowski --- Android.mk | 25 +- samsung-ipc/Makefile.am | 2 + samsung-ipc/device/galaxys3/galaxys3_ipc.c | 411 +++++++++++++++++++++++++++++ samsung-ipc/device/galaxys3/galaxys3_ipc.h | 49 ++++ samsung-ipc/ipc_devices.c | 24 +- samsung-ipc/ipc_devices.h | 1 + 6 files changed, 502 insertions(+), 10 deletions(-) create mode 100644 samsung-ipc/device/galaxys3/galaxys3_ipc.c create mode 100644 samsung-ipc/device/galaxys3/galaxys3_ipc.h diff --git a/Android.mk b/Android.mk index 9b5cf17..514240b 100644 --- a/Android.mk +++ b/Android.mk @@ -14,10 +14,6 @@ ifeq ($(TARGET_DEVICE),crespo) board_name := herring endif -ifeq ($(TARGET_DEVICE),galaxys2) - board_name := smdk4210 -endif - ifeq ($(TARGET_DEVICE),galaxysmtd) board_name := aries endif @@ -26,10 +22,6 @@ ifeq ($(TARGET_DEVICE),galaxytab) board_name := gt-p1000 endif -ifeq ($(TARGET_DEVICE),spica) - board_name := i5700 -endif - ifeq ($(TARGET_DEVICE),maguro) board_name := tuna endif @@ -42,6 +34,22 @@ ifeq ($(TARGET_DEVICE),p3100) board_name := espresso endif +ifeq ($(TARGET_DEVICE),i9100) + board_name := smdk4210 +endif + +ifeq ($(TARGET_DEVICE),galaxys2) + board_name := smdk4210 +endif + +ifeq ($(TARGET_DEVICE),i9300) + board_name := smdk4x12 +endif + +ifeq ($(TARGET_DEVICE),galaxys3) + board_name := smdk4x12 +endif + ifeq ($(DEBUG),true) LOCAL_CFLAGS += -DDEBUG LOCAL_CFLAGS += -DLOG_STDOUT @@ -68,6 +76,7 @@ samsung-ipc_files := \ samsung-ipc/device/crespo/crespo_ipc.c \ samsung-ipc/device/aries/aries_ipc.c \ samsung-ipc/device/galaxys2/galaxys2_ipc.c \ + samsung-ipc/device/galaxys3/galaxys3_ipc.c \ samsung-ipc/device/maguro/maguro_ipc.c \ samsung-ipc/device/piranha/piranha_ipc.c diff --git a/samsung-ipc/Makefile.am b/samsung-ipc/Makefile.am index 8145ba2..4bd0409 100644 --- a/samsung-ipc/Makefile.am +++ b/samsung-ipc/Makefile.am @@ -55,6 +55,8 @@ libsamsung_ipc_la_SOURCES = \ device/aries/phonet.h \ device/galaxys2/galaxys2_ipc.c \ device/galaxys2/galaxys2_ipc.h \ + device/galaxys3/galaxys3_ipc.c \ + device/galaxys3/galaxys3_ipc.h \ device/maguro/maguro_ipc.c \ device/maguro/maguro_ipc.h \ device/piranha/piranha_ipc.c \ diff --git a/samsung-ipc/device/galaxys3/galaxys3_ipc.c b/samsung-ipc/device/galaxys3/galaxys3_ipc.c new file mode 100644 index 0000000..39da41b --- /dev/null +++ b/samsung-ipc/device/galaxys3/galaxys3_ipc.c @@ -0,0 +1,411 @@ +/* + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2013 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 . + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "xmm6260.h" +#include "xmm6260_hsic.h" +#include "xmm6260_sec_modem.h" +#include "galaxys3_ipc.h" + +int galaxys3_ipc_bootstrap(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; + int rc; + + if (client == NULL) + return -1; + + ipc_client_log(client, "Starting galaxys3 modem bootstrap"); + + modem_image_fd = open(GALAXYS3_MODEM_IMAGE_DEVICE, O_RDONLY); + if (modem_image_fd < 0) { + ipc_client_log(client, "Opening modem image device failed"); + goto error; + } + ipc_client_log(client, "Opened modem image device"); + + modem_image_data = mmap(0, GALAXYS3_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"); + + modem_boot_fd = open(XMM6260_SEC_MODEM_BOOT0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (modem_boot_fd < 0) { + ipc_client_log(client, "Opening modem boot device failed"); + goto error; + } + ipc_client_log(client, "Opened modem boot device"); + + modem_link_fd = open(XMM6260_SEC_MODEM_LINK_PM_DEVICE, O_RDWR); + if (modem_link_fd < 0) { + ipc_client_log(client, "Opening modem link device failed"); + goto error; + } + ipc_client_log(client, "Opened modem link device"); + + rc = xmm6260_sec_modem_hci_power(0); + if (rc < 0) { + ipc_client_log(client, "Turning the modem off failed"); + goto error; + } + ipc_client_log(client, "Turned the modem off"); + + rc = xmm6260_sec_modem_power(modem_boot_fd, 1); + rc |= xmm6260_sec_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"); + + rc = xmm6260_sec_modem_link_connected_wait(modem_link_fd); + if (rc < 0) { + ipc_client_log(client, "Waiting for link connected failed"); + goto error; + } + ipc_client_log(client, "Waited for link connected"); + + p = (unsigned char *) modem_image_data + GALAXYS3_PSI_OFFSET; + + rc = xmm6260_hsic_psi_send(client, modem_boot_fd, (void *) p, GALAXYS3_PSI_SIZE); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC PSI failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC PSI"); + + p = (unsigned char *) modem_image_data + GALAXYS3_EBL_OFFSET; + + rc = xmm6260_hsic_ebl_send(client, modem_boot_fd, (void *) p, GALAXYS3_EBL_SIZE); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC EBL failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC EBL"); + + rc = xmm6260_hsic_port_config_send(client, modem_boot_fd); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC port config failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC port config"); + + p = (unsigned char *) modem_image_data + GALAXYS3_SEC_START_OFFSET; + + rc = xmm6260_hsic_sec_start_send(client, modem_boot_fd, (void *) p, GALAXYS3_SEC_START_SIZE); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC SEC start failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC SEC start"); + + p = (unsigned char *) modem_image_data + GALAXYS3_FIRMWARE_OFFSET; + + rc = xmm6260_hsic_firmware_send(client, modem_boot_fd, (void *) p, GALAXYS3_FIRMWARE_SIZE); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC firmware failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC firmware"); + + rc = xmm6260_hsic_nv_data_send(client, modem_boot_fd); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC nv_data failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC nv_data"); + + rc = xmm6260_hsic_sec_end_send(client, modem_boot_fd); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC SEC end failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC SEC end"); + + rc = xmm6260_hsic_hw_reset_send(client, modem_boot_fd); + if (rc < 0) { + ipc_client_log(client, "Sending XMM6260 HSIC HW reset failed"); + goto error; + } + ipc_client_log(client, "Sent XMM6260 HSIC HW reset"); + + usleep(300000); + + rc = xmm6260_sec_modem_link_get_hostwake_wait(modem_link_fd); + if (rc < 0) { + ipc_client_log(client, "Waiting for host wake failed"); + } + + rc = xmm6260_sec_modem_link_control_enable(modem_link_fd, 0); + rc |= xmm6260_sec_modem_hci_power(0); + rc |= xmm6260_sec_modem_link_control_active(modem_link_fd, 0); + + if (rc < 0) { + ipc_client_log(client, "Turning the modem off failed"); + goto error; + } + + rc = xmm6260_sec_modem_link_get_hostwake_wait(modem_link_fd); + if (rc < 0) { + ipc_client_log(client, "Waiting for host wake failed"); + goto error; + } + ipc_client_log(client, "Waited for host wake"); + + rc = xmm6260_sec_modem_link_control_enable(modem_link_fd, 1); + rc |= xmm6260_sec_modem_hci_power(1); + rc |= xmm6260_sec_modem_link_control_active(modem_link_fd, 1); + + if (rc < 0) { + ipc_client_log(client, "Turning the modem on failed"); + goto error; + } + + rc = xmm6260_sec_modem_link_connected_wait(modem_link_fd); + if (rc < 0) { + ipc_client_log(client, "Waiting for link connected failed"); + goto error; + } + ipc_client_log(client, "Waited for link connected"); + + usleep(300000); + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (modem_image_data != NULL) + munmap(modem_image_data, GALAXYS3_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 galaxys3_ipc_fmt_send(struct ipc_client *client, struct ipc_message_info *request) +{ + return xmm6260_sec_modem_ipc_fmt_send(client, request); +} + +int galaxys3_ipc_fmt_recv(struct ipc_client *client, struct ipc_message_info *response) +{ + return xmm6260_sec_modem_ipc_fmt_recv(client, response); +} + +int galaxys3_ipc_rfs_send(struct ipc_client *client, struct ipc_message_info *request) +{ + return xmm6260_sec_modem_ipc_rfs_send(client, request); +} + +int galaxys3_ipc_rfs_recv(struct ipc_client *client, struct ipc_message_info *response) +{ + return xmm6260_sec_modem_ipc_rfs_recv(client, response); +} + +int galaxys3_ipc_open(void *data, int type) +{ + struct galaxys3_ipc_transport_data *transport_data; + + if (data == NULL) + return -1; + + transport_data = (struct galaxys3_ipc_transport_data *) data; + + transport_data->fd = xmm6260_sec_modem_ipc_open(type); + if (transport_data->fd < 0) + return -1; + + return 0; +} + +int galaxys3_ipc_close(void *data) +{ + struct galaxys3_ipc_transport_data *transport_data; + + if (data == NULL) + return -1; + + transport_data = (struct galaxys3_ipc_transport_data *) data; + + xmm6260_sec_modem_ipc_close(transport_data->fd); + transport_data->fd = -1; + + return 0; +} + +int galaxys3_ipc_read(void *data, void *buffer, unsigned int length) +{ + struct galaxys3_ipc_transport_data *transport_data; + int rc; + + if (data == NULL) + return -1; + + transport_data = (struct galaxys3_ipc_transport_data *) data; + + rc = xmm6260_sec_modem_ipc_read(transport_data->fd, buffer, length); + return rc; +} + +int galaxys3_ipc_write(void *data, void *buffer, unsigned int length) +{ + struct galaxys3_ipc_transport_data *transport_data; + int rc; + + if (data == NULL) + return -1; + + transport_data = (struct galaxys3_ipc_transport_data *) data; + + rc = xmm6260_sec_modem_ipc_write(transport_data->fd, buffer, length); + return rc; +} + +int galaxys3_ipc_poll(void *data, struct timeval *timeout) +{ + struct galaxys3_ipc_transport_data *transport_data; + int rc; + + if (data == NULL) + return -1; + + transport_data = (struct galaxys3_ipc_transport_data *) data; + + rc = xmm6260_sec_modem_ipc_poll(transport_data->fd, timeout); + return rc; +} + +int galaxys3_ipc_power_on(void *data) +{ + return 0; +} + +int galaxys3_ipc_power_off(void *data) +{ + int fd; + int rc; + + fd = open(XMM6260_SEC_MODEM_BOOT0_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (fd < 0) + return -1; + + rc = xmm6260_sec_modem_power(fd, 0); + + close(fd); + + if (rc < 0) + return -1; + + return 0; +} + +int galaxys3_ipc_data_create(void **transport_data, void **power_data, void **gprs_data) +{ + if (transport_data == NULL) + return -1; + + *transport_data = (void *) malloc(sizeof(struct galaxys3_ipc_transport_data)); + memset(*transport_data, 0, sizeof(struct galaxys3_ipc_transport_data)); + + return 0; +} + +int galaxys3_ipc_data_destroy(void *transport_data, void *power_data, void *gprs_data) +{ + if (transport_data == NULL) + return -1; + + free(transport_data); + + return 0; +} + +char *galaxys3_ipc_gprs_get_iface(int cid) +{ + return xmm6260_sec_modem_ipc_gprs_get_iface(cid); +} + + +int galaxys3_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities) +{ + return xmm6260_sec_modem_ipc_gprs_get_capabilities(capabilities); +} + +struct ipc_ops galaxys3_ipc_fmt_ops = { + .bootstrap = galaxys3_ipc_bootstrap, + .send = galaxys3_ipc_fmt_send, + .recv = galaxys3_ipc_fmt_recv, +}; + +struct ipc_ops galaxys3_ipc_rfs_ops = { + .bootstrap = NULL, + .send = galaxys3_ipc_rfs_send, + .recv = galaxys3_ipc_rfs_recv, +}; + +struct ipc_handlers galaxys3_ipc_handlers = { + .read = galaxys3_ipc_read, + .write = galaxys3_ipc_write, + .open = galaxys3_ipc_open, + .close = galaxys3_ipc_close, + .poll = galaxys3_ipc_poll, + .transport_data = NULL, + .power_on = galaxys3_ipc_power_on, + .power_off = galaxys3_ipc_power_off, + .power_data = NULL, + .gprs_activate = NULL, + .gprs_deactivate = NULL, + .gprs_data = NULL, + .data_create = galaxys3_ipc_data_create, + .data_destroy = galaxys3_ipc_data_destroy, +}; + +struct ipc_gprs_specs galaxys3_ipc_gprs_specs = { + .gprs_get_iface = galaxys3_ipc_gprs_get_iface, + .gprs_get_capabilities = galaxys3_ipc_gprs_get_capabilities, +}; + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/galaxys3/galaxys3_ipc.h b/samsung-ipc/device/galaxys3/galaxys3_ipc.h new file mode 100644 index 0000000..8e5f64a --- /dev/null +++ b/samsung-ipc/device/galaxys3/galaxys3_ipc.h @@ -0,0 +1,49 @@ +/* + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2013 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 __GALAXYS3_IPC_H__ +#define __GALAXYS3_IPC_H__ + +#define GALAXYS3_MODEM_IMAGE_SIZE 0x1000000 +#define GALAXYS3_PSI_OFFSET 0x1000 +#define GALAXYS3_PSI_SIZE 0xE000 +#define GALAXYS3_EBL_OFFSET 0xF000 +#define GALAXYS3_EBL_SIZE 0x19000 +#define GALAXYS3_SEC_START_OFFSET 0x9FF800 +#define GALAXYS3_SEC_START_SIZE 0x800 +#define GALAXYS3_FIRMWARE_OFFSET 0x28000 +#define GALAXYS3_FIRMWARE_SIZE 0x9D7800 +#define GALAXYS3_NV_DATA_OFFSET 0xA00000 +#define GALAXYS3_NV_DATA_SIZE 0x200000 + +#define GALAXYS3_MODEM_IMAGE_DEVICE "/dev/block/mmcblk0p7" + +struct galaxys3_ipc_transport_data { + int fd; +}; + +extern struct ipc_ops galaxys3_ipc_fmt_ops; +extern struct ipc_ops galaxys3_ipc_rfs_ops; +extern struct ipc_handlers galaxys3_ipc_handlers; +extern struct ipc_gprs_specs galaxys3_ipc_gprs_specs; + +#endif + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/ipc_devices.c b/samsung-ipc/ipc_devices.c index 2bd436e..0b91fa0 100644 --- a/samsung-ipc/ipc_devices.c +++ b/samsung-ipc/ipc_devices.c @@ -65,7 +65,7 @@ struct ipc_device_desc ipc_devices[] = { .gprs_specs = &aries_ipc_gprs_specs, .nv_data_specs = NULL, }, - { + { .name = "galaxys2", .board_name = "i9100", .kernel_version = NULL, @@ -75,7 +75,7 @@ struct ipc_device_desc ipc_devices[] = { .gprs_specs = &galaxys2_ipc_gprs_specs, .nv_data_specs = NULL, }, - { + { .name = "galaxys2", .board_name = "smdk4210", .kernel_version = NULL, @@ -86,6 +86,26 @@ struct ipc_device_desc ipc_devices[] = { .nv_data_specs = NULL, }, { + .name = "galaxys3", + .board_name = "i9300", + .kernel_version = NULL, + .fmt_ops = &galaxys3_ipc_fmt_ops, + .rfs_ops = &galaxys3_ipc_rfs_ops, + .handlers = &galaxys3_ipc_handlers, + .gprs_specs = &galaxys3_ipc_gprs_specs, + .nv_data_specs = NULL, + }, + { + .name = "galaxys3", + .board_name = "smdk4x12", + .kernel_version = NULL, + .fmt_ops = &galaxys3_ipc_fmt_ops, + .rfs_ops = &galaxys3_ipc_rfs_ops, + .handlers = &galaxys3_ipc_handlers, + .gprs_specs = &galaxys3_ipc_gprs_specs, + .nv_data_specs = NULL, + }, + { .name = "maguro", .board_name = "tuna", .kernel_version = NULL, diff --git a/samsung-ipc/ipc_devices.h b/samsung-ipc/ipc_devices.h index 4777dc3..316f8f4 100644 --- a/samsung-ipc/ipc_devices.h +++ b/samsung-ipc/ipc_devices.h @@ -23,6 +23,7 @@ #include "device/crespo/crespo_ipc.h" #include "device/aries/aries_ipc.h" #include "device/galaxys2/galaxys2_ipc.h" +#include "device/galaxys3/galaxys3_ipc.h" #include "device/maguro/maguro_ipc.h" #include "device/piranha/piranha_ipc.h" -- cgit v1.1