aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/midas-camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/midas-camera.c')
-rw-r--r--arch/arm/mach-exynos/midas-camera.c618
1 files changed, 617 insertions, 1 deletions
diff --git a/arch/arm/mach-exynos/midas-camera.c b/arch/arm/mach-exynos/midas-camera.c
index 636ba13..7bfb378 100644
--- a/arch/arm/mach-exynos/midas-camera.c
+++ b/arch/arm/mach-exynos/midas-camera.c
@@ -18,6 +18,9 @@
#include <plat/csis.h>
#include <plat/pd.h>
#include <plat/gpio-cfg.h>
+#ifdef CONFIG_VIDEO_FIMC
+#include <plat/fimc.h>
+#endif
#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
#include <plat/fimc-core.h>
#include <media/s5p_fimc.h>
@@ -60,6 +63,10 @@
#include <media/sr200pc20_platform.h>
#endif
+#ifdef CONFIG_VIDEO_SR130PC20
+#include <media/sr130pc20_platform.h>
+#endif
+
struct class *camera_class;
static int __init camera_class_init(void)
@@ -1875,6 +1882,15 @@ static int isx012_get_i2c_busnum(void)
return 0;
}
+static atomic_t flash_status = ATOMIC_INIT(ISX012_FLASH_OFF);
+#ifdef CONFIG_MACH_KONA
+static int isx012_flash_en(u32 mode, u32 onoff)
+{
+ pr_info("[ISX012] %s: not supported!\n", __func__);
+ return 0;
+}
+#else
+
static void isx012_flashtimer_handler(unsigned long data)
{
int ret = -ENODEV;
@@ -1889,7 +1905,6 @@ static void isx012_flashtimer_handler(unsigned long data)
}
-static atomic_t flash_status = ATOMIC_INIT(ISX012_FLASH_OFF);
static int isx012_flash_en(u32 mode, u32 onoff)
{
static int flash_mode = ISX012_FLASH_MODE_NORMAL;
@@ -1962,12 +1977,257 @@ out:
mutex_unlock(&flash_lock);
return 0;
}
+#endif
static int isx012_is_flash_on(void)
{
return atomic_read(&flash_status);
}
+#ifdef CONFIG_MACH_KONA
+static int isx012_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "[ISX012] power on\n");
+ printk(KERN_DEBUG "%s: system_rev=%d\n", __func__, system_rev);
+
+ ret = gpio_request(GPIO_5M_nSTBY, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 5M_nSTBY\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_5M_nRST, "GPL1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 5M_nRST\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_CAM_EN2, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request CAM_EN2\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_VT_CAM_nSTBY, "GPF2");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request VT_CAM_nSTBY\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_VT_CAM_nRST, "GPJ1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request VT_CAM_nRST\n");
+ return ret;
+ }
+
+ /* 5M_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+
+#ifdef CONFIG_MACH_KONA_EUR_LTE /* HW request */
+ regulator_set_voltage(regulator, 1250000, 1250000);
+#endif
+
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core_1.2v");
+ udelay(10);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+ udelay(10);
+
+ /* CAM_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_EN2, 1);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+#if defined(CONFIG_MACH_KONA_EUR_OPEN) || defined(CONFIG_MACH_KONA_EUR_WIFI)
+ /* Kona 3G use PMIC for A2.8V on Rev0.0 */
+ if (system_rev < 1) {
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_a2.8v");
+ }
+#endif
+ udelay(10);
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(300); /* fix me. 300 is too big */
+
+ /* VT enable */
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 1);
+ CAM_CHECK_ERR(ret, "VT_CAM_nSTBY");
+
+ /* CAM_MCLK */
+ /*s5p_gpio_set_drvstr(GPIO_CAM_MCLK, S5P_GPIO_DRVSTR_LV2);*/
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ usleep_range(11000, 12000); /* fix me later */
+
+ /* VT Reset */
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 1);
+ CAM_CHECK_ERR(ret, "VT_CAM_nRST");
+ usleep_range(1100, 1200);
+
+ /* VT disable */
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "VT_CAM_nSTBY off");
+ udelay(20);
+
+ /* 5M Reset */
+ ret = gpio_direction_output(GPIO_5M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "5M_nRST");
+ udelay(10);
+
+ /* 5MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3mp_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_af_2.8v");
+ usleep_range(6000, 6500);
+
+ gpio_free(GPIO_5M_nSTBY);
+ gpio_free(GPIO_5M_nRST);
+ gpio_free(GPIO_CAM_EN2);
+ gpio_free(GPIO_VT_CAM_nSTBY);
+ gpio_free(GPIO_VT_CAM_nRST);
+
+ return ret;
+}
+
+static int isx012_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "[ISX012] power down\n");
+
+ ret = gpio_request(GPIO_5M_nSTBY, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 3M_nSTBY\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_5M_nRST, "GPL1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 3M_nRST\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_EN2, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request CAM_EN2\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_nRST, "GPJ1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request VT_CAM_nRST\n");
+ return ret;
+ }
+
+ /* 5MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3mp_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_af_2.8v");
+ udelay(10);
+
+ /* VT Reset */
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 0);
+ CAM_CHECK_ERR(ret, "VT_CAM_nRST");
+ udelay(10);
+
+ /* 5M_nSTBY */
+ ret = gpio_direction_output(GPIO_5M_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "5M_nSTBY");
+ udelay(10);
+
+ /* Check delay */
+
+ /* 5M_nRST */
+ ret = gpio_direction_output(GPIO_5M_nRST, 0);
+ CAM_CHECK_ERR(ret, "5M_nRST");
+ udelay(50);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(10);
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+ udelay(5);
+
+ /* CAM_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_EN2, 0);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+#if defined(CONFIG_MACH_KONA_EUR_OPEN) || defined(CONFIG_MACH_KONA_EUR_WIFI)
+ /* Kona 3G use PMIC for A2.8V on Rev0.0 */
+ if (system_rev < 1) {
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_a2.8v");
+ }
+#endif
+ udelay(5);
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ udelay(5);
+
+ /* 5MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_core_1.2v");
+
+ gpio_free(GPIO_5M_nSTBY);
+ gpio_free(GPIO_5M_nRST);
+ gpio_free(GPIO_CAM_EN2);
+ gpio_free(GPIO_VT_CAM_nRST);
+ return ret;
+}
+
+#else /* ! CONFIG_MACH_KONA */
+
/* Power up/down func for P4C, P2. */
static int isx012_power_on(void)
{
@@ -2125,6 +2385,7 @@ static int isx012_power_down(void)
return ret;
}
+#endif
static int isx012_power(int enable)
{
@@ -2161,6 +2422,10 @@ static int isx012_enable_standby(bool enable)
return err;
}
+#ifdef CONFIG_MACH_KONA
+ udelay(200);
+#endif
+
/* GPIO_5M_nSTBY */
err = gpio_direction_output(GPIO_5M_nSTBY, enable ?
GPIO_LEVEL_LOW : GPIO_LEVEL_HIGH);
@@ -2170,6 +2435,7 @@ static int isx012_enable_standby(bool enable)
return 0;
}
+#ifndef CONFIG_MACH_KONA
static int px_cam_cfg_init(void)
{
int ret = -ENODEV;
@@ -2197,6 +2463,7 @@ out_free:
out:
return ret;
}
+#endif
static const char *isx012_get_clk_name(void)
{
@@ -2292,6 +2559,19 @@ static ssize_t flash_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(rear_flash, 0664, flash_show, flash_store);
+extern u32 isx012_get_vendorid(void);
+static ssize_t isx012_rear_vendorid_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u32 vendorid = 0;
+
+ vendorid = isx012_get_vendorid();
+
+ return sprintf(buf, "0x%04X\n", vendorid);
+
+}
+static DEVICE_ATTR(rear_vendorid, S_IRUGO, isx012_rear_vendorid_show, NULL);
+
int isx012_create_file(struct class *cls)
{
struct device *dev_rear = NULL;
@@ -2317,6 +2597,11 @@ int isx012_create_file(struct class *cls)
if (unlikely(ret < 0))
pr_err("cam_init: failed to create device file, %s\n",
dev_attr_rear_flash.attr.name);
+
+ ret = device_create_file(dev_rear, &dev_attr_rear_vendorid);
+ if (unlikely(ret < 0))
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_rear_vendorid.attr.name);
return 0;
}
@@ -2773,6 +3058,334 @@ static struct s3c_platform_camera s5k5ccgx = {
};
#endif /* #ifdef CONFIG_VIDEO_S5K5CCGX_COMMON */
+#ifdef CONFIG_VIDEO_SR130PC20
+static int sr130pc20_get_i2c_busnum(void)
+{
+ return 0;
+}
+
+static int sr130pc20_flash_en(u32 mode, u32 onoff)
+{
+ pr_info("[SR130PC20] %s: not supported!\n", __func__);
+ return 0;
+}
+
+static int sr130pc20_is_flash_on(void)
+{
+ pr_info("[SR130PC20] %s: not supported!\n", __func__);
+ return 0;
+}
+
+static int sr130pc20_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "[SR130PC20] power on\n");
+
+ ret = gpio_request(GPIO_CAM_EN2, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request CAM_EN2\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_VT_CAM_nSTBY, "GPF2");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request VT_CAM_nSTBY\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_VT_CAM_nRST, "GPJ1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request VT_CAM_nRST\n");
+ return ret;
+ }
+
+ /* 5M_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core_1.2v");
+ udelay(10);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+ udelay(10);
+
+ /* CAM_A2.8V */
+#if defined(CONFIG_MACH_KONA_EUR_OPEN) || defined(CONFIG_MACH_KONA_EUR_WIFI)
+ /* Kona 3G use PMIC for A2.8V on Rev0.0 */
+ if (system_rev < 1) {
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_a2.8v");
+ }
+#endif
+ ret = gpio_direction_output(GPIO_CAM_EN2, 1);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+ udelay(10);
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(300); /* fix me. 300 is too big */
+
+ /* VT enable */
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 1);
+ CAM_CHECK_ERR(ret, "VT_CAM_nSTBY");
+ udelay(20); /* fix me. Delete */
+
+ /* CAM_MCLK */
+ /*s5p_gpio_set_drvstr(GPIO_VTCAM_MCLK, S5P_GPIO_DRVSTR_LV2);*/
+ ret = s3c_gpio_cfgpin(GPIO_VTCAM_MCLK, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_VTCAM_MCLK, S3C_GPIO_PULL_NONE);
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ usleep_range(11000, 12000); /* fix me later */
+
+ /* VT Reset */
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 1);
+ CAM_CHECK_ERR(ret, "VT_CAM_nRST");
+ usleep_range(1100, 1200);
+
+ gpio_free(GPIO_CAM_EN2);
+ gpio_free(GPIO_VT_CAM_nSTBY);
+ gpio_free(GPIO_VT_CAM_nRST);
+ return ret;
+}
+
+static int sr130pc20_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "[SR130PC20] power down\n");
+
+ ret = gpio_request(GPIO_CAM_EN2, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request CAM_EN2\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_nSTBY, "GPF2");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request VT_CAM_nSTBY\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_VT_CAM_nRST, "GPJ1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request VT_CAM_nRST\n");
+ return ret;
+ }
+
+ /* VT Reset */
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 0);
+ CAM_CHECK_ERR(ret, "VT_CAM_nRST");
+ usleep_range(1000, 1100);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_VTCAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_VTCAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(50);
+
+ /* VT disable */
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "VT_CAM_nSTBY");
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+ udelay(5);
+
+ /* CAM_A2.8V */
+#if defined(CONFIG_MACH_KONA_EUR_OPEN) || defined(CONFIG_MACH_KONA_EUR_WIFI)
+ /* Kona 3G use PMIC for A2.8V on Rev0.0 */
+ if (system_rev < 1) {
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_a2.8v");
+ }
+#endif
+ ret = gpio_direction_output(GPIO_CAM_EN2, 0);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+ udelay(5);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ udelay(5);
+
+ /* 5MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_core_1.2v");
+
+ gpio_free(GPIO_CAM_EN2);
+ gpio_free(GPIO_VT_CAM_nSTBY);
+ gpio_free(GPIO_VT_CAM_nRST);
+ return ret;
+}
+
+static int sr130pc20_power(int enable)
+{
+ int ret = 0;
+
+ if (enable)
+ ret = sr130pc20_power_on();
+ else
+ ret = sr130pc20_power_down();
+
+ if (unlikely(ret)) {
+ pr_err("%s: power-on/down failed\n", __func__);
+ return ret;
+ }
+
+ ret = s3c_csis_power(enable);
+ if (unlikely(ret)) {
+ pr_err("%s: csis power-on failed\n", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int sr130pc20_enable_standby(bool enable)
+{
+ pr_info("[SR130PC20] %s not supported!\n", __func__);
+ return 0;
+}
+
+static const char *sr130pc20_get_clk_name(void)
+{
+ return "sclk_cam1";
+}
+
+static struct sr130pc20_platform_data sr130pc20_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .streamoff_delay = SR130PC20_STREAMOFF_DELAY,
+ .flash_en = sr130pc20_flash_en,
+ .is_flash_on = sr130pc20_is_flash_on,
+ .stby_on = sr130pc20_enable_standby,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+
+static struct i2c_board_info sr130pc20_i2c_info = {
+ I2C_BOARD_INFO("SR130PC20", 0x40>>1),
+ .platform_data = &sr130pc20_plat,
+};
+
+static struct s3c_platform_camera sr130pc20 = {
+ .id = CAMERA_CSI_D,
+ .get_clk_name = sr130pc20_get_clk_name,
+ .get_i2c_busnum = sr130pc20_get_i2c_busnum,
+ .cam_power = sr130pc20_power, /*smdkv310_mipi_cam0_reset,*/
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &sr130pc20_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 1,
+ .mipi_settle = 6,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+
+static ssize_t sr130pc20_camtype_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const char cam_type[] = "SF_SR130PC20";
+ pr_info("%s\n", __func__);
+ return sprintf(buf, "%s\n", cam_type);
+}
+static DEVICE_ATTR(front_camtype, S_IRUGO, sr130pc20_camtype_show, NULL);
+
+static ssize_t sr130pc20_camfw_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char type[] = "SR130PC20";
+ return sprintf(buf, "%s %s\n", type, type);
+}
+static DEVICE_ATTR(front_camfw, S_IRUGO, sr130pc20_camfw_show, NULL);
+
+int sr130pc20_create_file(struct class *cls)
+{
+ struct device *dev_front = NULL;
+ int ret = -ENODEV;
+
+ dev_front = device_create(cls, NULL, 0, NULL, "front");
+ if (IS_ERR(dev_front)) {
+ pr_err("cam_init: failed to create device(frontcam_dev)\n");
+ return -ENODEV;
+ }
+
+ ret = device_create_file(dev_front, &dev_attr_front_camtype);
+ if (unlikely(ret < 0))
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_front_camtype.attr.name);
+
+ ret = device_create_file(dev_front, &dev_attr_front_camfw);
+ if (unlikely(ret < 0))
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_front_camtype.attr.name);
+
+ return 0;
+}
+#endif /* CONFIG_VIDEO_SR130PC20*/
#ifdef CONFIG_VIDEO_SR200PC20M
static int sr200pc20m_get_i2c_busnum(void)
@@ -3442,6 +4055,9 @@ static struct s3c_platform_fimc fimc_plat = {
#ifdef CONFIG_VIDEO_SR200PC20
&sr200pc20,
#endif
+#ifdef CONFIG_VIDEO_SR130PC20
+ &sr130pc20,
+#endif
#ifdef WRITEBACK_ENABLED
&writeback,
#endif