diff options
author | Jihoon Bang <jbang@nvidia.com> | 2011-06-15 12:23:38 -0700 |
---|---|---|
committer | Shail Dave <sdave@nvidia.com> | 2011-06-16 18:16:22 -0700 |
commit | 26540715d3beaab810a8c127e7594520081c3fa1 (patch) | |
tree | 0e82567fa4d4cb5134d6b4b1a4de6326b585ae71 | |
parent | 01deb05929bfaabd3621cda0873858659fd3507e (diff) |
ARM: tegra: enterprise: Add rear camera
[DO NOT INTEGRATE TO MAIN]
Add and enable rear camera sensor.
Support only one sensor for now.
Change-Id: Iee284bca42ffaf1d4b3b6de15caf72324e9c427e
Reviewed-on: http://git-master/r/37135
Tested-by: Jihoon Bang <jbang@nvidia.com>
Reviewed-by: Shail Dave <sdave@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise-pinmux.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise-sensors.c | 149 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise.h | 14 |
3 files changed, 164 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/board-enterprise-pinmux.c b/arch/arm/mach-tegra/board-enterprise-pinmux.c index dc4a5c28e90d..a38552a83a3b 100644 --- a/arch/arm/mach-tegra/board-enterprise-pinmux.c +++ b/arch/arm/mach-tegra/board-enterprise-pinmux.c @@ -273,7 +273,7 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux[] = { DEFAULT_PINMUX(GMI_A17, UARTD, NORMAL, NORMAL, INPUT), DEFAULT_PINMUX(GMI_A18, UARTD, NORMAL, NORMAL, INPUT), DEFAULT_PINMUX(GMI_A19, UARTD, NORMAL, NORMAL, OUTPUT), - DEFAULT_PINMUX(CAM_MCLK, VI_ALT2, PULL_UP, NORMAL, INPUT), + DEFAULT_PINMUX(CAM_MCLK, VI_ALT3, NORMAL, NORMAL, INPUT), DEFAULT_PINMUX(GPIO_PCC1, RSVD1, NORMAL, NORMAL, INPUT), DEFAULT_PINMUX(GPIO_PBB0, RSVD1, NORMAL, NORMAL, INPUT), DEFAULT_PINMUX(GPIO_PBB3, VGP3, NORMAL, NORMAL, INPUT), diff --git a/arch/arm/mach-tegra/board-enterprise-sensors.c b/arch/arm/mach-tegra/board-enterprise-sensors.c index 53cf704dfdf2..ad968031b2e7 100644 --- a/arch/arm/mach-tegra/board-enterprise-sensors.c +++ b/arch/arm/mach-tegra/board-enterprise-sensors.c @@ -19,10 +19,15 @@ */ #include <linux/i2c.h> +#include <linux/delay.h> #include <linux/err.h> #include <linux/mpu.h> #include <linux/nct1008.h> +#include <linux/regulator/consumer.h> + #include <mach/gpio.h> + +#include <media/ar0832_main.h> #include "cpu-tegra.h" #include "gpio-names.h" #include "board-enterprise.h" @@ -138,11 +143,155 @@ static void enterprise_isl_init(void) ARRAY_SIZE(enterprise_i2c0_isl_board_info)); } + +static struct regulator *cam_reg = NULL; +static struct regulator *csi_reg = NULL; + +static int enterprise_ar0832_power_on(void) +{ + int ret = 0; + + csi_reg = regulator_get(NULL, "avdd_dsi_csi"); + if (IS_ERR_OR_NULL(csi_reg)) { + pr_err("%s: get csi pwr err\n", __func__); + return PTR_ERR(cam_reg); + } + + ret = regulator_enable(csi_reg); + if (ret) { + pr_err("%s: enable csi pwr err\n", __func__); + goto fail_regulator_csi_reg; + } + + cam_reg = regulator_get(NULL, "vddio_cam"); + if (IS_ERR_OR_NULL(cam_reg)) { + pr_err("%s: get cam pwr err\n", __func__); + return PTR_ERR(cam_reg); + } + + ret = regulator_enable(cam_reg); + if (ret) { + pr_err("%s: enable cam pwr err\n", __func__); + goto fail_regulator_cam_reg; + } + + pr_info("%s: enable 1.8V...\n", __func__); + gpio_set_value(CAM_LDO_1V8_EN_L_GPIO, 1); + mdelay(20); + pr_info("%s: enable 2.8V...\n", __func__); + gpio_set_value(CAM_LDO_2V8_EN_L_GPIO, 1); + + gpio_set_value(CAM1_PWDN_GPIO, 1); + mdelay(5); + gpio_set_value(CAM1_RST_L_GPIO, 1); + + return 0; + +fail_regulator_cam_reg: + regulator_put(cam_reg); +fail_regulator_csi_reg: + regulator_put(csi_reg); + + return ret; +} + +static int enterprise_ar0832_power_off(void) +{ + if (!cam_reg) + regulator_put(cam_reg); + if (!csi_reg) + regulator_put(csi_reg); + + gpio_set_value(CAM_LDO_2V8_EN_L_GPIO, 0); + mdelay(20); + gpio_set_value(CAM_LDO_1V8_EN_L_GPIO, 0); + + return 0; +} + +struct enterprise_cam_gpio { + int gpio; + const char *label; + int value; +}; + +#define TEGRA_CAMERA_GPIO(_gpio, _label, _value) \ + { \ + .gpio = _gpio, \ + .label = _label, \ + .value = _value, \ + } + +static struct enterprise_cam_gpio enterprise_cam_gpio_data[] = { + [0] = TEGRA_CAMERA_GPIO(CAM_LDO_1V8_EN_L_GPIO, "cam_ldo_1v8", 0), + [1] = TEGRA_CAMERA_GPIO(CAM_LDO_2V8_EN_L_GPIO, "cam_ldo_2v8", 0), + [2] = TEGRA_CAMERA_GPIO(CAM_CSI_MUX_SEL_GPIO, "cam_csi_sel", 1), + + [3] = TEGRA_CAMERA_GPIO(CAM1_RST_L_GPIO, "cam1_rst_lo", 0), + [4] = TEGRA_CAMERA_GPIO(CAM1_PWDN_GPIO, "cam1_pwdn", 1), + + [5] = TEGRA_CAMERA_GPIO(CAM2_RST_L_GPIO, "cam2_rst_lo", 0), + [6] = TEGRA_CAMERA_GPIO(CAM2_PWDN_GPIO, "cam2_pwdn", 1), + + [7] = TEGRA_CAMERA_GPIO(CAM3_RST_L_GPIO, "cam3_rst_lo", 0), + [8] = TEGRA_CAMERA_GPIO(CAM3_PWDN_GPIO, "cam3_pwdn", 1), +}; + +struct ar0832_platform_data enterprise_ar0832_data = { + .power_on = enterprise_ar0832_power_on, + .power_off = enterprise_ar0832_power_off, +}; + +static struct i2c_board_info ar0832_i2c2_boardinfo[] = { + { + I2C_BOARD_INFO("ar0832", 0x36), + .platform_data = &enterprise_ar0832_data, + }, + { + I2C_BOARD_INFO("ar0832_focuser", 0x36), + }, +}; + +static int enterprise_cam_init(void) +{ + int ret; + int i; + + pr_info("%s:++\n", __func__); + + for (i = 0; i < ARRAY_SIZE(enterprise_cam_gpio_data); i++) { + ret = gpio_request(enterprise_cam_gpio_data[i].gpio, + enterprise_cam_gpio_data[i].label); + if (ret < 0) { + pr_err("%s: gpio_request failed for gpio #%d\n", + __func__, i); + goto fail_free_gpio; + } + gpio_direction_output(enterprise_cam_gpio_data[i].gpio, + enterprise_cam_gpio_data[i].value); + gpio_export(enterprise_cam_gpio_data[i].gpio, false); + tegra_gpio_enable(enterprise_cam_gpio_data[i].gpio); + } + + i2c_register_board_info(2, ar0832_i2c2_boardinfo, + ARRAY_SIZE(ar0832_i2c2_boardinfo)); + + return 0; + +fail_free_gpio: + pr_err("%s enterprise_cam_init failed!\n", __func__); + while (i--) + gpio_free(enterprise_cam_gpio_data[i].gpio); + return ret; +} + int __init enterprise_sensors_init(void) { + int ret; enterprise_isl_init(); enterprise_nct1008_init(); enterprise_mpuirq_init(); + enterprise_cam_init(); return 0; } diff --git a/arch/arm/mach-tegra/board-enterprise.h b/arch/arm/mach-tegra/board-enterprise.h index 58f8b8bb65a0..5520083b2149 100644 --- a/arch/arm/mach-tegra/board-enterprise.h +++ b/arch/arm/mach-tegra/board-enterprise.h @@ -56,4 +56,18 @@ int enterprise_suspend_init(void); #define TPS80031_IRQ_BASE TEGRA_NR_IRQS #define TPS80031_IRQ_END (TPS80031_IRQ_BASE + 24) +/*****************Camera GPIOs ******************/ +#define CAM_CSI_MUX_SEL_GPIO TEGRA_GPIO_PM3 +#define CAM_LDO_1V8_EN_L_GPIO TEGRA_GPIO_PF1 +#define CAM_LDO_2V8_EN_L_GPIO TEGRA_GPIO_PM7 +#define CAM1_RST_L_GPIO TEGRA_GPIO_PM5 /*REAR RIGHT*/ +#define CAM1_PWDN_GPIO TEGRA_GPIO_PF3 /*REAR RIGHT*/ +#define CAM2_RST_L_GPIO TEGRA_GPIO_PF4 /*REAR LEFT*/ +#define CAM2_PWDN_GPIO TEGRA_GPIO_PF2 /*REAR LEFT*/ +#define CAM3_RST_L_GPIO TEGRA_GPIO_PM2 /*FRONT*/ +#define CAM3_PWDN_GPIO TEGRA_GPIO_PN4 /*FRONT*/ +#define CAM_FLASH_EN_GPIO TEGRA_GPIO_PBB3 +#define CAM_FLASH_MAX_TORCH_AMP 7 +#define CAM_FLASH_MAX_FLASH_AMP 7 + #endif |