/* * Copyright (C) 2013 Paul Kocialkowski * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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 this program. If not, see . */ #include #include #include #include #include #include #include #define LOG_TAG "smdk4x12_ion" #include #include "smdk4x12_camera.h" int smdk4x12_ion_init(struct smdk4x12_camera *smdk4x12_camera) { smdk4x12_camera->ion_fd = -1; return 0; } int smdk4x12_ion_open(struct smdk4x12_camera *smdk4x12_camera) { int fd; fd = open("/dev/ion", O_RDWR); if (fd < 0) { ALOGE("%s: Unable to open ion device", __func__); return -1; } smdk4x12_camera->ion_fd = fd; return 0; } void smdk4x12_ion_close(struct smdk4x12_camera *smdk4x12_camera) { if (smdk4x12_camera->ion_fd >= 0) close(smdk4x12_camera->ion_fd); smdk4x12_camera->ion_fd = -1; } int smdk4x12_ion_alloc(struct smdk4x12_camera *smdk4x12_camera, int size) { struct ion_allocation_data alloc_data; struct ion_fd_data share_data; struct ion_handle_data free_data; int page_size; int fd; int rc; page_size = getpagesize(); fd = smdk4x12_camera->ion_fd; if (fd < 0) return -1; memset(&alloc_data, 0, sizeof(alloc_data)); alloc_data.len = size; alloc_data.align = page_size; alloc_data.flags = ION_HEAP_EXYNOS_CONTIG_MASK; rc = ioctl(fd, ION_IOC_ALLOC, &alloc_data); if (rc < 0) return -1; memset(&share_data, 0, sizeof(share_data)); share_data.handle = alloc_data.handle; rc = ioctl(fd, ION_IOC_SHARE, &share_data); if (rc < 0) return -1; memset(&free_data, 0, sizeof(free_data)); free_data.handle = alloc_data.handle; rc = ioctl(fd, ION_IOC_FREE, &free_data); if (rc < 0) return -1; return share_data.fd; } int smdk4x12_ion_free(struct smdk4x12_camera *smdk4x12_camera, int fd) { close(fd); return 0; } int smdk4x12_ion_phys(struct smdk4x12_camera *smdk4x12_camera, int fd) { struct ion_custom_data custom_data; struct ion_phys_data phys_data; int rc; memset(&phys_data, 0, sizeof(phys_data)); phys_data.fd_buffer = fd; memset(&custom_data, 0, sizeof(custom_data)); custom_data.cmd = ION_EXYNOS_CUSTOM_PHYS; custom_data.arg = (unsigned long) &phys_data; fd = smdk4x12_camera->ion_fd; if (fd < 0) return -1; rc = ioctl(fd, ION_IOC_CUSTOM, &custom_data); if (rc < 0) return -1; return (int) phys_data.phys; } int smdk4x12_ion_msync(struct smdk4x12_camera *smdk4x12_camera, int fd, int offset, int size) { struct ion_custom_data custom_data; struct ion_msync_data msync_data; int rc; memset(&msync_data, 0, sizeof(msync_data)); msync_data.dir = IMSYNC_SYNC_FOR_DEV | IMSYNC_DEV_TO_RW; msync_data.fd_buffer = fd; msync_data.offset = offset; msync_data.size = size; memset(&custom_data, 0, sizeof(custom_data)); custom_data.cmd = ION_EXYNOS_CUSTOM_MSYNC; custom_data.arg = (unsigned long) &msync_data; fd = smdk4x12_camera->ion_fd; if (fd < 0) return -1; rc = ioctl(fd, ION_IOC_CUSTOM, &custom_data); if (rc < 0) return -1; return 0; }