media: video: tegra: support multiple cameras
Jihoon Bang [Fri, 24 Jun 2011 17:05:32 +0000 (10:05 -0700)]
Separate board specific sequence from ar0832 driver and add it to board
files. Add function that changes device slave address in real time to support
multiple devices in the same I2C bus.

Bug 844021

Original-Change-Id: I48641909eb531b4ba827096bc30fa4eccf83469e
Reviewed-on: http://git-master/r/40385
Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com>
Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Tested-by: Jihoon Bang <jbang@nvidia.com>

Rebase-Id: R4b761bd3b09ed2b0101b03e8be737c25e5c3ee5f

drivers/media/video/tegra/ar0832_main.c
include/media/ar0832_main.h

index e4a144a..1fb9315 100644 (file)
 #include <mach/hardware.h>
 #include <linux/gpio.h>
 #include <asm/atomic.h>
-
+#include <linux/regulator/consumer.h>
 #include <media/ar0832_main.h>
 
-#define USE_I2C_DATA_2BYTES
-
 #define POS_LOW 50
 #define POS_HIGH 1000
 #define SETTLETIME_MS 100
@@ -37,6 +35,11 @@ struct ar0832_focuser_info {
        int focuser_init_flag;
 };
 
+struct ar0832_power_rail {
+       struct regulator *sen_1v8_reg;
+       struct regulator *sen_2v8_reg;
+};
+
 struct ar0832_dev {
        struct ar0832_sensor_info *sensor_info;
        struct ar0832_focuser_info *focuser_info;
@@ -44,7 +47,10 @@ struct ar0832_dev {
        struct i2c_client *i2c_client;
        struct mutex ar0832_camera_lock;
        struct miscdevice misc_dev;
+       struct ar0832_power_rail power_rail;
        atomic_t in_use;
+       char dname[20];
+       int is_stereo;
 };
 
 /* stereo */
@@ -57,7 +63,23 @@ static u16 DefaultImageHeight =  680;
 #define ar0832_TABLE_END 1
 #define ar0832_MAX_RETRIES 3
 
-#define USE_DIGITAL_GAIN 0
+#define AR0832_RESET_REG       0x301A
+#define AR0832_ID_REG          0x31FC
+
+/* AR0832_RESET_REG */
+#define AR0832_RESET_REG_GROUPED_PARAMETER_HOLD                (1 << 15)
+#define AR0832_RESET_REG_GAIN_INSERT                   (1 << 14)
+#define AR0832_RESET_REG_SMIA_SERIALIZER_DIS           (1 << 12)
+#define AR0832_RESET_REG_RESTART_BAD                   (1 << 10)
+#define AR0832_RESET_REG_MASK_BAD                      (1 << 9)
+#define AR0832_RESET_REG_GPI_EN                                (1 << 8)
+#define AR0832_RESET_REG_PARALLEL_EN                   (1 << 7)
+#define AR0832_RESET_REG_DRIVE_PINS                    (1 << 6)
+#define AR0832_RESET_REG_STDBY_EOF                     (1 << 4)
+#define AR0832_RESET_REG_LOCK_REG                      (1 << 3)
+#define AR0832_RESET_REG_STREAM                                (1 << 2)
+#define AR0832_RESET_REG_RESTART                       (1 << 1)
+#define AR0832_RESET_REG_RESET                         (1 << 0)
 
 static struct ar0832_reg mode_start[] = {
        {ar0832_TABLE_END, 0x0000}
@@ -568,6 +590,8 @@ static int ar0832_write_reg8(struct i2c_client *client, u16 addr, u8 val)
        msg.len = 3;
        msg.buf = data;
 
+       dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, val);
+
        do {
                err = i2c_transfer(client->adapter, &msg, 1);
                if (err > 0)
@@ -602,6 +626,8 @@ static int ar0832_write_reg16(struct i2c_client *client, u16 addr, u16 val)
        msg.len = 4;
        msg.buf = data;
 
+       dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, val);
+
        do {
                count = i2c_transfer(client->adapter, &msg, 1);
                if (count == 1)
@@ -616,6 +642,34 @@ static int ar0832_write_reg16(struct i2c_client *client, u16 addr, u16 val)
        return -EIO;
 }
 
+static int ar0832_read_reg16(struct i2c_client *client, u16 addr, u16 *val)
+{
+       struct i2c_msg msg[2];
+       u8 data[4];
+
+       msg[0].addr = client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 2;
+       msg[0].buf = data;
+       data[0] = (addr >> 8);
+       data[1] = (addr & 0xff);
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 2;
+       msg[1].buf = data + 2;
+
+       if (i2c_transfer(client->adapter, msg, 2) == 2) {
+               *val = ((data[2] << 8) | data[3]);
+               dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, *val);
+               return 0;
+       } else {
+               *val = 0;
+               dev_err(&client->dev,
+                       "%s: i2c read failed.\n", __func__);
+               return -1;
+       }
+}
+
 static int ar0832_write_reg_helper(struct ar0832_dev *dev,
                                        u16 addr,
                                        u16 val)
