From bd680338eb8cc55b970db82f2d344bc569514dca Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Mon, 22 Nov 2010 15:16:35 -0600 Subject: [PATCH] media: video: tegra: ov5650: Disable OTP readout on broken hw. Disabled reading bad OTP data from sensors on known-bad HW. Change-Id: I08d35ff6ff13bd2c0c0a4a1a50cd92e6e663efc8 Signed-off-by: Andrei Warkentin --- arch/arm/mach-tegra/board-stingray-sensors.c | 41 ++++++++++++-------- drivers/media/video/tegra/ov5650.c | 7 +++- include/media/ov5650.h | 5 ++- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-tegra/board-stingray-sensors.c b/arch/arm/mach-tegra/board-stingray-sensors.c index 2ab431da1257..568473a8231d 100755 --- a/arch/arm/mach-tegra/board-stingray-sensors.c +++ b/arch/arm/mach-tegra/board-stingray-sensors.c @@ -34,6 +34,7 @@ #include +#include "board-stingray.h" #include "gpio-names.h" #define KXTF9_IRQ_GPIO TEGRA_GPIO_PV3 @@ -47,23 +48,6 @@ #define SOC2030_RESETN_GPIO TEGRA_GPIO_PD5 #define SOC2030_PWRDN_GPIO TEGRA_GPIO_PBB5 -static int stingray_ov5650_init(void) -{ - tegra_gpio_enable(OV5650_RESETN_GPIO); - gpio_request(OV5650_RESETN_GPIO, "ov5650_reset"); - gpio_direction_output(OV5650_RESETN_GPIO, 0); - gpio_export(OV5650_RESETN_GPIO, false); - - tegra_gpio_enable(OV5650_PWRDN_GPIO); - gpio_request(OV5650_PWRDN_GPIO, "ov5650_pwrdn"); - gpio_direction_output(OV5650_PWRDN_GPIO, 1); - gpio_export(OV5650_PWRDN_GPIO, false); - - pr_info("initialize the ov5650 sensor\n"); - - return 0; -} - static int stingray_ov5650_power_on(void) { msleep(20); @@ -92,8 +76,31 @@ static int stingray_ov5650_power_off(void) struct ov5650_platform_data stingray_ov5650_data = { .power_on = stingray_ov5650_power_on, .power_off = stingray_ov5650_power_off, + .ignore_otp = false }; +static int stingray_ov5650_init(void) +{ + tegra_gpio_enable(OV5650_RESETN_GPIO); + gpio_request(OV5650_RESETN_GPIO, "ov5650_reset"); + gpio_direction_output(OV5650_RESETN_GPIO, 0); + gpio_export(OV5650_RESETN_GPIO, false); + + tegra_gpio_enable(OV5650_PWRDN_GPIO); + gpio_request(OV5650_PWRDN_GPIO, "ov5650_pwrdn"); + gpio_direction_output(OV5650_PWRDN_GPIO, 1); + gpio_export(OV5650_PWRDN_GPIO, false); + + if (stingray_revision() <= STINGRAY_REVISION_P1) { + stingray_ov5650_data.ignore_otp = true; + pr_info("running on old hardware, ignoring OTP data\n"); + } + + pr_info("initialize the ov5650 sensor\n"); + + return 0; +} + static int stingray_soc2030_init(void) { tegra_gpio_enable(SOC2030_RESETN_GPIO); diff --git a/drivers/media/video/tegra/ov5650.c b/drivers/media/video/tegra/ov5650.c index 6cc06dfb2770..96957448447a 100755 --- a/drivers/media/video/tegra/ov5650.c +++ b/drivers/media/video/tegra/ov5650.c @@ -578,7 +578,9 @@ static int ov5650_get_otp(struct ov5650_info *info, void __user *ubuffer) otpp = (uint8_t *)&info->otp_data; - /* Either we never read the OTP or CRC failure. */ + /* If we've already read the OTP successfully (and CRC matched). + Alternatively this is set also if ignore_otp was provided in + platform data, so we don't try to read OTP on known-bad hardware. */ if (info->otp_valid) goto end; @@ -765,7 +767,8 @@ static int ov5650_probe(struct i2c_client *client, info->pdata = client->dev.platform_data; info->i2c_client = client; - info->otp_valid = false; + if (info->pdata->ignore_otp) + info->otp_valid = true; i2c_set_clientdata(client, info); return 0; diff --git a/include/media/ov5650.h b/include/media/ov5650.h index 083cf6e21eae..ff7b1f76229c 100755 --- a/include/media/ov5650.h +++ b/include/media/ov5650.h @@ -67,9 +67,12 @@ struct ov5650_mode { }; #ifdef __KERNEL__ struct ov5650_platform_data { + + /* Assume OTP data are corrupted, so just + return an empty block when asked. */ + bool ignore_otp; int (*power_on)(void); int (*power_off)(void); - }; #endif /* __KERNEL__ */ -- 2.34.1