TV: Add dummy driver for TV Emulator
authorHyun myung Cho <hm83.cho@samsung.com>
Thu, 30 Jun 2016 07:01:46 +0000 (16:01 +0900)
committerHyun myung Cho <hm83.cho@samsung.com>
Thu, 30 Jun 2016 07:01:46 +0000 (16:01 +0900)
Change-Id: I09cb1b1a5b4b45a2b743218b552603685ae1c1e5
Signed-off-by: Hyun myung Cho <hm83.cho@samsung.com>
14 files changed:
arch/x86/configs/tizen_emul_defconfig
drivers/maru/Kconfig
drivers/maru/Makefile
drivers/maru/maru_eeprom.c [new file with mode: 0644]
drivers/maru/maru_eeprom.h [new file with mode: 0644]
drivers/maru/tztv-dummy/Makefile [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy.c [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy.h [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy_gpio.c [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy_i2c_sdp.c [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy_micom_isp.c [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy_micom_msg.c [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy_sdp_mem.c [new file with mode: 0644]
drivers/maru/tztv-dummy/maru_dummy_security.c [new file with mode: 0644]

index d518262..76806ae 100644 (file)
@@ -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
 
 #
index 623b349..efe0710 100644 (file)
@@ -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
index 5b2d497..a1627f8 100644 (file)
@@ -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 (file)
index 0000000..9baccf0
--- /dev/null
@@ -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 (file)
index 0000000..6d750f6
--- /dev/null
@@ -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 (file)
index 0000000..32e9052
--- /dev/null
@@ -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 (file)
index 0000000..725490e
--- /dev/null
@@ -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 (file)
index 0000000..c61154d
--- /dev/null
@@ -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 (file)
index 0000000..da39881
--- /dev/null
@@ -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 (file)
index 0000000..810b769
--- /dev/null
@@ -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 (file)
index 0000000..f12df2c
--- /dev/null
@@ -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 (file)
index 0000000..a830e62
--- /dev/null
@@ -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 (file)
index 0000000..f9372b8
--- /dev/null
@@ -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 (file)
index 0000000..59e9ee7
--- /dev/null
@@ -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