@@ -658,7 +712,7 @@ static int ar0832_set_frame_length(struct ar0832_dev *dev,
        struct i2c_client *i2c_client = dev->i2c_client;
        int ret;
 
-       dev_info(&i2c_client->dev, "[%s] (0x%08x)\n", __func__,  frame_length);
+       dev_dbg(&i2c_client->dev, "[%s] (0x%08x)\n", __func__,  frame_length);
 
        ar0832_get_frame_length_regs(&reg_list, frame_length);
        ret = ar0832_write_reg8(i2c_client, 0x0104, 0x1);
@@ -684,7 +738,7 @@ static int ar0832_set_coarse_time(struct ar0832_dev *dev,
        struct ar0832_reg reg_list;
        struct i2c_client *i2c_client = dev->i2c_client;
 
-       dev_info(&i2c_client->dev, "[%s] (0x%08x)\n", __func__,  coarse_time);
+       dev_dbg(&i2c_client->dev, "[%s] (0x%08x)\n", __func__,  coarse_time);
        ar0832_get_coarse_time_regs(&reg_list, coarse_time);
 
        ret = ar0832_write_reg8(i2c_client, 0x0104, 0x1);
@@ -721,6 +775,8 @@ static int ar0832_set_gain(struct ar0832_dev *dev, __u16 gain)
        }
        /* Gain register End */
        ret |= ar0832_write_reg8(dev->i2c_client, 0x0104, 0x0);
+
+       return ret;
 }
 
 static int ar0832_set_mode(struct ar0832_dev *dev,
@@ -732,6 +788,8 @@ static int ar0832_set_mode(struct ar0832_dev *dev,
        struct i2c_client *i2c_client = dev->i2c_client;
        struct ar0832_reg reg_frame_length, reg_coarse_time;
 
+       dev_info(&i2c_client->dev, "%s: ++\n", __func__);
+
        if (mode->xres == 3264 && mode->yres == 2448)
                sensor_mode = ar0832_MODE_3264X2448;
        else if (mode->xres == 2880 && mode->yres == 1620)
@@ -777,7 +835,8 @@ static int ar0832_set_mode(struct ar0832_dev *dev,
                return err;
 
        dev->sensor_info->mode = sensor_mode;
-       dev_info(&i2c_client->dev, "%s: end\n", __func__);
+       dev_dbg(&i2c_client->dev, "%s: --\n", __func__);
+
        return 0;
 }
 
@@ -791,7 +850,7 @@ static int ar0832_get_status(struct ar0832_dev *dev, u8 *status)
        /*
        err = ar0832_read_reg(dev->i2c_client, 0x001, status);
        */
-       dev_info(&i2c_client->dev, "%s: %u %d\n", __func__, *status, err);
+       dev_dbg(&i2c_client->dev, "%s: %u %d\n", __func__, *status, err);
        return err;
 }
 
@@ -802,7 +861,7 @@ static int ar0832_set_region(struct ar0832_dev *dev,
        u16 image_height = region->image_end.y - region->image_start.y+1;
        struct i2c_client *i2c_client = dev->i2c_client;
 
-       dev_info(&i2c_client->dev, "%s: %d\n", __func__, region->camera_index);
+       dev_dbg(&i2c_client->dev, "%s: %d\n", __func__, region->camera_index);
        if (region->camera_index == 0)
                i2c_client = dev->i2c_client;
 #if 0
@@ -811,7 +870,7 @@ static int ar0832_set_region(struct ar0832_dev *dev,
 #endif
        else
                return -1;
-       dev_info(&i2c_client->dev, "%s: width = %d  height = %d\n",
+       dev_dbg(&i2c_client->dev, "%s: width = %d  height = %d\n",
                 __func__, image_width, image_height);
 #if 0
        ar0832_write_reg(i2c_client, 0x0104, 1);
@@ -855,20 +914,85 @@ static int ar0832_set_region(struct ar0832_dev *dev,
        return 0;
 }
 
+static int ar0832_set_alternate_addr(struct i2c_client *client)
+{
+       int ret = 0;
+       u8 new_addr = client->addr;
+       u16 val;
+
+       /* Default slave address of ar0832 is 0x36 */
+       client->addr = 0x36;
+       ret = ar0832_read_reg16(client, AR0832_RESET_REG, &val);
+       val &= ~AR0832_RESET_REG_LOCK_REG;
+       ret |= ar0832_write_reg16(client, AR0832_RESET_REG, val);
+       ret |= ar0832_write_reg16(client, AR0832_ID_REG, new_addr << 1);
+
+       if (!ret) {
+               client->addr = new_addr;
+               dev_info(&client->dev,
+                       "new slave address is set to 0x%x\n", new_addr);
+       }
+
+       ret |= ar0832_read_reg16(client, AR0832_RESET_REG, &val);
+       val |= AR0832_RESET_REG_LOCK_REG;
+       ret |= ar0832_write_reg16(client, AR0832_RESET_REG, val);
+
+       return ret;
+}
+
 static int ar0832_power_on(struct ar0832_dev *dev)
 {
        struct i2c_client *i2c_client = dev->i2c_client;
+       int ret = 0;
+
+       dev_info(&i2c_client->dev, "%s: ++ %d\n", __func__, dev->is_stereo);
+
+       /* Plug 1.8V and 2.8V power to sensor */
+       if (dev->power_rail.sen_1v8_reg) {
+               ret = regulator_enable(dev->power_rail.sen_1v8_reg);
+               if (ret) {
+                       dev_err(&i2c_client->dev, "%s: failed to enable vdd\n",
+                               __func__);
+                       goto fail_regulator_1v8_reg;
+               }
+       }
+
+       ar0832_msleep(20);
+
+       if (dev->power_rail.sen_2v8_reg) {
+               ret = regulator_enable(dev->power_rail.sen_2v8_reg);
+               if (ret) {
+                       dev_err(&i2c_client->dev, "%s: failed to enable vaa\n",
+                               __func__);
+                       goto fail_regulator_2v8_reg;
+               }
+       }
+
+       /* Board specific power-on sequence */
+       dev->pdata->power_on(dev->is_stereo);
+
+       /* Change slave address */
+       if (i2c_client->addr)
+               ret = ar0832_set_alternate_addr(i2c_client);
 
-       dev_info(&i2c_client->dev, "%s: ++\n", __func__);
-       dev->pdata->power_on();
        return 0;
+
+fail_regulator_2v8_reg:
+       regulator_put(dev->power_rail.sen_2v8_reg);
+       dev->power_rail.sen_2v8_reg = NULL;
+       regulator_disable(dev->power_rail.sen_1v8_reg);
+fail_regulator_1v8_reg:
+       regulator_put(dev->power_rail.sen_1v8_reg);
+       dev->power_rail.sen_1v8_reg = NULL;
+       return ret;
 }
 
 static int ar0832_focuser_set_config(struct ar0832_dev *dev)
 {
        struct ar0832_reg reg_vcm_ctrl, reg_vcm_step_time;
-       int ret;
+       int ret = 0;
        u8 vcm_slew = 1;
+
        /* bit15(0x80) means that VCM driver enable bit. */
        /* bit3(0x08) means that keep VCM(AF position) */
        /* while sensor is in soft standby mode during mode transitions. */
@@ -885,16 +1009,13 @@ static int ar0832_focuser_set_config(struct ar0832_dev *dev)
                                                vcm_step_time);
        ret = ar0832_write_reg16(dev->i2c_client, reg_vcm_step_time.addr,
                                        reg_vcm_step_time.val);
-       if (ret)
-               return ret;
-
-       return 0;
+       return ret;
 }
 
 static int ar0832_focuser_set_position(struct ar0832_dev *dev,
                                        u32 position)
 {
-       int ret;
+       int ret = 0;
        struct ar0832_reg reg_data;
 
        if (position < dev->focuser_info->config.pos_low ||
@@ -904,9 +1025,7 @@ static int ar0832_focuser_set_position(struct ar0832_dev *dev,
        ar0832_get_focuser_data_regs(&reg_data, position);
        ret = ar0832_write_reg16(dev->i2c_client, reg_data.addr,
                                     reg_data.val);
-       if (ret)
-               return ret;
-       return 0;
+       return ret;
 }
 
 static long ar0832_ioctl(struct file *file,
@@ -915,15 +1034,24 @@ static long ar0832_ioctl(struct file *file,
        int err;
        struct ar0832_dev *dev = file->private_data;
        struct i2c_client *i2c_client = dev->i2c_client;
+       struct ar0832_mode mode;
 
        switch (cmd) {
        case AR0832_IOCTL_SET_POWER_ON:
-               dev_info(&i2c_client->dev, "AR0832_IOCTL_SET_POWER_ON\n");
+               dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_POWER_ON\n");
+               if (copy_from_user(&mode,
+                       (const void __user *)arg,
+                       sizeof(struct ar0832_mode))) {
+                       dev_err(&i2c_client->dev,
+                               "%s: AR0832_IOCTL_SET_POWER_ON failed\n",
+                               __func__);
+                       return -EFAULT;
+               }
+               dev->is_stereo = mode.stereo;
                return ar0832_power_on(dev);
        case AR0832_IOCTL_SET_MODE:
        {
-               struct ar0832_mode mode;
-               dev_info(&i2c_client->dev, "AR0832_IOCTL_SET_MODE\n");
+               dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_MODE\n");
                if (copy_from_user(&mode,
                        (const void __user *)arg,
                        sizeof(struct ar0832_mode))) {
@@ -952,16 +1080,14 @@ static long ar0832_ioctl(struct file *file,
                mutex_unlock(&dev->ar0832_camera_lock);
                return err;
        case AR0832_IOCTL_SET_GAIN:
-       {
                mutex_lock(&dev->ar0832_camera_lock);
                err = ar0832_set_gain(dev, (u16)arg);
                mutex_unlock(&dev->ar0832_camera_lock);
                return err;
-       }
        case AR0832_IOCTL_GET_STATUS:
        {
                u8 status;
-               dev_info(&i2c_client->dev, "AR0832_IOCTL_GET_STATUS\n");
+               dev_dbg(&i2c_client->dev, "AR0832_IOCTL_GET_STATUS\n");
                err = ar0832_get_status(dev, &status);
                if (err)
                        return err;
@@ -977,7 +1103,7 @@ static long ar0832_ioctl(struct file *file,
        case AR0832_IOCTL_SET_SENSOR_REGION:
        {
                struct ar0832_stereo_region region;
-               dev_info(&i2c_client->dev, "AR0832_IOCTL_SET_SENSOR_REGION\n");
+               dev_dbg(&i2c_client->dev, "AR0832_IOCTL_SET_SENSOR_REGION\n");
                if (copy_from_user(&region,
                        (const void __user *)arg,
                        sizeof(struct ar0832_stereo_region))) {
@@ -986,12 +1112,12 @@ static long ar0832_ioctl(struct file *file,
                                __func__);
                        return -EFAULT;
                }
+               err = ar0832_set_region(dev, &region);
                return err;
        }
 
        case AR0832_FOCUSER_IOCTL_GET_CONFIG:
-       {
-               dev_info(&i2c_client->dev,
+               dev_dbg(&i2c_client->dev,
                        "%s AR0832_FOCUSER_IOCTL_GET_CONFIG\n", __func__);
                if (copy_to_user((void __user *) arg,
                                 &dev->focuser_info->config,
@@ -1002,16 +1128,17 @@ static long ar0832_ioctl(struct file *file,
                        return -EFAULT;
                }
                return 0;
-       }
+
        case AR0832_FOCUSER_IOCTL_SET_POSITION:
-               dev_info(&i2c_client->dev,
+               dev_dbg(&i2c_client->dev,
                        "%s AR0832_FOCUSER_IOCTL_SET_POSITION\n", __func__);
                mutex_lock(&dev->ar0832_camera_lock);
                err = ar0832_focuser_set_position(dev, (u32)arg);
                mutex_unlock(&dev->ar0832_camera_lock);
                return err;
+
        default:
-               dev_info(&i2c_client->dev, "(error) %s NONE IOCTL\n",
+               dev_err(&i2c_client->dev, "(error) %s NONE IOCTL\n",
                        __func__);
                return -EINVAL;
        }
@@ -1039,7 +1166,16 @@ static int ar0832_release(struct inode *inode, struct file *file)
        struct i2c_client *i2c_client = dev->i2c_client;
 
        dev_info(&i2c_client->dev, "%s: ++\n", __func__);
-       dev->pdata->power_off();
+
+       /* Unplug 1.8V and 2.8V power from sensor */
+       if (dev->power_rail.sen_2v8_reg)
+               regulator_disable(dev->power_rail.sen_2v8_reg);
+       if (dev->power_rail.sen_1v8_reg)
+               regulator_disable(dev->power_rail.sen_1v8_reg);
+
+       /* Board specific power-down sequence */
+       dev->pdata->power_off(dev->is_stereo);
+
        file->private_data = NULL;
 
        WARN_ON(!atomic_xchg(&dev->in_use, 0));
@@ -1058,34 +1194,24 @@ static int ar0832_probe(struct i2c_client *client,
 {
        int err;
        struct ar0832_dev *dev = NULL;
+       int ret;
 
        dev_info(&client->dev, "ar0832: probing sensor.(id:%s)\n",
                id->name);
 
        dev = kzalloc(sizeof(struct ar0832_dev), GFP_KERNEL);
        if (!dev)
-               goto fail_ar0832_probe;
+               goto probe_fail_release;
 
        dev->sensor_info = kzalloc(sizeof(struct ar0832_sensor_info),
                                        GFP_KERNEL);
        if (!dev->sensor_info)
-               goto fail_ar0832_probe;
+               goto probe_fail_release;
 
        dev->focuser_info = kzalloc(sizeof(struct ar0832_focuser_info),
                                        GFP_KERNEL);
        if (!dev->focuser_info)
-               goto fail_ar0832_probe;
-
-       dev->misc_dev.minor = MISC_DYNAMIC_MINOR;
-       dev->misc_dev.name = "ar0832";
-       dev->misc_dev.fops = &ar0832_fileops;
-       dev->misc_dev.mode = S_IRWXUGO;
-       dev->misc_dev.parent = &client->dev;
-       err = misc_register(&dev->misc_dev);
-       if (err) {
-               dev_err(&client->dev, "Unable to register misc device!\n");
-               goto fail_ar0832_misc_reg;
-       }
+               goto probe_fail_release;
 
        /* sensor */
        dev->pdata = client->dev.platform_data;
@@ -1096,25 +1222,64 @@ static int ar0832_probe(struct i2c_client *client,
        dev->focuser_info->config.pos_low = POS_LOW;
        dev->focuser_info->config.pos_high = POS_HIGH;
 
+       snprintf(dev->dname, sizeof(dev->dname), "%s-%s",
+               id->name, dev->pdata->id);
+       dev->misc_dev.minor = MISC_DYNAMIC_MINOR;
+       dev->misc_dev.name = dev->dname;
+       dev->misc_dev.fops = &ar0832_fileops;
+       dev->misc_dev.mode = S_IRWXUGO;
+       dev->misc_dev.parent = &client->dev;
+       err = misc_register(&dev->misc_dev);
+       if (err) {
+               dev_err(&client->dev, "Unable to register misc device!\n");
+               ret = -ENOMEM;
+               goto probe_fail_free;
+       }
+
        i2c_set_clientdata(client, dev);
        mutex_init(&dev->ar0832_camera_lock);
+
+       dev->power_rail.sen_1v8_reg = regulator_get(&client->dev, "vdd");
+       if (IS_ERR_OR_NULL(dev->power_rail.sen_1v8_reg)) {
+               dev_err(&client->dev, "%s: failed to get vdd\n",
+                       __func__);
+               ret = PTR_ERR(dev->power_rail.sen_1v8_reg);
+               goto probe_fail_free;
+       }
+
+       dev->power_rail.sen_2v8_reg = regulator_get(&client->dev, "vaa");
+       if (IS_ERR_OR_NULL(dev->power_rail.sen_2v8_reg)) {
+               dev_err(&client->dev, "%s: failed to get vaa\n",
+                       __func__);
+               ret = PTR_ERR(dev->power_rail.sen_2v8_reg);
+               regulator_put(dev->power_rail.sen_1v8_reg);
+               dev->power_rail.sen_1v8_reg = NULL;
+               goto probe_fail_free;
+       }
+
        return 0;
 
-fail_ar0832_probe:
-       dev_err(&client->dev, "%s: Unable to allocate memory!\n", __func__);
-fail_ar0832_misc_reg:
+probe_fail_release:
+       dev_err(&client->dev, "%s: unable to allocate memory!\n", __func__);
+       ret = -ENOMEM;
+probe_fail_free:
        if (dev) {
                kfree(dev->focuser_info);
                kfree(dev->sensor_info);
        }
        kfree(dev);
-       return -ENOMEM;
+       return ret;
 }
 
 static int ar0832_remove(struct i2c_client *client)
 {
        struct ar0832_dev *dev = i2c_get_clientdata(client);
 
+       if (dev->power_rail.sen_1v8_reg)
+               regulator_put(dev->power_rail.sen_1v8_reg);
+       if (dev->power_rail.sen_2v8_reg)
+               regulator_put(dev->power_rail.sen_2v8_reg);
+
        misc_deregister(&dev->misc_dev);
        if (dev) {
                kfree(dev->sensor_info);
@@ -1126,6 +1291,7 @@ static int ar0832_remove(struct i2c_client *client)
 
 static const struct i2c_device_id ar0832_id[] = {
        { "ar0832", 0 },
+       { }
 };
 
 static struct i2c_driver ar0832_i2c_driver = {
index 436fb9f..6cf4558 100644 (file)
 
 #include <linux/ioctl.h> /* For IOCTL macros */
 
-#define AR0832_IOCTL_SET_MODE                  _IOW('o', 1, struct ar0832_mode)
-#define AR0832_IOCTL_SET_FRAME_LENGTH          _IOW('o', 2, __u32)
-#define AR0832_IOCTL_SET_COARSE_TIME           _IOW('o', 3, __u32)
-#define AR0832_IOCTL_SET_GAIN                  _IOW('o', 4, __u16)
-#define AR0832_IOCTL_GET_STATUS                        _IOR('o', 5, __u8)
-#define AR0832_IOCTL_GET_OTP                   _IOR('o', 6, struct ar0832_otp_data)
-#define AR0832_IOCTL_TEST_PATTERN              _IOW('o', 7, enum ar0832_test_pattern)
-#define AR0832_IOCTL_SET_POWER_ON              _IOW('o', 10, __u32)
-#define AR0832_IOCTL_SET_SENSOR_REGION         _IOW('o', 11, struct ar0832_stereo_region)
-
-#define AR0832_FOCUSER_IOCTL_GET_CONFIG                _IOR('o', 12, struct ar0832_focuser_config)
-#define AR0832_FOCUSER_IOCTL_SET_POSITION      _IOW('o', 13, __u32)
+#define AR0832_IOCTL_SET_MODE                  _IOW('o', 0x01, struct ar0832_mode)
+#define AR0832_IOCTL_SET_FRAME_LENGTH          _IOW('o', 0x02, __u32)
+#define AR0832_IOCTL_SET_COARSE_TIME           _IOW('o', 0x03, __u32)
+#define AR0832_IOCTL_SET_GAIN                  _IOW('o', 0x04, __u16)
+#define AR0832_IOCTL_GET_STATUS                        _IOR('o', 0x05, __u8)
+#define AR0832_IOCTL_GET_OTP                   _IOR('o', 0x06, struct ar0832_otp_data)
+#define AR0832_IOCTL_TEST_PATTERN              _IOW('o', 0x07, enum ar0832_test_pattern)
+#define AR0832_IOCTL_SET_POWER_ON              _IOW('o', 0x08, struct ar0832_mode)
+#define AR0832_IOCTL_SET_SENSOR_REGION         _IOW('o', 0x09, struct ar0832_stereo_region)
+
+#define AR0832_FOCUSER_IOCTL_GET_CONFIG                _IOR('o', 0x10, struct ar0832_focuser_config)
+#define AR0832_FOCUSER_IOCTL_SET_POSITION      _IOW('o', 0x11, __u32)
 
 enum ar0832_test_pattern {
        TEST_PATTERN_NONE,
@@ -61,6 +61,7 @@ struct ar0832_mode {
        __u32 frame_length;
        __u32 coarse_time;
        __u16 gain;
+       int stereo;
 };
 
 struct ar0832_point{
@@ -84,19 +85,16 @@ struct ar0832_focuser_config {
        __u32 actuator_range;
        __u32 pos_low;
        __u32 pos_high;
-       /* To-Do */
-       /*
-       float focal_length;
-       float fnumber;
-       float max_aperture;
-       */
+       __u32 focal_length;
+       __u32 fnumber;
+       __u32 max_aperture;
 };
 
 #ifdef __KERNEL__
 struct ar0832_platform_data {
-       int (*power_on)(void);
-       int (*power_off)(void);
-
+       int (*power_on)(int is_stereo);
+       int (*power_off)(int is_stereo);
+       char *id;
 };
 #endif /* __KERNEL__ */