From 7fc3ce7312fec9320aeffb1a6c6c6d4bf2408669 Mon Sep 17 00:00:00 2001 From: sbrissen Date: Wed, 23 Oct 2013 13:19:08 -0400 Subject: Add support for Note 8 (N5100 and N5110) Change-Id: I6c9798682f9f6349b37cb452353bd0c0e6958401 --- arch/arm/mach-exynos/midas-camera.c | 618 +++++++++++++++++++++++++++++++++++- 1 file changed, 617 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-exynos/midas-camera.c') 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 #include #include +#ifdef CONFIG_VIDEO_FIMC +#include +#endif #ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC #include #include @@ -60,6 +63,10 @@ #include #endif +#ifdef CONFIG_VIDEO_SR130PC20 +#include +#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 -- cgit v1.1