From a4bc2c0133fe300b79ec069a01b709b1b24a490e Mon Sep 17 00:00:00 2001 From: Scott Mertz Date: Sun, 19 Oct 2014 19:44:24 -0700 Subject: [PATCH] msm: camera: Merge tomato camera changes Merge yulong cp8675 camera driver to base camera driver Change-Id: I876a085d08db5e825393e46daf295a5480931836 msm: camera: add vana/af gpio power sequence dt entry Change-Id: I6ec11f57d90cf4113d187a2eb848c1f5708ddcec msm: camera: remove yulong power sequence - This is done in device tree Change-Id: Idd7184552b91c4fb7795bc79bb23e235a77a2b91 msm: camera_v2: merge in latest yulong Change-Id: I9f5b2d1609924fc910adaa3b9f8ab1481b7c4048 camera_v2: Make yulong drivers work with CONFIG_COMPAT The camera userspace can (and does) send 32bit data, even if it is 64bit. Be prepared for it, or things will go boom. Change-Id: If72cd19bea0868c5a95265f988bc87f412390fdd msm: camera: flash: fix build for non-yulong boards Change-Id: I2667bcfffe70b302fc97cd33ef2dcf6c1a3afd7f msm: camera: Fix Yulong camera power up/down sequence Change-Id: I6d106f42a923197dc91515bd35dd03f754859b94 msm: camera: Remove IMX135 driver Change-Id: I13b5a7c436dd618eb64e0a166bc7ce371a81766c msm: camera: Remove OV5648 driver Change-Id: I5aadfe52b4d75e62c4c5b6110a6b37ac792a11b8 msm: camera_v2: add af software powerdown Change-Id: I4dc7b7fc700301929e755eddce45a8d781b1f612 msm: camera: Add CKT camera ID function Change-Id: I6cb862626676a334990853d125dbf2624cffdc5f msm: camera: Fix compilation * Include subdirectory headers to avoid compilation issues when building standalone kernel image. msm: camera: Add Yulong camera definitions Change-Id: Id3f3fd96125b9444873c491083a143f79e402aa3 --- .../msm/camera_v2/sensor/flash/Makefile | 2 + .../camera_v2/sensor/flash/msm_led_flash.h | 14 + .../sensor/flash/msm_led_gpio_trigger.c | 499 ++++++++++++++++++ .../camera_v2/sensor/flash/msm_led_torch.c | 55 ++ .../msm/camera_v2/sensor/flash/sgm3780.c | 86 +++ .../platform/msm/camera_v2/sensor/io/Makefile | 1 + .../camera_v2/sensor/io/msm_camera_dt_util.c | 87 ++- .../msm/camera_v2/sensor/msm_sensor.c | 63 ++- .../msm/camera_v2/sensor/msm_sensor.h | 12 + include/media/msm_cam_sensor.h | 3 + 10 files changed, 820 insertions(+), 2 deletions(-) create mode 100644 drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_gpio_trigger.c create mode 100644 drivers/media/platform/msm/camera_v2/sensor/flash/sgm3780.c diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile index d4d1540f549..5b265de7807 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile @@ -8,4 +8,6 @@ obj-$(CONFIG_MSMB_CAMERA) += adp1660.o obj-$(CONFIG_MSMB_CAMERA) += bd7710.o obj-$(CONFIG_MSMB_CAMERA) += msm_led_torch.o obj-$(CONFIG_MSMB_CAMERA) += msm_flash.o +obj-$(CONFIG_MACH_YULONG) += msm_led_gpio_trigger.o +obj-$(CONFIG_MACH_YULONG) += sgm3780.o obj-$(CONFIG_MSMB_CAMERA) += lm3642.o diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h index 9edc6b02103..665281e55a9 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h @@ -91,4 +91,18 @@ int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_off(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_low(struct msm_led_flash_ctrl_t *fctrl); int msm_flash_led_high(struct msm_led_flash_ctrl_t *fctrl); + +#ifdef CONFIG_MACH_YULONG +int msm_flash_gpio_probe(struct platform_device *pdev, const void *data); +int32_t msm_led_gpio_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl, + void *arg); +int32_t msm_led_gpio_trigger_config(struct msm_led_flash_ctrl_t *fctrl, + void *data); +int msm_flash_led_gpio_init(struct msm_led_flash_ctrl_t *fctrl); +int msm_flash_led_gpio_release(struct msm_led_flash_ctrl_t *fctrl); +int msm_flash_led_gpio_off(struct msm_led_flash_ctrl_t *fctrl); +int msm_flash_led_gpio_low(struct msm_led_flash_ctrl_t *fctrl); +int msm_flash_led_gpio_high(struct msm_led_flash_ctrl_t *fctrl); +#endif + #endif diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_gpio_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_gpio_trigger.c new file mode 100644 index 00000000000..9e9b34cfe62 --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_gpio_trigger.c @@ -0,0 +1,499 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ + +#include +#include "msm_led_flash.h" +#include "msm_camera_io_util.h" +#include "../msm_sensor.h" +#include "msm_led_flash.h" +#include "../cci/msm_cci.h" +#include + +#define FLASH_NAME "camera-led-flash" +#define CAM_FLASH_PINCTRL_STATE_SLEEP "cam_flash_suspend" +#define CAM_FLASH_PINCTRL_STATE_DEFAULT "cam_flash_default" +/*#define CONFIG_MSMB_CAMERA_DEBUG*/ +#undef CDBG +#ifdef CONFIG_MSMB_CAMERA_DEBUG +#define CDBG(fmt, args...) pr_err(fmt, ##args) +#else +#define CDBG(fmt, args...) do { } while (0) +#endif + +extern int32_t msm_led_torch_create_classdev( + struct platform_device *pdev, void *data); + +int32_t msm_led_gpio_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl, + void *arg) +{ + uint32_t *subdev_id = (uint32_t *)arg; + if (!subdev_id) { + pr_err("failed\n"); + return -EINVAL; + } + *subdev_id = fctrl->subdev_id; + + CDBG("subdev_id %d\n", *subdev_id); + return 0; +} + +int32_t msm_led_gpio_trigger_config(struct msm_led_flash_ctrl_t *fctrl, + void *data) +{ + int rc = 0; + struct msm_camera_led_cfg_t *cfg = (struct msm_camera_led_cfg_t *)data; + CDBG("called led_state %d\n", cfg->cfgtype); + + if (!fctrl->func_tbl) { + pr_err("failed\n"); + return -EINVAL; + } + switch (cfg->cfgtype) { + + case MSM_CAMERA_LED_INIT: + if (fctrl->func_tbl->flash_led_init) + rc = fctrl->func_tbl->flash_led_init(fctrl); + break; + + case MSM_CAMERA_LED_RELEASE: + if (fctrl->func_tbl->flash_led_release) + rc = fctrl->func_tbl-> + flash_led_release(fctrl); + break; + + case MSM_CAMERA_LED_OFF: + if (fctrl->func_tbl->flash_led_off) + rc = fctrl->func_tbl->flash_led_off(fctrl); + break; + + case MSM_CAMERA_LED_LOW: + if (fctrl->func_tbl->flash_led_low) + rc = fctrl->func_tbl->flash_led_low(fctrl); + break; + + case MSM_CAMERA_LED_HIGH: + if (fctrl->func_tbl->flash_led_high) + rc = fctrl->func_tbl->flash_led_high(fctrl); + break; + default: + rc = -EFAULT; + break; + } + CDBG("flash_set_led_state: return %d\n", rc); + return rc; +} + +int msm_flash_led_gpio_init(struct msm_led_flash_ctrl_t *fctrl) +{ + int rc = 0; + struct msm_camera_sensor_board_info *flashdata = NULL; + struct msm_camera_power_ctrl_t *power_info = NULL; + + CDBG("%s:%d called\n", __func__, __LINE__); + + flashdata = fctrl->flashdata; + power_info = &flashdata->power_info; + if (power_info->gpio_conf->cam_gpiomux_conf_tbl != NULL) { + pr_err("%s:%d mux install\n", __func__, __LINE__); + } + + rc = msm_camera_request_gpio_table( + power_info->gpio_conf->cam_gpio_req_tbl, + power_info->gpio_conf->cam_gpio_req_tbl_size, 1); + if (rc < 0) { + pr_err("%s: request gpio failed\n", __func__); + return rc; + } + + if (fctrl->pinctrl_info.use_pinctrl == true) { + CDBG("%s:%d PC:: flash pins setting to active state", + __func__, __LINE__); + rc = pinctrl_select_state(fctrl->pinctrl_info.pinctrl, + fctrl->pinctrl_info.gpio_state_active); + if (rc) + pr_err("%s:%d cannot set pin to active state", + __func__, __LINE__); + } + msleep(20); + + if (power_info->gpio_conf->gpio_num_info-> + valid[SENSOR_GPIO_FL_RESET] == 1) + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_RESET], + GPIO_OUT_LOW); + + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_EN], + GPIO_OUT_LOW); + + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_NOW], + GPIO_OUT_LOW); + + return 0; +} + +int msm_flash_led_gpio_release(struct msm_led_flash_ctrl_t *fctrl) +{ + int rc = 0, ret = 0; + struct msm_camera_sensor_board_info *flashdata = NULL; + struct msm_camera_power_ctrl_t *power_info = NULL; + + flashdata = fctrl->flashdata; + power_info = &flashdata->power_info; + CDBG("%s:%d called\n", __func__, __LINE__); + if (!fctrl) { + pr_err("%s:%d fctrl NULL\n", __func__, __LINE__); + return -EINVAL; + } + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_EN], + GPIO_OUT_LOW); + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_NOW], + GPIO_OUT_LOW); + if (power_info->gpio_conf->gpio_num_info-> + valid[SENSOR_GPIO_FL_RESET] == 1) + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_RESET], + GPIO_OUT_LOW); + + if (fctrl->pinctrl_info.use_pinctrl == true) { + ret = pinctrl_select_state(fctrl->pinctrl_info.pinctrl, + fctrl->pinctrl_info.gpio_state_suspend); + if (ret) + pr_err("%s:%d cannot set pin to suspend state", + __func__, __LINE__); + } + rc = msm_camera_request_gpio_table( + power_info->gpio_conf->cam_gpio_req_tbl, + power_info->gpio_conf->cam_gpio_req_tbl_size, 0); + if (rc < 0) { + pr_err("%s: request gpio failed\n", __func__); + return rc; + } + return 0; +} + +int msm_flash_led_gpio_off(struct msm_led_flash_ctrl_t *fctrl) +{ + int rc = 0; + struct msm_camera_sensor_board_info *flashdata = NULL; + struct msm_camera_power_ctrl_t *power_info = NULL; + + flashdata = fctrl->flashdata; + power_info = &flashdata->power_info; + CDBG("%s:%d called\n", __func__, __LINE__); + if (!fctrl) { + pr_err("%s:%d fctrl NULL\n", __func__, __LINE__); + return -EINVAL; + } + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_EN], + GPIO_OUT_LOW); + + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_NOW], + GPIO_OUT_LOW); + return rc; +} + +int msm_flash_led_gpio_low(struct msm_led_flash_ctrl_t *fctrl) +{ + int rc = 0; + struct msm_camera_sensor_board_info *flashdata = NULL; + struct msm_camera_power_ctrl_t *power_info = NULL; + CDBG("%s:%d called\n", __func__, __LINE__); + + flashdata = fctrl->flashdata; + power_info = &flashdata->power_info; + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_EN], + GPIO_OUT_LOW); + + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_NOW], + GPIO_OUT_HIGH); + return rc; +} + +int msm_flash_led_gpio_high(struct msm_led_flash_ctrl_t *fctrl) +{ + int rc = 0; + struct msm_camera_sensor_board_info *flashdata = NULL; + struct msm_camera_power_ctrl_t *power_info = NULL; + CDBG("%s:%d called\n", __func__, __LINE__); + + flashdata = fctrl->flashdata; + power_info = &flashdata->power_info; + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_EN], + GPIO_OUT_HIGH); + + gpio_set_value_cansleep( + power_info->gpio_conf->gpio_num_info-> + gpio_num[SENSOR_GPIO_FL_NOW], + GPIO_OUT_LOW); + return rc; +} + +static int32_t msm_led_gpio_get_dt_data(struct device_node *of_node, + struct msm_led_flash_ctrl_t *fctrl) +{ + int32_t rc = 0, i = 0; + struct msm_camera_gpio_conf *gconf = NULL; + struct device_node *flash_src_node = NULL; + struct msm_camera_sensor_board_info *flashdata = NULL; + struct msm_camera_power_ctrl_t *power_info = NULL; + uint32_t count = 0; + uint16_t *gpio_array = NULL; + uint16_t gpio_array_size = 0; + + CDBG("called\n"); + + if (!of_node) { + pr_err("of_node NULL\n"); + return -EINVAL; + } + + fctrl->flashdata = kzalloc(sizeof( + struct msm_camera_sensor_board_info), + GFP_KERNEL); + if (!fctrl->flashdata) { + pr_err("%s failed %d\n", __func__, __LINE__); + return -ENOMEM; + } + + flashdata = fctrl->flashdata; + power_info = &flashdata->power_info; + + rc = of_property_read_u32(of_node, "cell-index", &fctrl->subdev_id); + if (rc < 0) { + pr_err("failed\n"); + return -EINVAL; + } + + CDBG("subdev id %d\n", fctrl->subdev_id); + + rc = of_property_read_string(of_node, "label", + &flashdata->sensor_name); + CDBG("%s label %s, rc %d\n", __func__, + flashdata->sensor_name, rc); + if (rc < 0) { + pr_err("%s failed %d\n", __func__, __LINE__); + goto ERROR1; + } + + rc = of_property_read_u32(of_node, "qcom,cci-master", + &fctrl->cci_i2c_master); + CDBG("%s qcom,cci-master %d, rc %d\n", __func__, fctrl->cci_i2c_master, + rc); + if (rc < 0) { + /* Set default master 0 */ + fctrl->cci_i2c_master = MASTER_0; + rc = 0; + } + + fctrl->pinctrl_info.use_pinctrl = false; + fctrl->pinctrl_info.use_pinctrl = of_property_read_bool(of_node, + "qcom,enable_pinctrl"); + if (of_get_property(of_node, "qcom,flash-source", &count)) { + count /= sizeof(uint32_t); + CDBG("count %d\n", count); + if (count > MAX_LED_TRIGGERS) { + pr_err("failed\n"); + return -EINVAL; + } + for (i = 0; i < count; i++) { + flash_src_node = of_parse_phandle(of_node, + "qcom,flash-source", i); + if (!flash_src_node) { + pr_err("flash_src_node NULL\n"); + continue; + } + + rc = of_property_read_string(flash_src_node, + "linux,default-trigger", + &fctrl->flash_trigger_name[i]); + if (rc < 0) { + pr_err("failed\n"); + of_node_put(flash_src_node); + continue; + } + + CDBG("default trigger %s\n", + fctrl->flash_trigger_name[i]); + + rc = of_property_read_u32(flash_src_node, + "qcom,max-current", + &fctrl->flash_op_current[i]); + if (rc < 0) { + pr_err("failed rc %d\n", rc); + of_node_put(flash_src_node); + continue; + } + + of_node_put(flash_src_node); + + CDBG("max_current[%d] %d\n", + i, fctrl->flash_op_current[i]); + + led_trigger_register_simple( + fctrl->flash_trigger_name[i], + &fctrl->flash_trigger[i]); + } + + } else { /*Handle LED Flash Ctrl by GPIO*/ + power_info->gpio_conf = + kzalloc(sizeof(struct msm_camera_gpio_conf), + GFP_KERNEL); + if (!power_info->gpio_conf) { + pr_err("%s failed %d\n", __func__, __LINE__); + rc = -ENOMEM; + return rc; + } + gconf = power_info->gpio_conf; + + gpio_array_size = of_gpio_count(of_node); + CDBG("%s gpio count %d\n", __func__, gpio_array_size); + + if (gpio_array_size) { + gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size, + GFP_KERNEL); + if (!gpio_array) { + pr_err("%s failed %d\n", __func__, __LINE__); + rc = -ENOMEM; + goto ERROR4; + } + for (i = 0; i < gpio_array_size; i++) { + gpio_array[i] = of_get_gpio(of_node, i); + CDBG("%s gpio_array[%d] = %d\n", __func__, i, + gpio_array[i]); + } + + rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf, + gpio_array, gpio_array_size); + if (rc < 0) { + pr_err("%s failed %d\n", __func__, __LINE__); + goto ERROR4; + } + + rc = msm_camera_get_dt_gpio_set_tbl(of_node, gconf, + gpio_array, gpio_array_size); + if (rc < 0) { + pr_err("%s failed %d\n", __func__, __LINE__); + goto ERROR5; + } + + rc = msm_camera_init_gpio_pin_tbl(of_node, gconf, + gpio_array, gpio_array_size); + if (rc < 0) { + pr_err("%s failed %d\n", __func__, __LINE__); + goto ERROR6; + } + } + + kfree(gpio_array); + return rc; +ERROR6: + kfree(gconf->cam_gpio_set_tbl); +ERROR5: + kfree(gconf->cam_gpio_req_tbl); +ERROR4: + kfree(gconf); +ERROR1: + kfree(fctrl->flashdata); + kfree(gpio_array); + } + return rc; +} + +#ifdef CONFIG_DEBUG_FS +static int set_led_gpio_status(void *data, u64 val) +{ + struct msm_led_flash_ctrl_t *fctrl = + (struct msm_led_flash_ctrl_t *)data; + int rc = -1; + pr_debug("set_led_status: Enter val: %llu", val); + if (!fctrl) { + pr_err("set_led_status: fctrl is NULL"); + return rc; + } + if (!fctrl->func_tbl) { + pr_err("set_led_status: fctrl->func_tbl is NULL"); + return rc; + } + if (val == 0) { + pr_debug("set_led_status: val is disable"); + rc = msm_flash_led_off(fctrl); + } else { + pr_debug("set_led_status: val is enable"); + rc = msm_flash_led_low(fctrl); + } + + return rc; +} + +DEFINE_SIMPLE_ATTRIBUTE(ledflashdbg_fops, + NULL, set_led_gpio_status, "%llu\n"); +#endif + +int msm_flash_gpio_probe(struct platform_device *pdev, + const void *data) +{ + int rc = 0; + struct msm_led_flash_ctrl_t *fctrl = + (struct msm_led_flash_ctrl_t *)data; + struct device_node *of_node = pdev->dev.of_node; + + if (!of_node) { + pr_err("of_node NULL\n"); + goto probe_failure; + } + fctrl->pdev = pdev; + + rc = msm_led_gpio_get_dt_data(pdev->dev.of_node, fctrl); + if (rc < 0) { + pr_err("%s failed line %d rc = %d\n", __func__, __LINE__, rc); + return rc; + } + + /* Assign name for sub device */ + snprintf(fctrl->msm_sd.sd.name, sizeof(fctrl->msm_sd.sd.name), + "%s", fctrl->flashdata->sensor_name); + /* Set device type as Platform*/ + fctrl->flash_device_type = MSM_CAMERA_PLATFORM_DEVICE; + + rc = msm_led_flash_create_v4lsubdev(pdev, fctrl); + if (!rc) + msm_led_torch_create_classdev(pdev, &fctrl); + CDBG("%s: probe success\n", __func__); + return 0; + +probe_failure: + CDBG("%s probe failed\n", __func__); + return rc; +} diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c index bd896c2d677..299e76f2392 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c @@ -13,20 +13,63 @@ #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ +#ifdef CONFIG_MACH_YULONG +#include +#endif #include #include "msm_led_flash.h" +#ifdef CONFIG_MACH_YULONG +#include "msm_camera_io_util.h" +#endif +#ifndef CONFIG_MACH_YULONG static struct led_trigger *torch_trigger; +#endif + +#ifdef CONFIG_MACH_YULONG +static struct gpio torch_gpio[]={ + {933,0,"FLASH"}, + {934,0,"TORCH"}, +}; +#endif static void msm_led_torch_brightness_set(struct led_classdev *led_cdev, enum led_brightness value) { +#ifndef CONFIG_MACH_YULONG if (!torch_trigger) { pr_err("No torch trigger found, can't set brightness\n"); return; } led_trigger_event(torch_trigger, value); + +#else + int rc = 0; + rc = msm_camera_request_gpio_table(torch_gpio, 2, 1); + if (rc < 0) { + pr_err("%s: request gpio failed\n", __func__); + return; + } + + if(value == 0) { + gpio_set_value_cansleep(torch_gpio[0].gpio, GPIO_OUT_LOW); + gpio_set_value_cansleep(torch_gpio[1].gpio, GPIO_OUT_LOW); + } else if (value > 0 && value <= 127) { + gpio_set_value_cansleep(torch_gpio[0].gpio, GPIO_OUT_LOW); + gpio_set_value_cansleep(torch_gpio[1].gpio, GPIO_OUT_HIGH); + } else if(value > 127 && value <= 255) { + gpio_set_value_cansleep(torch_gpio[0].gpio, GPIO_OUT_HIGH); + gpio_set_value_cansleep(torch_gpio[1].gpio, GPIO_OUT_LOW); + } else { + pr_err("%s: invalid value\n", __func__); + } + + rc = msm_camera_request_gpio_table(torch_gpio, 2, 0); + if (rc < 0) { + pr_err("%s: free gpio failed\n", __func__); + } +#endif }; static struct led_classdev msm_torch_led[MAX_LED_TRIGGERS] = { @@ -51,6 +94,7 @@ int32_t msm_led_torch_create_classdev(struct platform_device *pdev, void *data) { int32_t i, rc = 0; +#ifndef CONFIG_MACH_YULONG struct msm_led_flash_ctrl_t *fctrl = (struct msm_led_flash_ctrl_t *)data; @@ -77,6 +121,17 @@ int32_t msm_led_torch_create_classdev(struct platform_device *pdev, return -EINVAL; } } +#else + i = 0; + msm_led_torch_brightness_set(&msm_torch_led[i], LED_OFF); + rc = led_classdev_register(&pdev->dev, + &msm_torch_led[i]); + if (rc) { + pr_err("Failed to register %d led dev. rc = %d\n", + i, rc); + return rc; + } +#endif return 0; }; diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/sgm3780.c b/drivers/media/platform/msm/camera_v2/sensor/flash/sgm3780.c new file mode 100644 index 00000000000..ca4d42761ed --- /dev/null +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/sgm3780.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include "msm_led_flash.h" + +#define FLASH_NAME "rohm-flash,sgm3780" + +/*#define CONFIG_MSMB_CAMERA_DEBUG*/ +#undef CDBG +#ifdef CONFIG_MSMB_CAMERA_DEBUG +#define CDBG(fmt, args...) pr_err(fmt, ##args) +#else +#define CDBG(fmt, args...) do { } while (0) +#endif + +static struct msm_led_flash_ctrl_t fctrl; + +static const struct of_device_id sgm3780_trigger_dt_match[] = { + {.compatible = "rohm-flash,sgm3780", .data = &fctrl}, + {} +}; +MODULE_DEVICE_TABLE(of, sgm3780_trigger_dt_match); + +static int msm_flash_sgm3780_platform_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + match = of_match_device(sgm3780_trigger_dt_match, &pdev->dev); + if (!match) + return -EFAULT; + return msm_flash_gpio_probe(pdev, match->data); +} + +static struct platform_driver sgm3780_platform_driver = { + .probe = msm_flash_sgm3780_platform_probe, + .driver = { + .name = "rohm-flash,sgm3780", + .owner = THIS_MODULE, + .of_match_table = sgm3780_trigger_dt_match, + }, +}; + +static int __init msm_flash_sgm3780_init_module(void) +{ + int32_t rc = 0; + rc = platform_driver_register(&sgm3780_platform_driver); + if (!rc) + return rc; + pr_debug("%s:%d rc %d\n", __func__, __LINE__, rc); + return 0; +} + +static void __exit msm_flash_sgm3780_exit_module(void) +{ + if (fctrl.pdev) + platform_driver_unregister(&sgm3780_platform_driver); +} + +static struct msm_flash_fn_t sgm3780_func_tbl = { + .flash_get_subdev_id = msm_led_gpio_trigger_get_subdev_id, + .flash_led_config = msm_led_gpio_trigger_config, + .flash_led_init = msm_flash_led_gpio_init, + .flash_led_release = msm_flash_led_gpio_release, + .flash_led_off = msm_flash_led_gpio_off, + .flash_led_low = msm_flash_led_gpio_low, + .flash_led_high = msm_flash_led_gpio_high, +}; + +static struct msm_led_flash_ctrl_t fctrl = { + .func_tbl = &sgm3780_func_tbl, +}; + +module_init(msm_flash_sgm3780_init_module); +module_exit(msm_flash_sgm3780_exit_module); +MODULE_DESCRIPTION("sgm3780 FLASH"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile index 55f52311876..af353b775e4 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile +++ b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile @@ -1,4 +1,5 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2/ ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci +ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io obj-$(CONFIG_MSMB_CAMERA) += msm_camera_io_util.o msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_spi.o msm_camera_dt_util.o diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c index a8d1753ff8f..989c086e140 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c @@ -14,6 +14,7 @@ #include "msm_camera_io_util.h" #include "msm_camera_i2c_mux.h" #include "msm_cci.h" +#include "msm_sensor.h" #define CAM_SENSOR_PINCTRL_STATE_SLEEP "cam_suspend" #define CAM_SENSOR_PINCTRL_STATE_DEFAULT "cam_default" @@ -486,6 +487,8 @@ int msm_camera_get_dt_power_setting_data(struct device_node *of_node, ps[i].seq_val = SENSOR_GPIO_VDIG; else if (!strcmp(seq_name, "sensor_gpio_vana")) ps[i].seq_val = SENSOR_GPIO_VANA; + else if (!strcmp(seq_name, "sensor_gpio_af_pwdm")) + ps[i].seq_val = SENSOR_GPIO_AF_PWDM; else if (!strcmp(seq_name, "sensor_gpio_vaf")) ps[i].seq_val = SENSOR_GPIO_VAF; else if (!strcmp(seq_name, "sensor_gpio_vio")) @@ -1221,7 +1224,10 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, { int rc = 0, index = 0, no_gpio = 0, ret = 0; struct msm_sensor_power_setting *power_setting = NULL; - +#ifdef CONFIG_MACH_YULONG + struct msm_camera_sensor_board_info * sensor_board_info = NULL; + sensor_board_info = container_of(ctrl, struct msm_camera_sensor_board_info ,power_info); +#endif CDBG("%s:%d\n", __func__, __LINE__); if (!ctrl || !sensor_i2c_client) { pr_err("failed ctrl %pK sensor_i2c_client %pK\n", ctrl, @@ -1239,11 +1245,32 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, } else { ctrl->cam_pinctrl_status = 1; } + +#ifdef CONFIG_MACH_YULONG + if (msm_sensor_is_probed(sensor_board_info->sensor_info->position)) { + CDBG("current sensor is already probed\n"); + for (index = 0; index < ctrl->gpio_conf->cam_gpio_req_tbl_size; index++) { + CDBG("current gpio label is :%s\n", + ctrl->gpio_conf->cam_gpio_req_tbl[index].label); + if (!strcmp(ctrl->gpio_conf->cam_gpio_req_tbl[index].label,"CAMIF_MCLK")) { + CDBG("request mclk gpio\n"); + gpio_request( + ctrl->gpio_conf->cam_gpio_req_tbl[index].gpio, + ctrl->gpio_conf->cam_gpio_req_tbl[index].label); + } + } + } else { +#endif + rc = msm_camera_request_gpio_table( ctrl->gpio_conf->cam_gpio_req_tbl, ctrl->gpio_conf->cam_gpio_req_tbl_size, 1); if (rc < 0) no_gpio = rc; +#ifdef CONFIG_MACH_YULONG + } +#endif + if (ctrl->cam_pinctrl_status) { ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl, ctrl->pinctrl_info.gpio_state_active); @@ -1308,6 +1335,11 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, SENSOR_GPIO_MAX); goto power_up_failed; } +#ifdef CONFIG_MACH_YULONG + if (msm_sensor_is_probed(sensor_board_info->sensor_info->position)) { + CDBG("current sensor use system power,and has probed ok,do not request vreg\n"); + } else { +#endif if (power_setting->seq_val < ctrl->num_vreg) msm_camera_config_single_vreg(ctrl->dev, &ctrl->cam_vreg[power_setting->seq_val], @@ -1317,6 +1349,9 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, pr_err("ERR:%s: %d usr_idx:%d dts_idx:%d\n", __func__, __LINE__, power_setting->seq_val, ctrl->num_vreg); +#ifdef CONFIG_MACH_YULONG + } +#endif break; case SENSOR_I2C_MUX: if (ctrl->i2c_conf && ctrl->i2c_conf->use_i2c_mux) @@ -1399,8 +1434,12 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, } } if (ctrl->cam_pinctrl_status) { +#ifndef CONFIG_MACH_YULONG ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl, ctrl->pinctrl_info.gpio_state_suspend); +#else + ret = 0; +#endif if (ret) pr_err("%s:%d cannot set pin to suspend state\n", __func__, __LINE__); @@ -1440,6 +1479,10 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl, int index = 0, ret = 0; struct msm_sensor_power_setting *pd = NULL; struct msm_sensor_power_setting *ps; +#ifdef CONFIG_MACH_YULONG + struct msm_camera_sensor_board_info * sensor_board_info = NULL; + sensor_board_info = container_of(ctrl, struct msm_camera_sensor_board_info ,power_info); +#endif CDBG("%s:%d\n", __func__, __LINE__); if (!ctrl || !sensor_i2c_client) { @@ -1483,10 +1526,25 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl, if (!ctrl->gpio_conf->gpio_num_info->valid [pd->seq_val]) continue; + +#ifdef CONFIG_MACH_YULONG + CDBG("%s:%d gpio set val %d\n", __func__, __LINE__, + ctrl->gpio_conf->gpio_num_info->gpio_num[pd->seq_val]); + if (((SENSOR_GPIO_VIO == pd->seq_val) || + (SENSOR_GPIO_VANA == pd->seq_val) || + (SENSOR_GPIO_VDIG == pd->seq_val) || + (SENSOR_GPIO_VAF == pd->seq_val)) && + msm_sensor_is_probed(sensor_board_info->sensor_info->position)) { + CDBG("camera use Sx voltage,so not disable other voltages-GPIO\n"); + } else { +#endif gpio_set_value_cansleep( ctrl->gpio_conf->gpio_num_info->gpio_num [pd->seq_val], (int) pd->config_val); +#ifdef CONFIG_MACH_YULONG + } +#endif break; case SENSOR_VREG: if (pd->seq_val >= CAM_VREG_MAX) { @@ -1500,6 +1558,11 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl, pd->seq_type, pd->seq_val); if (ps) { +#ifdef CONFIG_MACH_YULONG + if (msm_sensor_is_probed(sensor_board_info->sensor_info->position)) { + CDBG("camera use Sx voltage,and sensor probe ok,so not disable voltages-VREG\n"); + } else { +#endif if (pd->seq_val < ctrl->num_vreg) msm_camera_config_single_vreg(ctrl->dev, &ctrl->cam_vreg[pd->seq_val], @@ -1509,6 +1572,9 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl, pr_err("%s:%d:seq_val:%d > num_vreg: %d\n" , __func__, __LINE__, pd->seq_val, ctrl->num_vreg); +#ifdef CONFIG_MACH_YULONG + } +#endif } else pr_err("%s error in power up/down seq data\n", __func__); @@ -1530,17 +1596,36 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl, } } if (ctrl->cam_pinctrl_status) { +#ifndef CONFIG_MACH_YULONG ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl, ctrl->pinctrl_info.gpio_state_suspend); +#else + ret = 0; +#endif if (ret) pr_err("%s:%d cannot set pin to suspend state", __func__, __LINE__); devm_pinctrl_put(ctrl->pinctrl_info.pinctrl); } ctrl->cam_pinctrl_status = 0; +#ifdef CONFIG_MACH_YULONG + if (msm_sensor_is_probed(sensor_board_info->sensor_info->position)) { + CDBG("current sensor use system power,so do not release gpios,just release mclk gpio\n"); + for (index = 0; index < ctrl->gpio_conf->cam_gpio_req_tbl_size; index++) { + CDBG("current gpio label is :%s\n",ctrl->gpio_conf->cam_gpio_req_tbl[index].label); + if (!strcmp(ctrl->gpio_conf->cam_gpio_req_tbl[index].label,"CAMIF_MCLK")) { + CDBG("release mclk gpio\n"); + gpio_free(ctrl->gpio_conf->cam_gpio_req_tbl[index].gpio); + } + } + } else { +#endif msm_camera_request_gpio_table( ctrl->gpio_conf->cam_gpio_req_tbl, ctrl->gpio_conf->cam_gpio_req_tbl_size, 0); +#ifdef CONFIG_MACH_YULONG + } +#endif CDBG("%s exit\n", __func__); return 0; } diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c index 619cff86bc0..2a07f67fd16 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c @@ -23,6 +23,11 @@ static struct v4l2_file_operations msm_sensor_v4l2_subdev_fops; +#ifdef CONFIG_MACH_YULONG +static bool sensor_probed[2]; +static bool sensor_otp_prepared[2]; +#endif + #ifdef CONFIG_MACH_CKT static uint32_t g_camera_id = 0; @@ -502,7 +507,9 @@ int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl) struct msm_camera_i2c_client *sensor_i2c_client; struct msm_camera_slave_info *slave_info; const char *sensor_name; - +#ifdef CONFIG_MACH_YULONG + int position; +#endif if (!s_ctrl) { pr_err("%s:%d failed: %pK\n", __func__, __LINE__, s_ctrl); @@ -523,6 +530,9 @@ int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl) sensor_i2c_client, slave_info->sensor_id_reg_addr, &chipid, MSM_CAMERA_I2C_WORD_DATA); if (rc < 0) { +#ifdef CONFIG_MACH_YULONG + sensor_probed[s_ctrl->sensordata->sensor_info->position] = false; +#endif pr_err("%s: %s: read id failed\n", __func__, sensor_name); return rc; } @@ -533,6 +543,22 @@ int msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl) pr_err("msm_sensor_match_id chip id doesnot match\n"); return -ENODEV; } +#ifdef CONFIG_MACH_YULONG + position = s_ctrl->sensordata->sensor_info->position; + CDBG("sensor info: name: %s sensor_otp_prepared: %d\n", + s_ctrl->sensordata->sensor_name, sensor_otp_prepared[position]); + if(s_ctrl->func_tbl->sensor_prepare_otp && !sensor_otp_prepared[position]) { + rc = s_ctrl->func_tbl->sensor_prepare_otp(s_ctrl); + if (rc) { + pr_err("sensor_prepare_otp failed\n"); + } else { + CDBG("sensor OTP prepared"); + sensor_otp_prepared[position] = true; + } + } + + sensor_probed[s_ctrl->sensordata->sensor_info->position] = true; +#endif return rc; } @@ -616,7 +642,11 @@ long msm_sensor_subdev_fops_ioctl(struct file *file, return video_usercopy(file, cmd, arg, msm_sensor_subdev_do_ioctl); } +#ifdef CONFIG_MACH_YULONG +int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, +#else static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, +#endif void __user *argp) { struct sensorb_cfg_data32 *cdata = (struct sensorb_cfg_data32 *)argp; @@ -733,6 +763,18 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, kfree(reg_setting); break; } +#ifdef CONFIG_MACH_YULONG + case CFG_UPDATE_OTP: { + if(s_ctrl->func_tbl->sensor_update_otp) { + rc = s_ctrl->func_tbl->sensor_update_otp(s_ctrl); + if (rc) { + pr_err("sensor_update_otp failed\n"); + break; + } + } + break; + } +#endif case CFG_SLAVE_READ_I2C: { struct msm_camera_i2c_read_config read_config; uint16_t local_data = 0; @@ -1060,6 +1102,18 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp) kfree(reg_setting); break; } +#ifdef CONFIG_MACH_YULONG + case CFG_UPDATE_OTP: { + if(s_ctrl->func_tbl->sensor_update_otp) { + rc = s_ctrl->func_tbl->sensor_update_otp(s_ctrl); + if (rc) { + pr_err("sensor_update_otp failed\n"); + break; + } + } + break; + } +#endif case CFG_SLAVE_READ_I2C: { struct msm_camera_i2c_read_config read_config; uint16_t local_data = 0; @@ -1528,6 +1582,13 @@ int32_t msm_sensor_platform_probe(struct platform_device *pdev, return rc; } +#ifdef CONFIG_MACH_YULONG +bool msm_sensor_is_probed(int position){ + CDBG("%s sensor_probed[%d] = %d", __func__, position, sensor_probed[position]); + return sensor_probed[position]; +} +#endif + int msm_sensor_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id, struct msm_sensor_ctrl_t *s_ctrl) { diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h index d9b934fe75e..d77b1ba9331 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h @@ -53,6 +53,10 @@ struct msm_sensor_fn_t { int (*sensor_power_down) (struct msm_sensor_ctrl_t *); int (*sensor_power_up) (struct msm_sensor_ctrl_t *); int (*sensor_match_id) (struct msm_sensor_ctrl_t *); +#ifdef CONFIG_MACH_YULONG + int (*sensor_prepare_otp)(struct msm_sensor_ctrl_t *s_ctrl); + int (*sensor_update_otp) (struct msm_sensor_ctrl_t *); +#endif }; struct msm_sensor_ctrl_t { @@ -82,6 +86,9 @@ struct msm_sensor_ctrl_t { }; int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp); +#ifdef CONFIG_MACH_YULONG +int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp); +#endif int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl); @@ -118,4 +125,9 @@ long msm_sensor_subdev_fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg); #endif + +#ifdef CONFIG_MACH_YULONG +bool msm_sensor_is_probed(int position); +#endif + #endif diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h index 5d438cf548b..0ac00689bb5 100644 --- a/include/media/msm_cam_sensor.h +++ b/include/media/msm_cam_sensor.h @@ -401,6 +401,9 @@ enum msm_sensor_cfg_type_t { CFG_SET_AUTOFOCUS, CFG_CANCEL_AUTOFOCUS, CFG_SET_STREAM_TYPE, +#ifdef CONFIG_MACH_YULONG + CFG_UPDATE_OTP, +#endif }; enum msm_actuator_cfg_type_t {