tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / media / sprd_sensor / compat_sensor_drv_k.c
1 /*\r * Copyright (C) 2012 Spreadtrum Communications Inc.\r *\r * This software is licensed under the terms of the GNU General Public\r * License version 2, as published by the Free Software Foundation, and\r * may be copied, distributed, and modified under those terms.\r *\r * This program is distributed in the hope that it will be useful,\r * but WITHOUT ANY WARRANTY; without even the implied warranty of\r * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r * GNU General Public License for more details.\r */\r#include <linux/compat.h>\r#include <linux/fs.h>\r#include <linux/uaccess.h>\r#include <video/sensor_drv_k.h>\r#include "compat_sensor_drv_k.h"\r//#define DEBUG_COMPAT_SENSOR_DRV\r#ifdef  DEBUG_COMPAT_SENSOR_DRV\r#define COMPAT_SENSOR_PRINT                      printk\r#else\r#define COMPAT_SENSOR_PRINT(...)\r#endif\rstruct compat_sensor_reg_tab_tag {\r   compat_caddr_t sensor_reg_tab_ptr;\r     uint32_t reg_count;\r    uint32_t reg_bits;\r     uint32_t burst_mode;\r};\rstruct compat_sensor_i2c_tag {\r compat_caddr_t i2c_data;\r       uint16_t i2c_count;\r    uint16_t slave_addr;\r};\r\rstruct compat_sensor_otp_data_info_tag {\r      uint32_t size;\r compat_caddr_t data_ptr;\r};\rstruct compat_sensor_otp_param_tag {\r       uint32_t start_addr;\r   uint32_t len;\r  compat_caddr_t buff;\r   struct compat_sensor_otp_data_info_tag golden;\r struct compat_sensor_otp_data_info_tag awb;\r    struct compat_sensor_otp_data_info_tag lsc;\r    uint32_t type;\r};\r\r#define COMPAT_SENSOR_IO_I2C_WRITE_REGS    _IOW(SENSOR_IOC_MAGIC,  14, struct compat_sensor_reg_tab_tag)\r#define COMPAT_SENSOR_IO_I2C_WRITE_EXT     _IOW(SENSOR_IOC_MAGIC,  17, struct compat_sensor_i2c_tag)\r#define COMPAT_SENSOR_IO_I2C_READ_EXT      _IOWR(SENSOR_IOC_MAGIC, 20, struct compat_sensor_i2c_tag)\r#define COMPAT_SENSOR_IO_READ_OTPDATA      _IOWR(SENSOR_IOC_MAGIC, 254,struct compat_sensor_otp_param_tag)\r\rstatic long compat_get_sensor_reg_tab_tag(\r                   struct compat_sensor_reg_tab_tag __user *data32,\r                       struct sensor_reg_tab_tag __user *data)\r{\r      compat_caddr_t c;\r      uint32_t i;\r    int err;\r       err = get_user(c, &data32->sensor_reg_tab_ptr);\r        err |= put_user(c, &data->sensor_reg_tab_ptr);\r err |= get_user(i, &data32->reg_count);\r        err |= put_user(i, &data->reg_count);\r  err |= get_user(i, &data32->reg_bits);\r err |= put_user(i, &data->reg_bits);\r   err |= get_user(i, &data32->burst_mode);\r       err |= put_user(i, &data->burst_mode);\r COMPAT_SENSOR_PRINT("sensor_reg_tab_ptr: %p reg_count: %d reg_bits: %d burst_mode: %d\n",\r              data->sensor_reg_tab_ptr, data->reg_count, data->reg_bits, data->burst_mode);\r  return err;\r}\r\rstatic long compat_get_sensor_i2c_tag(\r                  struct compat_sensor_i2c_tag __user *data32,\r                   struct sensor_i2c_tag __user *data)\r{\r  compat_caddr_t c;\r      uint16_t i;\r    int err;\r       err = get_user(c, &data32->i2c_data);\r  err |= put_user(c, &data->i2c_data);\r   err |= get_user(i, &data32->i2c_count);\r        err |= put_user(i, &data->i2c_count);\r  err |= get_user(i, &data32->slave_addr);\r       err |= put_user(i, &data->slave_addr);\r COMPAT_SENSOR_PRINT("i2c_data: %p i2c_count: %d slave_addr: %d\n",\r             data->i2c_data, data->i2c_count, data->slave_addr);\r    return err;\r}\r\rstatic long compat_get_otp_param_tag(\r                   struct compat_sensor_otp_param_tag __user *data32,\r                     struct _sensor_otp_param_tag __user *data)\r{\r   compat_caddr_t c;\r      uint32_t i;\r    int err;\r\r      err = get_user(i, &data32->start_addr);\r        err |= put_user(i, &data->start_addr);\r err |= get_user(i, &data32->len);\r      err |= put_user(i, &data->len);\r        err |= get_user(c, &data32->buff);\r     err |= put_user(c, &data->buff);\r\r      err |= get_user(c, &data32->awb.data_ptr);\r     err |= put_user(c, &data->awb.data_ptr);\r       err |= get_user(i, &data32->awb.size);\r err |= put_user(i, &data->awb.size);\r\r  err |= get_user(c, &data32->lsc.data_ptr);\r     err |= put_user(c, &data->lsc.data_ptr);\r       err |= get_user(i, &data32->lsc.size);\r err |= put_user(i, &data->lsc.size);\r   return err;\r}\rlong compat_sensor_k_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)\r{\r     int compatible_arg = 1;\r        long err = 0;\r  if (!filp->f_op || !filp->f_op->unlocked_ioctl)\r                return -ENOTTY;\r        switch (cmd) {\r case COMPAT_SENSOR_IO_I2C_WRITE_REGS:\r  {\r              struct compat_sensor_reg_tab_tag __user *data32;\r               struct sensor_reg_tab_tag __user *data;\r                data32 = compat_ptr(arg);\r              data = compat_alloc_user_space(sizeof(*data));\r         if (NULL == data)\r                      return -EFAULT;\r                err = compat_get_sensor_reg_tab_tag(data32, data);\r             if (err)\r                       return err;\r            return filp->f_op->unlocked_ioctl(filp, SENSOR_IO_I2C_WRITE_REGS,\r                                                              (unsigned long)data);\r  }\r      case COMPAT_SENSOR_IO_I2C_WRITE_EXT:\r   {\r              struct compat_sensor_i2c_tag __user *data32;\r           struct sensor_i2c_tag __user *data;\r            data32 = compat_ptr(arg);\r              data = compat_alloc_user_space(sizeof(*data));\r         if (NULL == data)\r                      return -EFAULT;\r                err = compat_get_sensor_i2c_tag(data32, data);\r         if (err)\r                       return err;\r            return filp->f_op->unlocked_ioctl(filp, SENSOR_IO_I2C_WRITE_EXT,\r                                                               (unsigned long)data);\r  }\r      case COMPAT_SENSOR_IO_I2C_READ_EXT:\r    {\r              struct compat_sensor_i2c_tag __user *data32;\r           struct sensor_i2c_tag __user *data;\r            data32 = compat_ptr(arg);\r              data = compat_alloc_user_space(sizeof(*data));\r         if (NULL == data)\r                      return -EFAULT;\r                err = compat_get_sensor_i2c_tag(data32, data);\r         if (err)\r                       return err;\r            return filp->f_op->unlocked_ioctl(filp, SENSOR_IO_I2C_READ_EXT,\r                                                                (unsigned long)data);\r  }\r\r     case COMPAT_SENSOR_IO_READ_OTPDATA:\r    {\r              struct compat_sensor_otp_param_tag __user *data32;\r             SENSOR_OTP_PARAM_T __user *data;\r\r              printk("SENSOR: ioctl COMPAT_SENSOR_IO_READ_OTPDATA \n");\r              data32 = compat_ptr(arg);\r              data = compat_alloc_user_space(sizeof(*data));\r         if (NULL == data)\r                      return -EFAULT;\r\r               err = compat_get_otp_param_tag(data32, data);\r          if (err)\r                       return err;\r            return filp->f_op->unlocked_ioctl(filp, SENSOR_IO_READ_OTPDATA,\r                                                                (unsigned long)data);\r  }\r      break;\r\r        default:\r               return filp->f_op->unlocked_ioctl(filp, cmd,\r                                           (unsigned long)compat_ptr(arg));\r       }\r}\r