summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyun myung Cho <hm83.cho@samsung.com>2016-06-30 16:01:46 +0900
committerHyun myung Cho <hm83.cho@samsung.com>2016-06-30 16:01:46 +0900
commit99ca6a81497c5b4b34f907b9c7a6c025843d6d43 (patch)
tree7b081bba0afc7d6da7c21ce86239b39d0dfb5864
parent6b7d3aebe881dc9f6afbd3fc44be8d3ffc0f0300 (diff)
downloademulator-kernel-99ca6a81497c5b4b34f907b9c7a6c025843d6d43.tar.gz
emulator-kernel-99ca6a81497c5b4b34f907b9c7a6c025843d6d43.tar.bz2
emulator-kernel-99ca6a81497c5b4b34f907b9c7a6c025843d6d43.zip
TV: Add dummy driver for TV Emulator
Change-Id: I09cb1b1a5b4b45a2b743218b552603685ae1c1e5 Signed-off-by: Hyun myung Cho <hm83.cho@samsung.com>
-rw-r--r--arch/x86/configs/tizen_emul_defconfig8
-rw-r--r--drivers/maru/Kconfig31
-rw-r--r--drivers/maru/Makefile2
-rw-r--r--drivers/maru/maru_eeprom.c705
-rw-r--r--drivers/maru/maru_eeprom.h61
-rw-r--r--drivers/maru/tztv-dummy/Makefile7
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy.c219
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy.h52
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy_gpio.c196
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy_i2c_sdp.c278
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy_micom_isp.c269
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy_micom_msg.c356
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy_sdp_mem.c174
-rw-r--r--drivers/maru/tztv-dummy/maru_dummy_security.c202
14 files changed, 2560 insertions, 0 deletions
diff --git a/arch/x86/configs/tizen_emul_defconfig b/arch/x86/configs/tizen_emul_defconfig
index d518262da321..76806aebe736 100644
--- a/arch/x86/configs/tizen_emul_defconfig
+++ b/arch/x86/configs/tizen_emul_defconfig
@@ -3454,6 +3454,14 @@ CONFIG_MARU_VIRTIO_NFC=y
CONFIG_MARU_BRILLCODEC=y
CONFIG_MARU_VIRTIO_VMODEM=y
CONFIG_MARU_VIRTIO_ROTARY=y
+CONFIG_MARU_EEPROM=y
+CONFIG_MARU_MICOM_MSG=y
+CONFIG_MARU_MICOM_ISP=y
+CONFIG_MARU_DUMMY=y
+CONFIG_MARU_SECURITY=y
+CONFIG_MARU_SDP_MEM=y
+CONFIG_MARU_GPIO=y
+CONFIG_MARU_I2C_SDP=y
# CONFIG_MARU_EXTENSION_SOURCE is not set
#
diff --git a/drivers/maru/Kconfig b/drivers/maru/Kconfig
index 623b349a32fe..efe071060be3 100644
--- a/drivers/maru/Kconfig
+++ b/drivers/maru/Kconfig
@@ -69,3 +69,34 @@ config MARU_EXTENSION_SOURCE
config MARU_EXTENSION_SOURCE_PATH
string "MARU Extension source path"
depends on MARU != n && MARU_EXTENSION_SOURCE != n
+
+config MARU_MICOM_MSG
+ tristate "Micom Auto Remocon driver support for WT61P807"
+
+config MARU_MICOM_ISP
+ tristate "Micom ISP data support for WT61P807"
+
+config MARU_DUMMY
+ tristate "MARU Dummy Driver"
+ depends on MARU != n
+
+config MARU_SECURITY
+ tristate "MARU Security Driver"
+ depends on MARU != n
+
+config MARU_SDP_MEM
+ tristate "MARU SDP Memory Driver"
+ depends on MARU != n
+
+config MARU_GPIO
+ tristate "MARU Dummy GPIO Driver"
+ depends on MARU != n && GPIOLIB != n
+
+config MARU_I2C_SDP
+ tristate "Maru Dummy I2C SDP Driver"
+ depends on MARU != n && I2C != n
+
+config MARU_EEPROM
+ tristate "MARU VirtIO Virtual EEPROM Device Driver"
+ depends on MARU != n
+ depends on SYSFS
diff --git a/drivers/maru/Makefile b/drivers/maru/Makefile
index 5b2d4976dd29..a1627f8007c9 100644
--- a/drivers/maru/Makefile
+++ b/drivers/maru/Makefile
@@ -15,4 +15,6 @@ obj-$(CONFIG_MARU_BRILLCODEC) += maru_brillcodec.o
obj-$(CONFIG_MARU_VIRTIO_VMODEM) += maru_virtio_vmodem.o
obj-$(CONFIG_MARU_VIRTIO_ROTARY) += maru_virtio_rotary.o
obj-$(CONFIG_MARU_VIRTIO_TABLET) += maru_virtio_tablet.o
+obj-$(CONFIG_MARU_EEPROM) += maru_eeprom.o
+obj-$(CONFIG_MARU_DUMMY) += tztv-dummy/
obj-$(CONFIG_MARU_EXTENSION_SOURCE) += $(CONFIG_MARU_EXTENSION_SOURCE_PATH)/
diff --git a/drivers/maru/maru_eeprom.c b/drivers/maru/maru_eeprom.c
new file mode 100644
index 000000000000..9baccf00a38d
--- /dev/null
+++ b/drivers/maru/maru_eeprom.c
@@ -0,0 +1,705 @@
+/*
+ * MARU EEPROM
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Dongkyun Yun <dk77.yun@samsung.com>
+ * Munkyu Im <munkyu.im@samsung.com>
+ * Sangho Park <sangho.p@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <asm/current.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#include <linux/version.h>
+#include <linux/moduleparam.h>
+#include <linux/cdev.h>
+#include <linux/file.h>
+#include "maru_eeprom.h"
+#include <linux/vmalloc.h>
+
+//#define EEP_DEBUG
+
+#ifdef EEP_DEBUG
+#define eep_log(fmt, arg...) \
+ printk(KERN_INFO "[%s](%s:%d)[%s:%d]: " fmt, EEPROM_DEV_NAME, \
+ __func__, __LINE__, current->comm, current->pid, ##arg);
+#else
+#define eep_log(fmt, arg...)
+#endif
+
+#define eep_err(fmt, arg...) \
+ printk(KERN_ERR "[%s](%s)[%s:%d]: " fmt, EEPROM_DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+#define eep_warn(fmt, arg...) \
+ printk(KERN_WARNING "[%s](%s)[%s:%d]: " fmt, EEPROM_DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+#define eep_info(fmt, arg...) \
+ printk(KERN_INFO "[%s](%s:%d)[%s:%d]: " fmt, EEPROM_DEV_NAME, __func__, __LINE__, \
+ current->comm, current->pid, ##arg);
+
+
+
+#define FILENAME "/boot/eeprom"
+
+#define true 1
+#define false 0
+
+/* device protocol */
+enum req_cmd {
+ req_eeprom_get = 1,
+ req_eeprom_set,
+ req_eeprom_reply
+};
+
+/* eeprom specific macros */
+#define EEP_BLOCK_SIZE 4096
+#define EEP_BLOCK_COUNT 16
+#define EEPROM_MAX_SIZE (EEP_BLOCK_SIZE * EEP_BLOCK_COUNT)
+#define MAX_ATTR_BYTES 6
+
+/* 10 milliseconds of delay is required after each i2c write operation */
+//#define DELAY 10000
+
+/* upper/lower 8-bit word address macros */
+#define HI_BYTE(x) (((x) >> 8) & (0x00FF))
+#define LO_BYTE(x) ((x) & (0x00FF))
+
+/* define global mutex statically ***/
+static DEFINE_MUTEX(eep_mutex);
+
+/* global variables for this module ***/
+static int counter;
+static const unsigned int eeprom_size = EEPROM_MAX_SIZE;
+static int eeprom_dev_major;
+//static struct i2c_client *eep_client;
+
+/* write protection for eeprom */
+static int g_protect;
+
+static struct file *g_file;
+
+static ssize_t eeprom_write_file(const unsigned char __user *buf, int len, loff_t pos)
+{
+ ssize_t ret = 0;
+ mm_segment_t old_fs;
+
+ if (g_file == NULL)
+ return -ENODEV;
+
+ if (g_protect) {
+ eep_info("memory is protected.\n");
+ return ret;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ ret = vfs_write(g_file, buf, len, &pos);
+ if (ret != len) {
+ eep_warn("len mismatch len: %d, ret: %d, pos: %lld\n", ret, len, pos);
+ }
+ set_fs(old_fs);
+
+ return ret;
+}
+
+static int eeprom_init_file(void)
+{
+ unsigned int i;
+ loff_t pos = 0;
+ int ret = 0;
+ int reminder_pos = 0;
+ unsigned char *buf = vmalloc(EEP_BLOCK_SIZE);
+ if (!buf) {
+ eep_warn("memory not allocated for buffer.\n");
+ ret = -ENOMEM;
+ goto out_ext;
+ }
+ memset(buf, 0xff, EEP_BLOCK_SIZE);
+
+ for (i = 0; i < EEP_BLOCK_COUNT; i++) {
+ ret = eeprom_write_file(buf, EEP_BLOCK_SIZE, pos);
+ if (ret < 0) {
+ eep_warn("failed to initialize. ret: %d\n", ret);
+ goto out_ext;
+ } else if (ret < EEP_BLOCK_SIZE) {
+ eep_info("write reminder.\n");
+ reminder_pos = ret;
+ do {
+ ret = eeprom_write_file(buf, EEP_BLOCK_SIZE - reminder_pos, pos + reminder_pos);
+ if (ret <= 0) {
+ eep_warn("failed to write reminder. ret: %d\n", ret);
+ goto out_ext;
+ }
+ reminder_pos += ret;
+ } while (reminder_pos != EEP_BLOCK_SIZE);
+ }
+ pos += EEP_BLOCK_SIZE;
+ }
+ ret = pos;
+ vfree(buf);
+ eep_info("file initialized: %s\n", FILENAME);
+
+out_ext:
+ return ret;
+}
+
+static int eeprom_open_file(void)
+{
+ struct file *file;
+ eep_log("eeprom_open_file\n");
+
+ file = filp_open(FILENAME, O_CREAT|O_RDWR|O_EXCL|O_SYNC, 0666);
+ if (IS_ERR(file)) {
+ eep_info("file already exists: %s\n", FILENAME);
+ file = filp_open(FILENAME, O_CREAT|O_RDWR|O_SYNC, 0666);
+ if (IS_ERR(file)) {
+ eep_warn("filp_open failed.\n");
+ return -ENOENT;
+ }
+ g_file = file;
+ return 0;
+ }
+ g_file = file;
+
+ return eeprom_init_file();
+}
+
+static ssize_t eeprom_read_file(unsigned char __user *buf, int len, loff_t pos)
+{
+ ssize_t ret = 0;
+ mm_segment_t old_fs;
+
+ if (g_file == NULL)
+ return -ENODEV;
+
+ eep_log("pos(%lld) len(%d) \n", pos, len);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ ret = vfs_read(g_file, buf, len, &pos);
+ if (ret != len) {
+ eep_warn("len mismatch len: %d, ret: %d, pos: %lld\n", ret, len, pos);
+ }
+ set_fs(old_fs);
+
+ return ret;
+}
+
+static int eeprom_usr_write(const char __user *buf, size_t count, unsigned long addr)
+{
+ int ret = -EFAULT;
+
+ eep_log("eep write.\n");
+ if (!buf) {
+ eep_err("Invalid User buffer.\n");
+ } else if (count > 0) {
+ if (addr + count > eeprom_size) {
+ eep_err("overflow!!.\n");
+ goto out_err;
+ }
+ ret = eeprom_write_file(buf, count, addr);
+ if (ret < 0) {
+ eep_warn("Write failed.\n");
+ }
+ } else {
+ eep_warn("inavalid count.\n");
+ }
+
+out_err:
+ return ret;
+}
+
+static ssize_t eeprom_usr_read(char __user *buf, size_t count, unsigned long addr)
+{
+ int ret = -EFAULT;
+
+ eep_log("eep read.\n");
+ if (!buf) {
+ eep_err("User buf has no memory allocation.\n");
+ } else if (count > 0) {
+ if (count + addr > eeprom_size) {
+ eep_err("overflow!!.\n");
+ goto out_err;
+ }
+ ret = eeprom_read_file(buf, count, addr);
+ if (ret < 0) {
+ eep_warn("read failed.\n");
+ }
+ } else {
+ eep_warn("invalid count.\n");
+ }
+
+out_err:
+ return ret;
+}
+
+
+
+
+/* for using sysfs. (class, device, device attribute) */
+
+/** @brief This function inhibits the write operation on eeprom.
+ *
+ * @param [in] protect value(0 or 1).
+ * 1 - To protect memory.
+ * 0 - To unprotect memory.
+ * @return On success Returns 0.
+ * On failure Returns negative error number.
+ */
+int eep_set_wp(int protect)
+{
+ int ret = 0;
+
+ if (protect != 0 && protect != 1) {
+ eep_warn("invalid input.\n");
+ return -EINVAL;
+ }
+
+ g_protect = protect;
+ eep_log("eeprom => %d (1:locked, 0:unlocked)\n", g_protect);
+
+ return ret;
+}
+EXPORT_SYMBOL(eep_set_wp);
+
+/**
+ * @brief Returns the status of eeprom write protection.
+ *
+ * @param [in] void It takes no arguments.
+ *
+ * @return On success Returns 0.
+ * On failure Returns negative error number.
+ */
+int eep_get_wp()
+{
+ int ret = 0;
+
+ ret = g_protect;
+ eep_log("eeprom => %d (1:locked, 0:unlocked)\n", g_protect);
+
+ return ret;
+}
+EXPORT_SYMBOL(eep_get_wp);
+
+/**
+ * @brief This function resets the whole eeprom chip.
+ *
+ * @parms [in] void It takes no arguments.
+ *
+ * @return On success Returns 0.
+ * On failure Returns negative error number.
+ */
+static int eep_reset(void)
+{
+ return eeprom_init_file();
+}
+
+/**
+ * @brief This function opens the eeprom device.
+ *
+ * @param inode inode.
+ * @param [in] fp File pointer points to the file descriptor.
+ *
+ * @return On success Returns 0.
+ * On failure Returns negative error number.
+ */
+int eep_open(struct inode *inode, struct file *fp)
+{
+ int ret = 0;
+
+ mutex_lock(&eep_mutex);
+ if (counter == 0) {
+ eeprom_open_file();
+ } else if (g_file == NULL) {
+ eep_warn("g_file is NULL\n");
+ ret = -ENODEV;
+ goto out;
+ } else {
+ //Increase reference count of g_file
+ atomic_long_inc_not_zero(&g_file->f_count);
+ }
+
+ counter++;
+ eep_log("Open: #:%d\n" , counter);
+ //eep_log("major number=%d, minor number=%d \n", imajor(inode), iminor(inode));
+out:
+ mutex_unlock(&eep_mutex);
+
+ return ret;
+}
+
+/**
+ * @brief This function undo the all open call operations.
+ *
+ * @param inode inode.
+ * @param [in] fp File pointer points to the file descriptor.
+ *
+ * @return On success Returns 0.
+ * On failure Returns negative error number.
+ */
+int eep_close(struct inode *inode, struct file *fp)
+{
+ int ret = 0;
+
+ eep_log("close.\n");
+
+ mutex_lock(&eep_mutex);
+ BUG_ON(g_file == NULL);
+ fput(g_file);
+ counter--;
+ mutex_unlock(&eep_mutex);
+ return ret;
+}
+
+/**
+ * @brief The lseek method is used to change the current read/write position
+ * in a file
+ *
+ * @param [in] fp File pointer points to the file descriptor.
+ * @param [in] offset Offset.
+ * @param [in] origin Origin.
+ *
+ * @return On success The new position(resulting offset) is returned.
+ * On failure Returns negative error number.
+ */
+loff_t eep_lseek(struct file *fp, loff_t offset, int origin)
+{
+ loff_t current_offset = 0;
+
+ eep_log("lseek.\n");
+
+ mutex_lock(&eep_mutex);
+
+ switch (origin) {
+ case SEEK_SET:
+ current_offset = offset;
+ break;
+ case SEEK_CUR:
+ current_offset = fp->f_pos + offset;
+ break;
+ case SEEK_END:
+ current_offset = eeprom_size - offset;
+ break;
+ default:
+ break;
+ }
+ if (current_offset >= eeprom_size) {
+ eep_err("offset overflow!\n");
+ current_offset = eeprom_size - 1;
+ } else if (current_offset < 0) {
+ eep_err("offset underflow!\n");
+ current_offset = 0;
+ }
+
+ fp->f_pos = current_offset;
+
+ mutex_unlock(&eep_mutex);
+ return current_offset;
+}
+
+/**
+ * @brief This function reads the data from eeprom device.
+ *
+ * @param [in] fp File pointer points to the file descriptor.
+ * @param [in] buf Pointer to the user space buffer.
+ * @param [in] count Number of bytes application intend to read.
+ * @param [in/out] pos Current file offset position.
+ *
+ * @return On success Returns count(number of read bytes).
+ * On failure Returns negative error number.
+ */
+ssize_t eep_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
+{
+ int ret = 0;
+
+ mutex_lock(&eep_mutex);
+ ret = eeprom_usr_read(buf, count, fp->f_pos);
+ if (ret < 0) {
+ eep_warn("eep_read failed. ret: %d", ret);
+ }
+ mutex_unlock(&eep_mutex);
+
+ return ret;
+}
+
+/**
+ * @brief This function writes the data to eeprom device.
+ *
+ * @param [in] fp File pointer points to the file descriptor.
+ * @param [in] buf Pointer to the user space buffer.
+ * @param [in] count Number of bytes application intend to write.
+ * @param [in/out] pos Current file offset position.
+ *
+ * @return On success Returns count(the number of bytes successfully written).
+ * On failure Returns negative error number.
+ */
+ssize_t eep_write(struct file *fp, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ int ret = 0;
+
+ mutex_lock(&eep_mutex);
+ ret = eeprom_usr_write(buf, count, fp->f_pos);
+ if (ret < 0) {
+ eep_warn("eep_write failed. ret: %d", ret);
+ }
+ mutex_unlock(&eep_mutex);
+
+ return ret;
+}
+
+
+/**
+ * @brief This function performs control operations on eeprom.
+ *
+ * @param [in] fp File pointer points to the file descriptor.
+ * @param [in] cmd Request command.
+ * @param [in/out] args The arguments based on request command.
+ *
+ * @return On Success Returns zero.
+ * On failure Returns negative error number.
+ */
+long eep_ioctl(struct file *fp, unsigned int cmd, unsigned long args)
+{
+ int protect = 0, size;
+ long ret = 0;
+
+ eep_log("ioctl.\n");
+
+ /*verify args*/
+ if (_IOC_TYPE(cmd) != EEPROM_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > EEPROM_MAX_CMDS)
+ return -ENOTTY;
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ if (!access_ok(VERIFY_WRITE, (void *)args, _IOC_SIZE(cmd)))
+ return -EFAULT;
+ if (_IOC_DIR(cmd) & _IOC_WRITE)
+ if (!access_ok(VERIFY_READ, (void *)args, _IOC_SIZE(cmd)))
+ return -EFAULT;
+ mutex_lock(&eep_mutex);
+ switch (cmd) {
+ case EEPROM_RESET:
+ eep_reset();
+ break;
+ case EEPROM_SET_WP:
+ if (copy_from_user(&protect, (int *)args, sizeof(int))) {
+ eep_warn("failed copy_from_user.\n");
+ return -EFAULT;
+ }
+ eep_set_wp(protect);
+ break;
+ case EEPROM_GET_WP:
+ protect = eep_get_wp();
+ if (copy_to_user((int *)args, &protect, sizeof(int))) {
+ eep_warn("failed copy_to_user.\n");
+ ret = -EFAULT;
+ }
+ break;
+ case EEPROM_GET_SIZE:
+ size = eeprom_size;
+ if (copy_to_user((int *)args, &size, sizeof(int))) {
+ eep_warn("failed copy_to_user.\n");
+ ret = -EFAULT;
+ }
+ break;
+ case EEPROM_WRITE_DATA:
+ case EEPROM_READ_DATA:
+ {
+ struct eeprom_io_pkt *pkt = (struct eeprom_io_pkt *)args;
+ if (cmd == EEPROM_WRITE_DATA)
+ ret = eeprom_usr_write(pkt->wbuf, pkt->size, pkt->addr);
+ else
+ ret = eeprom_usr_read(pkt->rbuf, pkt->size, pkt->addr);
+ if (ret < 0) {
+ eep_warn("failed handle eeprom data: %ld", ret);
+ }
+ }
+ break;
+ default:
+ eep_warn("invalid cmd %d \n", cmd);
+ ret = -EFAULT;
+ break;
+ }
+ mutex_unlock(&eep_mutex);
+ return ret;
+}
+
+/**
+ * @brief This function will be called when the user read from sysfs.
+ *
+ * @param [in] dev device.
+ * @param [in] attr device attributes.
+ * @param [in/out] buf buffer.
+ *
+ * @return On success Returns maxlen characters pointed to by buf.
+ * On failure Returns negative error number.
+ */
+static ssize_t nvram_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ eep_log("called.\n");
+
+ mutex_lock(&eep_mutex);
+ snprintf(buf, sizeof(int), "%d", eeprom_size);
+ mutex_unlock(&eep_mutex);
+ return strnlen(buf, MAX_ATTR_BYTES);
+}
+
+/* for using sysfs. (class, device, device attribute) */
+static struct class *eep_class;
+static struct device *eep_dev;
+static DEVICE_ATTR_RO(nvram_size);
+
+static const struct of_device_id eepdev_of_match[] = {
+ { .compatible = "sii,s24c512c" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, eepdev_of_match);
+
+/**
+ * Devices are identified using device id
+ * of the chip
+ */
+static const struct i2c_device_id eep_i2c_id[] = {
+ { "s24c512c", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, eep_i2c_id);
+
+/* device number */
+dev_t eeprom_dev_num;
+
+/* function pointers for file operations */
+static const struct file_operations eep_drv_fops = {
+ .llseek = eep_lseek,
+ .read = eep_read,
+ .open = eep_open,
+ .release = eep_close,
+ .write = eep_write,
+ .unlocked_ioctl = eep_ioctl,
+ .owner = THIS_MODULE,
+};
+
+
+/* Device initialization routine */
+static int __init eep_init(void)
+{
+ int res = 0;
+
+ eep_info("init!!\n");
+
+ counter = 0;
+ eeprom_dev_major = 0;
+ eeprom_dev_num = 0;
+ eep_dev = NULL;
+ eep_class = NULL;
+ //eep_client = NULL;
+
+ /* register device with file operation mappings
+ * for dynamic allocation of major number
+ */
+ res = register_chrdev(eeprom_dev_major, EEPROM_DEV_NAME, &eep_drv_fops);
+ if (res < 0) {
+ eep_err("failed to get major number.\n");
+ goto out;
+ }
+ /* if the allocation is dynamic ?*/
+ if (res != 0)
+ eeprom_dev_major = res;
+
+ eeprom_dev_num = MKDEV(eeprom_dev_major, 0);
+
+ /* create class. (/sys/class/eep_class) */
+ eep_class = class_create(THIS_MODULE, "eep_class");
+ if (IS_ERR(eep_class)) {
+ res = PTR_ERR(eep_class);
+ goto out_unreg_chrdev;
+ }
+ /* create class device. (/sys/class/eep_class/eeprom) */
+ eep_dev = device_create(eep_class, NULL, eeprom_dev_num, NULL,
+ "eeprom");
+
+ if (IS_ERR(eep_dev)) {
+ res = PTR_ERR(eep_dev);
+ goto out_unreg_class;
+ }
+ /* create sysfs file. (/sys/class/eep_class/eeprom/nvram_size) */
+ res = device_create_file(eep_dev, &dev_attr_nvram_size);
+ if (res) {
+ eep_err("failed to create sysfs.\n");
+ goto out_unreg_device;
+ }
+
+ return res;
+
+ //out_unreg_sysfs:
+ // device_remove_file(eep_dev, &dev_attr_nvram_size);
+out_unreg_device:
+ device_destroy(eep_class, eeprom_dev_num);
+out_unreg_class:
+ class_destroy(eep_class);
+out_unreg_chrdev:
+ unregister_chrdev(eeprom_dev_major, EEPROM_DEV_NAME);
+out:
+ return res;
+}
+
+/* Device exit routine */
+static void __exit eep_exit(void)
+{
+ eep_info("Exit!!\n");
+
+ /* remove sysfs file */
+ device_remove_file(eep_dev, &dev_attr_nvram_size);
+ /* remove class device */
+ device_destroy(eep_class, eeprom_dev_num);
+ /* remove class */
+ class_destroy(eep_class);
+ //i2c_del_driver(&eep_i2c_driver);
+ /* unregister device */
+ unregister_chrdev(eeprom_dev_major, EEPROM_DEV_NAME);
+
+ /* for emulator */
+}
+
+/* define module init/exit, license */
+subsys_initcall(eep_init);
+module_exit(eep_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dronamraju Santosh Pavan Kumar, <dronamraj.k@samsung.com>");
diff --git a/drivers/maru/maru_eeprom.h b/drivers/maru/maru_eeprom.h
new file mode 100644
index 000000000000..6d750f65d652
--- /dev/null
+++ b/drivers/maru/maru_eeprom.h
@@ -0,0 +1,61 @@
+/**
+ *
+ * Copyright (c) 2013 Samsung Electronics Co. Ltd.
+ * Copyright (C) 2013 Samsung R&D Institute India-Delhi.
+ * Author: Dronamraju Santosh Pavan Kumar <dronamraj.k@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * @file eeprom.h
+ * @brief Header file for the eeprom_s24c512c eeprom chip.
+ * @author Dronamraju Santosh pavan Kumar <dronamraj.k@samsung.com>
+ * @date 2013/07/12
+ *
+ */
+
+/* internal Release1 */
+
+#ifndef _EEPROM_H
+#define _EEPROM_H
+
+#include<asm-generic/ioctl.h>
+
+#define EEPROM_MAGIC 'I'
+#define EEPROM_LOCAL_BUFF_SIZE 128
+
+/*device name*/
+#define EEPROM_DEV_NAME "eeprom"
+
+struct eeprom_io_pkt {
+ unsigned int addr;
+ unsigned int size;
+ const char *wbuf;
+ char *rbuf;
+};
+
+#define EEPROM_RESET _IOW(EEPROM_MAGIC, 0x01, int)
+#define EEPROM_SET_WP _IOW(EEPROM_MAGIC, 0x02, int)
+#define EEPROM_GET_WP _IOR(EEPROM_MAGIC, 0x03, int)
+#define EEPROM_GET_SIZE _IOR(EEPROM_MAGIC, 0x04, int)
+#define EEPROM_WRITE_DATA _IOW(EEPROM_MAGIC, 0x05, struct eeprom_io_pkt *)
+#define EEPROM_READ_DATA _IOR(EEPROM_MAGIC, 0x06, struct eeprom_io_pkt *)
+#define EEPROM_SLAVE_ADDR 0x50
+#define EEPROM_MAX_CMDS 6
+
+/* function prototypes */
+int eep_i2c_write(unsigned int addr, const unsigned char *buf, int len);
+int eep_reg_write(unsigned int reg, const unsigned char *buf, int len);
+int eep_reg_read(unsigned int reg, unsigned char *buf, int len);
+int eep_set_wp(int protect);
+int eep_get_wp(void);
+ssize_t eeprom_dev_write(char *buf, size_t count, unsigned long addr);
+ssize_t eeprom_dev_read(char *buf, size_t count, unsigned long addr);
+
+#endif /*_EEPROM_H */
diff --git a/drivers/maru/tztv-dummy/Makefile b/drivers/maru/tztv-dummy/Makefile
new file mode 100644
index 000000000000..32e9052f8835
--- /dev/null
+++ b/drivers/maru/tztv-dummy/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_MARU_DUMMY) += maru_dummy.o
+obj-$(CONFIG_MARU_SECURITY) += maru_dummy_security.o
+obj-$(CONFIG_MARU_SDP_MEM) += maru_dummy_sdp_mem.o
+obj-$(CONFIG_MARU_GPIO) += maru_dummy_gpio.o
+obj-$(CONFIG_MARU_I2C_SDP) += maru_dummy_i2c_sdp.o
+obj-$(CONFIG_MARU_MICOM_MSG) += maru_dummy_micom_msg.o
+obj-$(CONFIG_MARU_MICOM_ISP) += maru_dummy_micom_isp.o \ No newline at end of file
diff --git a/drivers/maru/tztv-dummy/maru_dummy.c b/drivers/maru/tztv-dummy/maru_dummy.c
new file mode 100644
index 000000000000..725490e65e4a
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy.c
@@ -0,0 +1,219 @@
+/*
+ * MARU dummy driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Jinhyung Choi <jinh0.choi@samsung.com>
+ * Hyunjin Lee <hyunjin816.lee@samsung.com>
+ * SangHo Park <sangho.p@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+
+#include "maru_dummy.h"
+
+struct dummy_device {
+ const char *name;
+ struct class *dev_class;
+ struct device* dev_device;
+ struct cdev cdev;
+ dev_t dev;
+ struct file_operations fops;
+};
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+int dummy_driver_debug = 0;
+module_param(dummy_driver_debug, int, 0644);
+MODULE_PARM_DESC(dummy_driver_debug, "Turn on/off maru dummy debugging (default:off).");
+
+#define GENERATE_ACCESSORS_DEV(_dev) \
+static int maru_##_dev##_open(struct inode *inode, struct file *file) \
+{ \
+ maru_device_dbg(1, "open is called.\n"); \
+ return 0; \
+} \
+static int maru_##_dev##_close(struct inode *inode, struct file *file) \
+{ \
+ maru_device_dbg(1, "close is called.\n"); \
+ return 0; \
+} \
+static long maru_##_dev##_ioctl(struct file *file, unsigned int cmd, unsigned long arg) \
+{ \
+ maru_device_dbg(1, "ioctl cmd : 0x%08x, arg : 0x%08lx\n", cmd, arg); \
+ return 0; \
+} \
+static ssize_t maru_##_dev##_write(struct file *file, const char __user *buf, \
+ size_t len, loff_t *ppos) \
+{ \
+ maru_device_dbg(1, "write is called. size: %d, buf: %s, \n", len, buf); \
+ return len; \
+} \
+static unsigned int maru_##_dev##_poll(struct file *file, struct poll_table_struct *wait) \
+{ \
+ return 0; \
+}
+
+#define __ATTRIBUTE_DUMMY_DEVICE(_name) { \
+ .name = __stringify(_name), \
+ .fops = { \
+ .open = maru_##_name##_open, \
+ .unlocked_ioctl = maru_##_name##_ioctl, \
+ .write = maru_##_name##_write, \
+ .poll = maru_##_name##_poll, \
+ .release = maru_##_name##_close \
+ }, \
+}
+
+#define __ATTRIBUTE_HYPHEN_DUMMY_DEVICE(_name, _fname) {\
+ .name = __stringify(_name), \
+ .fops = { \
+ .open = maru_##_fname##_open, \
+ .unlocked_ioctl = maru_##_fname##_ioctl,\
+ .write = maru_##_fname##_write, \
+ .poll = maru_##_fname##_poll, \
+ .release = maru_##_fname##_close \
+ }, \
+}
+
+GENERATE_ACCESSORS_DEV(tztv_frc)
+GENERATE_ACCESSORS_DEV(tztv_tcon)
+GENERATE_ACCESSORS_DEV(micom_cec)
+GENERATE_ACCESSORS_DEV(micom_ar)
+GENERATE_ACCESSORS_DEV(micom_bsensor)
+GENERATE_ACCESSORS_DEV(kfactory)
+
+struct dummy_device dummy_device_group[] = {
+ __ATTRIBUTE_DUMMY_DEVICE(tztv_frc),
+ __ATTRIBUTE_DUMMY_DEVICE(tztv_tcon),
+ __ATTRIBUTE_HYPHEN_DUMMY_DEVICE(micom-cec, micom_cec),
+ __ATTRIBUTE_HYPHEN_DUMMY_DEVICE(micom-ar, micom_ar),
+ __ATTRIBUTE_HYPHEN_DUMMY_DEVICE(micom-bsensor, micom_bsensor),
+ __ATTRIBUTE_DUMMY_DEVICE(kfactory),
+};
+
+static void remove_device(struct dummy_device *device)
+{
+ if (device == NULL) {
+ return;
+ }
+
+ if (device->dev_device) {
+ device_destroy(device->dev_class, device->dev);
+ device->dev_device = NULL;
+ }
+
+ if (device->dev) {
+ unregister_chrdev_region(device->dev, 1);
+ }
+
+ if (device->dev_class) {
+ class_destroy(device->dev_class);
+ }
+}
+
+static int create_device(struct dummy_device *device)
+{
+ int ret = 0;
+
+ if (device == NULL) {
+ maru_device_err("failed to create device: device == NULL \n");
+ return ret;
+ }
+
+ ret = alloc_chrdev_region(&device->dev, 0, 1, device->name);
+ if (ret < 0) {
+ maru_device_err("%s alloc_chrdev_region failed.\n", device->name);
+ return ret;
+ }
+
+ device->dev_class = class_create(THIS_MODULE, device->name);
+ if (IS_ERR(device->dev_class)) {
+ ret = PTR_ERR(device->dev_class);
+ maru_device_err("create %s class failed.\n", device->name);
+ remove_device(device);
+ return ret;
+ }
+
+ cdev_init(&device->cdev, &device->fops);
+
+ ret = cdev_add(&device->cdev, device->dev, 1);
+ if (ret < 0) {
+ maru_device_err("%s cdev_add failed\n", device->name);
+ remove_device(device);
+ return ret;
+ }
+
+ device->dev_device = device_create(device->dev_class, 0, device->dev, NULL, "%s", device->name);
+ if (ret < 0) {
+ maru_device_err("%s device_create failed\n", device->name);
+ remove_device(device);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __init maru_dummy_init(void)
+{
+ int ret = 0;
+ int i = 0;
+ int size = sizeof(dummy_device_group) / sizeof(dummy_device_group[0]);
+
+ for (i = 0; i < size; i++) {
+ ret = create_device(&dummy_device_group[i]);
+ if (ret < 0)
+ continue;
+ }
+
+ maru_device_info("dummy driver was initialized.\n");
+
+ return 0;
+}
+
+static void __exit maru_dummy_exit(void)
+{
+ int i = 0;
+ int size = sizeof(dummy_device_group) / sizeof(dummy_device_group[0]);
+
+ for (i = 0; i < size; i++) {
+ remove_device(&dummy_device_group[i]);
+ }
+
+ maru_device_info("dummy driver was exited.\n");
+}
+
+module_init(maru_dummy_init);
+module_exit(maru_dummy_exit); \ No newline at end of file
diff --git a/drivers/maru/tztv-dummy/maru_dummy.h b/drivers/maru/tztv-dummy/maru_dummy.h
new file mode 100644
index 000000000000..c61154dcb39a
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy.h
@@ -0,0 +1,52 @@
+/*
+ * MARU dummy driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Jinhyung Choi <jinh0.choi@samsung.com>
+ * Hyunjin Lee <hyunjin816.lee@samsung.com>
+ * SangHo Park <sangho.p@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef _MARU_DUMMY_H
+#define _MARU_DUMMY_H
+
+extern int dummy_driver_debug;
+
+#define maru_device_err(fmt, arg...) \
+ printk(KERN_ERR "[ERR][%s]: " fmt, __func__, ##arg)
+
+#define maru_device_warn(fmt, arg...) \
+ printk(KERN_WARNING "[WARN][%s]: " fmt, __func__, ##arg)
+
+#define maru_device_info(fmt, arg...) \
+ printk(KERN_INFO "[INFO][%s]: " fmt, __func__, ##arg)
+
+#define maru_device_dbg(log_level, fmt, arg...) \
+ do { \
+ if (dummy_driver_debug >= (log_level)) { \
+ printk(KERN_INFO "[DEBUG][%s]: " fmt, __func__, ##arg); \
+ } \
+ } while (0)
+
+#endif \ No newline at end of file
diff --git a/drivers/maru/tztv-dummy/maru_dummy_gpio.c b/drivers/maru/tztv-dummy/maru_dummy_gpio.c
new file mode 100644
index 000000000000..da39881e5f86
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy_gpio.c
@@ -0,0 +1,196 @@
+/*
+ * MARU Dummy GPIO driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Jinhyung Choi <jinh0.choi@samsung.com>
+ * SangHo Park <sangho.p@samsung.com>
+ *
+ * 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 2
+ * 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 License13
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
+#include <linux/platform_device.h>
+
+#include "maru_dummy.h"
+
+#define DRVNAME "maru_gpio"
+
+struct maru_gpio_dev {
+ int addr;
+};
+
+struct maru_gpio {
+ struct gpio_chip chip;
+ struct maru_gpio_dev *dev;
+};
+
+static int maru_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ maru_device_dbg(1, "gpio request offset : %u\n", offset);
+ return 0;
+}
+
+static int maru_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+ maru_device_dbg(1, "gpio direction in offset : %u\n", offset);
+ return 0;
+}
+
+static int maru_gpio_direction_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ maru_device_dbg(1, "gpio direction out offset : %u, value : %d\n", offset, value);
+ return 0;
+}
+
+static int maru_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ maru_device_dbg(1, "gpio get offset : %u\n", offset);
+ return 0;
+}
+
+static void maru_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ maru_device_dbg(1, "gpio set offset : %u, value : %d\n", offset, value);
+}
+
+static int maru_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ maru_device_dbg(1, "gpio to irq offset : %u\n", offset);
+ return 0;
+}
+
+static struct gpio_chip maru_gpio_chip = {
+ .label = DRVNAME,
+ .owner = THIS_MODULE,
+ .request = maru_gpio_request,
+ .direction_input = maru_gpio_direction_in,
+ .direction_output = maru_gpio_direction_out,
+ .get = maru_gpio_get,
+ .set = maru_gpio_set,
+ .to_irq = maru_gpio_to_irq,
+ .can_sleep = 1,
+ .ngpio = 255,
+ .base = 1,
+};
+
+static int maru_gpio_probe(struct platform_device *pdev)
+{
+ struct maru_gpio *maru_gpio;
+ int ret;
+
+ maru_gpio = devm_kzalloc(&pdev->dev, sizeof(*maru_gpio),
+ GFP_KERNEL);
+ if (maru_gpio == NULL){
+ maru_device_err("Could not allocate maru_gpio\n");
+ return -ENOMEM;
+ }
+
+ maru_gpio->chip = maru_gpio_chip;
+ maru_gpio->chip.dev = &pdev->dev;
+
+ ret = gpiochip_add(&maru_gpio->chip);
+ if (ret < 0) {
+ maru_device_err("Could not register maru gpiochip %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, maru_gpio);
+
+ maru_device_info("maru gpio device probe done.\n");
+
+ return ret;
+}
+
+void maru_gpio_remove(struct platform_device *pdev)
+{
+ struct maru_gpio *maru_gpio = platform_get_drvdata(pdev);
+
+ gpiochip_remove(&maru_gpio->chip);
+}
+
+static struct platform_device *maru_gpio_pdev;
+
+static int __init maru_gpio_device_add(const struct maru_gpio_dev *dev)
+{
+ int err;
+
+ maru_gpio_pdev = platform_device_alloc(DRVNAME, -1);
+ if (!maru_gpio_pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_data(maru_gpio_pdev, dev, sizeof(*dev));
+ if (err) {
+ maru_device_err("Platform data allocation failed\n");
+ goto err;
+ }
+
+ err = platform_device_add(maru_gpio_pdev);
+ if (err) {
+ maru_device_err("Device addition failed\n");
+ goto err;
+ }
+
+ maru_device_info("maru_gpio_device is added.\n");
+ return 0;
+err:
+ platform_device_put(maru_gpio_pdev);
+
+ return err;
+}
+
+static struct platform_driver maru_gpio_driver = {
+ .driver = {
+ .name = DRVNAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = maru_gpio_probe,
+ .remove = maru_gpio_remove,
+};
+
+static int __init maru_gpio_init(void)
+{
+ int err;
+ struct maru_gpio_dev dev;
+
+ err = platform_driver_register(&maru_gpio_driver);
+ if (!err) {
+ err = maru_gpio_device_add(&dev);
+ if (err)
+ platform_driver_unregister(&maru_gpio_driver);
+ }
+
+ return err;
+}
+subsys_initcall(maru_gpio_init);
+
+static void __exit maru_gpio_exit(void)
+{
+ platform_driver_unregister(&maru_gpio_driver);
+}
+module_exit(maru_gpio_exit);
+
+MODULE_AUTHOR("Jinhyung Choi");
+MODULE_DESCRIPTION("Maru Dummy GPIO driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/maru/tztv-dummy/maru_dummy_i2c_sdp.c b/drivers/maru/tztv-dummy/maru_dummy_i2c_sdp.c
new file mode 100644
index 000000000000..810b76999c0e
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy_i2c_sdp.c
@@ -0,0 +1,278 @@
+/*
+ * MARU Dummy I2C SDP driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Jinhyung Choi <jinh0.choi@samsung.com>
+ * SangHo Park <sangho.p@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <linux/semaphore.h>
+
+#include "maru_dummy.h"
+
+/* i2c controller state */
+enum sdp_i2c_state {
+ STATE_IDLE,
+ STATE_START,
+ STATE_READ,
+ STATE_WRITE,
+ STATE_STOP
+};
+
+struct sdp_platform_i2c {
+ int bus_num;
+ unsigned int flags;
+ unsigned int slave_addr;
+ unsigned long frequency;
+ unsigned int sda_delay;
+ unsigned int irq_reg;
+};
+
+struct sdp_i2c {
+ wait_queue_head_t wait;
+
+ struct i2c_msg *msg;
+ unsigned int msg_num;
+ unsigned int msg_idx;
+ unsigned int msg_ptr;
+
+ unsigned int tx_setup;
+ unsigned int irq;
+
+ enum sdp_i2c_state state;
+ unsigned long clkrate;
+
+ void __iomem *regs;
+ void __iomem *irq_reg;
+ struct clk *clk;
+ struct device *dev;
+ struct i2c_adapter adap;
+
+ struct sdp_platform_i2c *pdata;
+
+};
+
+static spinlock_t lock_pend;
+static spinlock_t lock_int;
+
+static int sdp_i2c_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num)
+{
+ maru_device_dbg(1, "sdp_i2c_xfer");
+ return 0;
+}
+
+static u32 sdp_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |
+ I2C_FUNC_PROTOCOL_MANGLING;
+}
+
+static const struct i2c_algorithm sdp_i2c_algorithm = {
+ .master_xfer = sdp_i2c_xfer,
+ .functionality = sdp_i2c_func,
+};
+
+static int sdp_i2c_get_irq_reg(struct sdp_i2c *i2c)
+{
+ struct sdp_platform_i2c *pdata;
+ pdata = i2c->pdata;
+
+ i2c->irq_reg = ioremap(pdata->irq_reg, 8);
+
+ if (!i2c->irq_reg) {
+ maru_device_err("Can't get interrupts status register\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int sdp_i2c_probe(struct platform_device *pdev)
+{
+ struct sdp_i2c *i2c;
+ struct sdp_platform_i2c *pdata = NULL;
+ int ret;
+
+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct sdp_i2c), GFP_KERNEL);
+ if (!i2c) {
+ maru_device_err("no memory for state\n");
+ return -ENOMEM;
+ }
+
+ i2c->pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!i2c->pdata) {
+ ret = -ENOMEM;
+ goto err_noclk;
+ }
+
+ spin_lock_init(&lock_pend);
+ spin_lock_init(&lock_int);
+
+ strlcpy(i2c->adap.name, "sdp-i2c", sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &sdp_i2c_algorithm;
+ i2c->adap.retries = 2;
+ i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ i2c->tx_setup = 50;
+
+ init_waitqueue_head(&i2c->wait);
+
+ i2c->dev = &pdev->dev;
+ i2c->clk = clk_get(&pdev->dev, "rstn_i2c");
+ if (IS_ERR(i2c->clk)) {
+ maru_device_err("cannot get clock\n");
+ ret = -ENOENT;
+ goto err_noclk;
+ }
+
+ clk_prepare_enable(i2c->clk);
+
+ i2c->adap.algo_data = i2c;
+ i2c->adap.dev.parent = &pdev->dev;
+
+ ret = sdp_i2c_get_irq_reg(i2c);
+ if (ret != 0)
+ goto err_clk;
+
+ i2c->adap.nr = 6;
+ ret = i2c_add_numbered_adapter(&i2c->adap);
+ if (ret < 0) {
+ maru_device_err("failed to add bus to i2c core\n");
+ goto err_irq;
+ }
+
+ platform_set_drvdata(pdev, i2c);
+
+ return 0;
+
+ err_irq:
+ free_irq(i2c->irq, i2c);
+
+ err_clk:
+ clk_disable_unprepare(i2c->clk);
+ clk_put(i2c->clk);
+
+ err_noclk:
+ return ret;
+}
+
+static int sdp_i2c_remove(struct platform_device *pdev)
+{
+ struct sdp_i2c *i2c = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c->adap);
+ free_irq(i2c->irq, i2c);
+
+ clk_disable_unprepare(i2c->clk);
+ clk_put(i2c->clk);
+
+ return 0;
+}
+
+static struct platform_driver sdp_i2c_driver = {
+ .probe = sdp_i2c_probe,
+ .remove = sdp_i2c_remove,
+ .driver = {
+ .name = "sdp-i2c",
+ .owner = THIS_MODULE,
+ },
+};
+
+struct maru_i2c_dev {
+ int addr;
+};
+
+static struct platform_device *maru_i2c_pdev;
+
+static int __init maru_i2c_device_add(const struct maru_i2c_dev *dev)
+{
+ int err;
+
+ maru_i2c_pdev = platform_device_alloc("sdp-i2c", -1);
+ if (!maru_i2c_pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_data(maru_i2c_pdev, dev, sizeof(*dev));
+ if (err) {
+ maru_device_err("Platform data allocation failed\n");
+ goto err;
+ }
+
+ err = platform_device_add(maru_i2c_pdev);
+ if (err) {
+ maru_device_err("Device addition failed\n");
+ goto err;
+ }
+
+ maru_device_info("maru_i2c_device is added.\n");
+ return 0;
+err:
+ platform_device_put(maru_i2c_pdev);
+
+ return err;
+}
+
+static int __init sdp_i2c_init(void)
+{
+ int err;
+
+ struct maru_i2c_dev dev;
+
+ err = platform_driver_register(&sdp_i2c_driver);
+ if (!err) {
+ err = maru_i2c_device_add(&dev);
+ if (err)
+ platform_driver_unregister(&sdp_i2c_driver);
+ }
+
+ return err;
+}
+subsys_initcall(sdp_i2c_init);
+
+static void __exit sdp_i2c_exit(void)
+{
+ platform_driver_unregister(&sdp_i2c_driver);
+}
+module_exit(sdp_i2c_exit);
+
+MODULE_AUTHOR("Jinhyung Choi");
+MODULE_DESCRIPTION("Maru Dummy I2C SDP driver");
+MODULE_LICENSE("GPL"); \ No newline at end of file
diff --git a/drivers/maru/tztv-dummy/maru_dummy_micom_isp.c b/drivers/maru/tztv-dummy/maru_dummy_micom_isp.c
new file mode 100644
index 000000000000..f12df2c7a905
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy_micom_isp.c
@@ -0,0 +1,269 @@
+/*
+ * MARU MICOM ISP
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Dongkyun Yun <dk77.yun@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/sched.h>
+#include <linux/cdev.h>
+
+#define DRIVER_NAME "isp-wt61p807"
+#define DEV_NAME "micom-isp"
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off maru micom isp debugging (default:off).");
+
+#define print_err(fmt, arg...) \
+ printk(KERN_ERR "[%s](%s)[%s:%d]: " fmt, DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+
+#define print_warn(fmt, arg...) \
+ printk(KERN_WARNING "[%s](%s)[%s:%d]: " fmt, DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+
+#define print_info(fmt, arg...) \
+ printk(KERN_INFO "[%s](%s)[%s:%d]: " fmt, DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+
+#define print_dbg(level, fmt, arg...) \
+ do { \
+ if (debug >= (level)) { \
+ printk(KERN_INFO "[%s](%s:%d)[%s:%d]: " fmt, DEV_NAME, \
+ __func__, __LINE__, current->comm, current->pid, ##arg); \
+ } \
+ } while (0)
+
+/* contains device information */
+struct wt61p807_isp_data {
+ struct cdev *isp_dev;
+ struct class *isp_class;
+ struct device *isp_device;
+ int micom_isp_major;
+ int ref_count;
+};
+
+struct wt61p807_isp_data *wt61p807_isp;
+
+/* static mutexes for micom isp driver */
+DEFINE_MUTEX(isp_dev_lock);
+
+/* global structures for wt61p807_isp_data and wt61p807_isp_cdev as those must
+ * be accessible from other functions ie.open, release etc.
+ */
+struct wt61p807_isp_data m_isp_dev;
+static struct cdev wt61p807_isp_cdev;
+
+/* micom isp file operations */
+static int micom_isp_open(struct inode *inode, struct file *filp);
+static int micom_isp_release(struct inode *inode, struct file *filp);
+static long micom_isp_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+/* file operations for micom isp device */
+const struct file_operations wt61p807_isp_fops = {
+ .owner = THIS_MODULE,
+ .open = micom_isp_open,
+ .unlocked_ioctl = micom_isp_ioctl,
+ .release = micom_isp_release,
+};
+
+/*
+ *
+ * @fn static int micom_isp_open(struct inode *inode, \
+ * struct file *filp);
+ * @brief opens micom isp device and returns file descriptor
+ * @details opens micom isp device and increments m_isp_dev_p->ref_count by
+ * one.
+ *
+ * @param inode pointer to device node's inode structure
+ * filp pointer to device node file
+ *
+ * @return returns file descriptor if device is opened successfully
+ */
+static int micom_isp_open(struct inode *inode, struct file *filp)
+{
+ struct wt61p807_isp_data *wt61p807_isp = &m_isp_dev;
+
+ /* acquire lock before setting is_open.*/
+ mutex_lock(&isp_dev_lock);
+
+ wt61p807_isp->ref_count++;
+ print_dbg(1, "reference count : %d\n", wt61p807_isp->ref_count);
+
+ /* Release lock*/
+ mutex_unlock(&isp_dev_lock);
+
+ return 0;
+}
+
+/* @fn static long micom_isp_ioctl(struct file *filp, \
+ * unsigned int cmd, unsigned long arg);
+ * @brief handles IOCTLs addressed to micom isp device and returns status
+ * @details valid IOCTLs:
+ * MICOM_MSG_IOCTL_SEND_MSG: Used to send messages
+ * containing normal data to micom device. It expects
+ * acknowledgement from the device.
+ * MICOM_MSG_IOCTL_SEND_MSG_NO_ACK: Used to send messages
+ * containing normal buffer data without expecting any
+ * acknowledgement from micom isp device.
+ *
+ * @param filp pointer to device node file
+ * cmd IOCTL command.
+ * arg argument to ioctl command (struct sdp_micom_usr_isp).
+ *
+ * @return returns status of IOCTL
+ * -EINVAL: if null arg is passed from user.
+ * -EFAULT: if copy_from_user() fails to copy
+ * -ERANGE: if micom command sent from user exceeds the
+ * defined max value (0xFF)
+ * zero: if suceess
+ */
+static long micom_isp_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ long status = 0;
+
+ print_dbg(1, "device ioctl \n");
+
+ return status;
+}
+
+/*
+ *
+ * @fn static int micom_isp_release(struct inode *inode, \
+ * struct file *filp);
+ * @brief closes micom isp device and returns status
+ * @details
+ *
+ * @param inode pointer to device node's inode structure
+ * filp pointer to device node file
+ *
+ * @return returns zero if device is closed
+ */
+static int micom_isp_release(struct inode *inode, struct file *filp)
+{
+
+ struct wt61p807_isp_data *wt61p807_isp = &m_isp_dev;
+
+ /* acquire lock before setting is_open.*/
+ mutex_lock(&isp_dev_lock);
+
+ wt61p807_isp->ref_count--;
+ print_dbg(1 , "reference count : %d\n", wt61p807_isp->ref_count);
+
+ /* Release lock*/
+ mutex_unlock(&isp_dev_lock);
+
+ return 0;
+}
+
+/* Device initialization routine */
+static int __init micom_isp_init(void)
+{
+ dev_t devid = 0;
+ int ret = -1;
+
+ print_info("called \n");
+
+ /* allocate char device region */
+ ret = alloc_chrdev_region(&devid, 0, 1, DRIVER_NAME);
+ if (ret) {
+ print_err("alloc_chrdev_region failed with %d\n", ret);
+ goto chrdev_alloc_fail;
+ }
+
+ /* initialize associated cdev and attach the file_operations */
+ cdev_init(&wt61p807_isp_cdev, &wt61p807_isp_fops);
+ /* add cdev to device */
+ ret = cdev_add(&wt61p807_isp_cdev, devid, 1);
+ if (ret) {
+ print_err("cdev_add failed with %d\n", ret);
+ goto cdev_add_fail;
+ }
+
+ wt61p807_isp = &m_isp_dev;
+
+ wt61p807_isp->isp_dev = &wt61p807_isp_cdev;
+ wt61p807_isp->micom_isp_major = MAJOR(devid);
+ wt61p807_isp->ref_count = 0;
+
+ wt61p807_isp->isp_class = class_create(THIS_MODULE, DRIVER_NAME);
+ if (IS_ERR(wt61p807_isp->isp_class)) {
+ print_err("failed to create sys class\n");
+ } else {
+ wt61p807_isp->isp_device = device_create(
+ wt61p807_isp->isp_class,
+ NULL, devid, NULL, DEV_NAME);
+ if (IS_ERR(wt61p807_isp->isp_device)) {
+ print_err("failed to create sys device\n");
+ class_destroy(wt61p807_isp->isp_class);
+ }
+ }
+
+ /* dynamic initialization of mutex for device */
+ mutex_init(&isp_dev_lock);
+
+ return ret;
+
+ /* cleaning up due to failure. */
+cdev_add_fail:
+ unregister_chrdev_region(devid, 1);
+chrdev_alloc_fail:
+ return ret;
+}
+
+/* Device exit routine */
+static void __exit micom_isp_exit(void)
+{
+ print_info("called \n");
+
+ mutex_destroy(&isp_dev_lock);
+
+ /* destroy micom isp sysfs device and class */
+ if (wt61p807_isp->isp_device != NULL) {
+ device_destroy(wt61p807_isp->isp_class,
+ MKDEV(wt61p807_isp->micom_isp_major, 0));
+ }
+ if (wt61p807_isp->isp_class != NULL)
+ class_destroy(wt61p807_isp->isp_class);
+
+ unregister_chrdev_region(MKDEV(m_isp_dev.micom_isp_major, 0), 1);
+ return;
+}
+
+/* define module init/exit, license */
+subsys_initcall(micom_isp_init);
+module_exit(micom_isp_exit);
+
+MODULE_DESCRIPTION("Micom driver interface for ISP data");
+MODULE_AUTHOR("Abhishek Jaiswal <abhishek1.j@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/maru/tztv-dummy/maru_dummy_micom_msg.c b/drivers/maru/tztv-dummy/maru_dummy_micom_msg.c
new file mode 100644
index 000000000000..a830e6232876
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy_micom_msg.c
@@ -0,0 +1,356 @@
+/*
+ * MARU MICOM MSG
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Dongkyun Yun <dk77.yun@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+/* internal Release1 */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/platform_device.h>
+
+#define DRIVER_NAME "msg-wt61p807"
+#define DEV_NAME "micom-msg"
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off maru micom msg debugging (default:off).");
+
+#define print_err(fmt, arg...) \
+ printk(KERN_ERR "[%s](%s)[%s:%d]: " fmt, DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+
+#define print_warn(fmt, arg...) \
+ printk(KERN_WARNING "[%s](%s)[%s:%d]: " fmt, DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+
+#define print_info(fmt, arg...) \
+ printk(KERN_INFO "[%s](%s)[%s:%d]: " fmt, DEV_NAME, __func__, \
+ current->comm, current->pid, ##arg);
+
+#define print_dbg(level, fmt, arg...) \
+ do { \
+ if (debug >= (level)) { \
+ printk(KERN_INFO "[%s](%s:%d)[%s:%d]: " fmt, DEV_NAME, \
+ __func__, __LINE__, current->comm, current->pid, ##arg); \
+ } \
+ } while (0)
+
+/* no of retries */
+#define ACK_RETRY_MAX 4
+
+/* static mutexes for micom msg device */
+DEFINE_MUTEX(dev_msg_lock);
+
+/* list of micom msg file operations prototypes. */
+static int micom_msg_open(struct inode *inode, struct file *filp);
+static int micom_msg_release(struct inode *inode, struct file *filp);
+static long micom_msg_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg);
+static ssize_t show_jack_ident(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t show_scart_lv_1(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t show_scart_lv_2(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t show_jack_ident_ready(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+/* file operations for micom msg device */
+const struct file_operations wt61p807_msg_fops = {
+ .owner = THIS_MODULE,
+ .open = micom_msg_open,
+ .unlocked_ioctl = micom_msg_ioctl,
+ .release = micom_msg_release,
+};
+
+struct wt61p807_msg_data {
+ struct cdev *msg_dev;
+ struct class *msg_class;
+ struct device *msg_device;
+ int micom_msg_major;
+ int ref_count;
+
+ int jack_ident;
+ int jack_ident_ready;
+ int scart_lv_1;
+ int scart_lv_2;
+};
+
+struct wt61p807_msg_data *wt61p807_msg;
+
+/* micom msg device specific data */
+struct wt61p807_msg_data m_msg_dev;
+
+/* micom msg cdev */
+struct cdev wt61p807_msg_cdev;
+
+static DEVICE_ATTR(jack_ident, S_IRUGO, show_jack_ident, NULL);
+static DEVICE_ATTR(scart_lv_1, S_IRUGO, show_scart_lv_1, NULL);
+static DEVICE_ATTR(scart_lv_2, S_IRUGO, show_scart_lv_2, NULL);
+static DEVICE_ATTR(jack_ident_ready, S_IRUGO,
+ show_jack_ident_ready, NULL);
+
+/*
+ *
+ * @fn static int micom_msg_open(struct inode *inode, \
+ * struct file *filp);
+ * @brief opens micom msg device and returns file descriptor
+ * @details opens micom msg device and increments m_msg_dev_p->ref_count.
+ *
+ * @param inode pointer to device node's inode structure
+ * filp pointer to device node file
+ *
+ * @return returns file descriptor if device is opened successfully
+ */
+static int micom_msg_open(struct inode *inode, struct file *filp)
+{
+ int ret = 0;
+ struct wt61p807_msg_data *m_msg_dev_p = &m_msg_dev;
+
+ /* acquire lock before opening device.*/
+ mutex_lock(&dev_msg_lock);
+
+ m_msg_dev_p->ref_count++;
+
+ print_dbg(1, "MSG device is opened. ref_count[%d]\n",
+ m_msg_dev_p->ref_count);
+
+ /* Release lock */
+ mutex_unlock(&dev_msg_lock);
+
+ return ret;
+}
+
+/*
+ *
+ * @fn static int micom_msg_release(struct inode *inode, \
+ * struct file *filp);
+ * @brief closes micom msg device and returns status
+ * @details
+ *
+ * @param inode pointer to device node's inode structure
+ * filp pointer to device node file
+ *
+ * @return returns zero if device is closed
+ */
+static int micom_msg_release(struct inode *inode, struct file *filp)
+{
+
+ int ret = 0;
+ struct wt61p807_msg_data *m_msg_dev_p = &m_msg_dev;
+
+ /* acquire lock before closing device.*/
+ mutex_lock(&dev_msg_lock);
+
+ m_msg_dev_p->ref_count--;
+
+ print_dbg(1, "MSG device is closed. ref_count[%d]\n",
+ m_msg_dev_p->ref_count);
+
+ /* Release lock*/
+ mutex_unlock(&dev_msg_lock);
+
+ return ret;
+}
+
+/*
+ *
+ * @fn static long micom_msg_ioctl(struct file *filp, \
+ * unsigned int cmd, unsigned long arg);
+ * @brief handles IOCTLs addressed to micom msg device and returns status
+ * @details valid IOCTLs:
+ * MICOM_MSG_IOCTL_SEND_MSG: Used to send messages
+ * containing normal data to micom device. It expects
+ * acknowledgement from the device.
+ * MICOM_MSG_IOCTL_SEND_MSG_NO_ACK: Used to send messages
+ * containing normal buffer data without expecting any
+ * acknowledgement from micom msg device.
+ *
+ * @param filp pointer to device node file
+ * cmd IOCTL command.
+ * arg argument to ioctl command (struct sdp_micom_usr_msg).
+ *
+ * @return returns status of IOCTL
+ * -EINVAL: if null arg is passed from user.
+ * -EFAULT: if copy_from_user() fails to copy
+ * -ERANGE: if micom command sent from user exceeds the
+ * defined max value (0xFF)
+ * zero: if suceess
+ */
+static long micom_msg_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ long status = 0;
+
+ print_dbg(1, "MSG device ioctl \n");
+
+ return status;
+}
+
+static ssize_t show_jack_ident(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ print_dbg(1, "\n");
+ return snprintf(buf, sizeof(int), "%d", m_msg_dev.jack_ident);
+}
+
+static ssize_t show_scart_lv_1(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ print_dbg(1, "\n");
+ return snprintf(buf, sizeof(int), "%d", m_msg_dev.scart_lv_1);
+}
+
+static ssize_t show_scart_lv_2(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ print_dbg(1, "\n");
+ return snprintf(buf, sizeof(int), "%d", m_msg_dev.scart_lv_2);
+}
+
+static ssize_t show_jack_ident_ready(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ print_dbg(1, "\n");
+ return snprintf(buf, sizeof(int), "%d", m_msg_dev.jack_ident_ready);
+}
+
+/* Device initialization routine */
+static int __init micom_msg_init(void)
+{
+ dev_t devid = 0;
+ int ret = -1;
+
+ print_info("called \n");
+
+ /* allocate char device region */
+ ret = alloc_chrdev_region(&devid, 0, 1, DRIVER_NAME);
+ if (ret) {
+ print_err("alloc_chrdev_region failed with %d\n", ret);
+ goto chrdev_alloc_fail;
+ }
+
+ /* initialize associated cdev and attach the file_operations */
+ cdev_init(&wt61p807_msg_cdev, &wt61p807_msg_fops);
+ /* add cdev to device */
+ ret = cdev_add(&wt61p807_msg_cdev, devid, 1);
+ if (ret) {
+ print_err("cdev_add failed with %d\n", ret);
+ goto cdev_add_fail;
+ }
+
+ wt61p807_msg = &m_msg_dev;
+
+ wt61p807_msg->msg_dev = &wt61p807_msg_cdev;
+ wt61p807_msg->micom_msg_major = MAJOR(devid);
+ wt61p807_msg->ref_count = 0;
+
+ wt61p807_msg->msg_class = class_create(THIS_MODULE, DEV_NAME);
+ if (IS_ERR(wt61p807_msg->msg_class)) {
+ print_err("failed to create sys class\n");
+ } else {
+ wt61p807_msg->msg_device = device_create(
+ wt61p807_msg->msg_class,
+ NULL, devid, NULL, DEV_NAME);
+ if (IS_ERR(wt61p807_msg->msg_device)) {
+ print_err("failed to create sys device\n");
+ class_destroy(wt61p807_msg->msg_class);
+ }
+ }
+
+ ret = device_create_file(wt61p807_msg->msg_device,
+ &dev_attr_jack_ident);
+ if (ret) {
+ print_err("failed to create sysfs files (ret = %d) \n", ret);
+ goto dev_fail;
+ }
+ ret = device_create_file(wt61p807_msg->msg_device,
+ &dev_attr_scart_lv_1);
+ if (ret) {
+ print_err("failed to create sysfs files (ret = %d) \n", ret);
+ goto dev_fail;
+ }
+ ret = device_create_file(wt61p807_msg->msg_device,
+ &dev_attr_scart_lv_2);
+ if (ret) {
+ print_err("failed to create sysfs files (ret = %d) \n", ret);
+ goto dev_fail;
+ }
+ ret = device_create_file(wt61p807_msg->msg_device,
+ &dev_attr_jack_ident_ready);
+ if (ret) {
+ print_err("failed to create sysfs files (ret = %d) \n", ret);
+ goto dev_fail;
+ }
+
+ /* dynamic initialization of mutex for device */
+ mutex_init(&dev_msg_lock);
+
+ return ret;
+
+dev_fail:
+cdev_add_fail:
+ unregister_chrdev_region(devid, 1);
+chrdev_alloc_fail:
+ return ret;
+}
+
+/* Device exit routine */
+static void __exit micom_msg_exit(void)
+{
+ print_info("called \n");
+
+ mutex_destroy(&dev_msg_lock);
+
+ /* destroy micom msg sysfs device and class */
+ if (wt61p807_msg->msg_device != NULL) {
+ device_destroy(wt61p807_msg->msg_class,
+ MKDEV(wt61p807_msg->micom_msg_major, 0));
+ }
+ if (wt61p807_msg->msg_class != NULL)
+ class_destroy(wt61p807_msg->msg_class);
+
+ unregister_chrdev_region(MKDEV(wt61p807_msg->micom_msg_major, 0), 1);
+ return;
+}
+
+/* define module init/exit, license */
+subsys_initcall(micom_msg_init);
+module_exit(micom_msg_exit);
+
+MODULE_DESCRIPTION("Micom driver interface for Normal buffer data");
+MODULE_AUTHOR("Abhishek Jaiswal <abhishek1.j@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/maru/tztv-dummy/maru_dummy_sdp_mem.c b/drivers/maru/tztv-dummy/maru_dummy_sdp_mem.c
new file mode 100644
index 000000000000..f9372b8c6d71
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy_sdp_mem.c
@@ -0,0 +1,174 @@
+/*
+ * MARU SDP Memory Driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Dongkyun Yun <dk77.yun@samsung.com>
+ * Jinhyung Choi <jinh0.choi@samsung.com>
+ * Hyunjin Lee <hyunjin816.lee@samsung.com>
+ * SangHo Park <sangho.p@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+#include <linux/miscdevice.h>
+#include <linux/vmalloc.h>
+
+#include "maru_dummy.h"
+
+#define DRV_NAME "sdp_mem"
+#define SDP_MEM_MINOR 193
+
+static LIST_HEAD(region_list);
+static DEFINE_MUTEX(region_mutex);
+
+struct sdp_mem_region
+{
+ struct list_head list;
+ unsigned long vm_pgoff;
+ unsigned long size;
+ void *vaddr;
+};
+
+static int
+sdp_mem_mmap(struct file * file, struct vm_area_struct * vma)
+{
+ int ret;
+ unsigned long size = vma->vm_end - vma->vm_start;
+ struct sdp_mem_region *region;
+ int pages;
+
+ maru_device_dbg(1, "[%d:%s] \n", current->pid, current->comm);
+
+ mutex_lock(&region_mutex);
+
+ list_for_each_entry(region, &region_list, list) {
+ if( region->vm_pgoff == vma->vm_pgoff ) {
+ if( region->size != size ) {
+ maru_device_err("size mismatch \n");
+ /* TODO: use first mapping size */
+ size = region->size;
+ }
+ maru_device_dbg(1, "pgoff %lx found \n", vma->vm_pgoff);
+ goto found;
+ }
+ }
+
+ maru_device_dbg(1, "pgoff %lx not found \n", vma->vm_pgoff);
+
+ region = kzalloc(sizeof(struct sdp_mem_region), GFP_KERNEL);
+ if (!region) {
+ maru_device_err("kzalloc fail \n");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ region->vm_pgoff = vma->vm_pgoff;
+ region->size = size;
+
+ pages = PAGE_ALIGN(size);
+ region->vaddr = vmalloc_user(pages);
+ if (!region->vaddr) {
+ maru_device_err("vmalloc_user fail \n");
+ kfree(region);
+ ret = -ENOMEM;
+ goto error;
+ }
+ list_add_tail(&region->list, &region_list);
+
+ maru_device_dbg(1, "vaddr(%p) with size(%lu) \n", region->vaddr, size);
+
+found:
+
+ /* Try to remap memory */
+ ret = remap_vmalloc_range(vma, region->vaddr, 0);
+ if (ret) {
+ maru_device_err("remap_vmalloc_range failed (ret:%d) \n", ret);
+ goto error;
+ }
+
+ maru_device_info("%s/%d mmap phy addr(0x%lx, size:%lu) to 0x%p\n",
+ current->comm, current->pid, vma->vm_pgoff, size, region->vaddr);
+
+error:
+ mutex_unlock(&region_mutex);
+ return ret;
+}
+
+static int sdp_mem_open(struct inode *inode, struct file *file)
+{
+ maru_device_dbg(1, "open\n");
+ return 0;
+}
+
+
+static int sdp_mem_close(struct inode *inode, struct file *file)
+{
+ maru_device_dbg(1, "close\n");
+ return 0;
+}
+
+static const struct file_operations sdp_mem_fops = {
+ .owner = THIS_MODULE,
+ .open = sdp_mem_open,
+ .release = sdp_mem_close,
+ .mmap = sdp_mem_mmap,
+};
+
+static struct miscdevice sdp_mem_dev = {
+ .minor = SDP_MEM_MINOR,
+ .name = DRV_NAME,
+ .fops = &sdp_mem_fops
+};
+
+static int __init maru_sdp_mem_init(void)
+{
+ int ret_val = 0;
+
+ ret_val = misc_register(&sdp_mem_dev);
+
+ if(ret_val){
+ maru_device_err("misc_register is failed.");
+ return ret_val;
+ }
+
+ maru_device_info("sdp_mem initialized.");
+
+ return ret_val;
+}
+
+static void __exit maru_sdp_mem_exit(void)
+{
+ misc_deregister(&sdp_mem_dev);
+}
+
+module_init(maru_sdp_mem_init);
+module_exit(maru_sdp_mem_exit);
diff --git a/drivers/maru/tztv-dummy/maru_dummy_security.c b/drivers/maru/tztv-dummy/maru_dummy_security.c
new file mode 100644
index 000000000000..59e9ee792e80
--- /dev/null
+++ b/drivers/maru/tztv-dummy/maru_dummy_security.c
@@ -0,0 +1,202 @@
+/*
+ * MARU security driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hyunjin Lee <hyunjin816.lee@samsung.com>
+ * SangHo Park <sangho1206.park@samsung.com>
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/pagemap.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <linux/interrupt.h>
+
+#define SECURITY_DEV_NAME "security"
+
+static unsigned security_debug = 0;
+static struct class *security_class;
+static struct cdev security_cdev;
+dev_t security_dev;
+
+module_param(security_debug, int, 0644);
+MODULE_PARM_DESC(security_debug, "Turn on/off maru security debugging (default:off).");
+
+#define maru_security_err(fmt, arg...) \
+ printk(KERN_ERR "[ERR]maru_security[%s]: " fmt, __func__, ##arg)
+
+#define maru_security_warn(fmt, arg...) \
+ printk(KERN_WARNING "[WARN]maru_security[%s]: " fmt, __func__, ##arg)
+
+#define maru_security_info(fmt, arg...) \
+ printk(KERN_INFO "[INFO]maru_security[%s]: " fmt, __func__, ##arg)
+
+#define maru_security_dbg(level, fmt, arg...) \
+ do { \
+ if (security_debug >= (level)) { \
+ printk(KERN_ERR "[DBG]maru_security[%s]: " fmt, \
+ __func__, ##arg); \
+ } \
+ } while (0)
+#define SECURITY_G_SEQNUM _IOR('S', 0, unsigned int)
+
+struct security_information {
+ unsigned int seq_num;
+};
+
+/* -----------------------------------------------------------------
+ file operations
+ ------------------------------------------------------------------*/
+static int maru_security_open(struct inode *inode, struct file *file)
+{
+ int ret = 0;
+ struct security_information *sec_info;
+
+ maru_security_dbg(5, "[security]enter.\n");
+
+ sec_info = kzalloc(sizeof(struct security_information), GFP_KERNEL);
+ if (!sec_info) {
+ maru_security_err("kzalloc() failed\n");
+ ret = -ENOMEM;
+ goto enomem;
+ }
+
+ sec_info->seq_num = 0;
+ file->private_data = sec_info;
+
+enomem:
+ return ret;
+}
+
+static long maru_security_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+ struct security_information *sec_info = file->private_data;
+ int __user *data = (int __user *)arg;
+
+ switch (cmd) {
+ case SECURITY_G_SEQNUM:
+ ret = copy_to_user(data, &sec_info->seq_num, sizeof(unsigned int));
+ if (ret) {
+ ret = -EFAULT;
+ break;
+ }
+ sec_info->seq_num++;
+ break;
+ default:
+ maru_security_info("[security] unsupported command : %08x.\n", cmd);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int maru_security_close(struct inode *inode, struct file *file)
+{
+ struct security_information *sec_info = file->private_data;
+
+ maru_security_dbg(5, "[security]enter.\n");
+
+ if (sec_info) {
+ kfree(sec_info);
+ sec_info = NULL;
+ }
+
+ return 0;
+}
+
+static const struct file_operations maru_security_fops = {
+ .open = maru_security_open,
+ .unlocked_ioctl = maru_security_ioctl,
+ .release = maru_security_close,
+};
+
+/* -----------------------------------------------------------------
+ Initialization
+ ------------------------------------------------------------------*/
+static int __init maru_security_init(void)
+{
+ int ret = 0;
+
+ /* allocate character device */
+ ret = alloc_chrdev_region(&security_dev, 0, 1, SECURITY_DEV_NAME);
+ if (ret < 0) {
+ maru_security_err("security alloc_chrdev_region failed.\n");
+ goto alloc_chrdev_region_err;
+ }
+
+ /* create class */
+ security_class = class_create(THIS_MODULE, SECURITY_DEV_NAME);
+ if (IS_ERR(security_class)) {
+ ret = PTR_ERR(security_class);
+ maru_security_err("create security class failed.\n");
+ goto create_class_err;
+ }
+
+ /* character device initialize */
+ cdev_init(&security_cdev, &maru_security_fops);
+
+ ret = cdev_add(&security_cdev, security_dev, 1);
+ if (ret < 0) {
+ maru_security_err("security cdev_add failed\n");
+ goto cdev_add_err;
+ }
+
+ /* create device */
+ device_create(security_class, 0, security_dev, NULL, "%s", SECURITY_DEV_NAME);
+
+ maru_security_info("security driver was registerd.\n");
+
+ return ret;
+
+cdev_add_err:
+ class_destroy(security_class);
+create_class_err:
+ unregister_chrdev_region(security_dev, 1);
+alloc_chrdev_region_err:
+ return ret;
+}
+
+static void __exit maru_security_exit(void)
+{
+ cdev_del(&security_cdev);
+ class_destroy(security_class);
+ unregister_chrdev_region(security_dev, 1);
+
+ maru_security_info("security driver was exited.\n");
+}
+
+module_init(maru_security_init);
+module_exit(maru_security_exit); \ No newline at end of file