summaryrefslogtreecommitdiff
path: root/drivers/media/video/wmt_v4l2/sensors/flash
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/media/video/wmt_v4l2/sensors/flash
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'drivers/media/video/wmt_v4l2/sensors/flash')
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/flash/flash.c54
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/flash/flash.h36
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/flash/flash_eup2471.c131
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/flash/flash_eup3618.c124
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/flash/flash_gpio.c103
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/flash/flash_ktd231.c156
-rwxr-xr-xdrivers/media/video/wmt_v4l2/sensors/flash/flash_sgm3780.c207
7 files changed, 811 insertions, 0 deletions
diff --git a/drivers/media/video/wmt_v4l2/sensors/flash/flash.c b/drivers/media/video/wmt_v4l2/sensors/flash/flash.c
new file mode 100755
index 00000000..7d5d3b2c
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/flash/flash.c
@@ -0,0 +1,54 @@
+/*
+ * ==========================================================================
+ *
+ * Filename: flash.c
+ *
+ * Description:
+ *
+ * Version: 0.01
+ * Created: 2013年07月02日 14时16分08秒
+ *
+ * Author: smmei (),
+ * Company:
+ *
+ * ==========================================================================
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include "flash.h"
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif
+
+static struct flash_dev *fl_devices[] = {
+ &flash_dev_gpio,
+ &flash_dev_eup2471,
+ &flash_dev_eup3618,
+ &flash_dev_ktd231,
+ &flash_dev_sgm3780,
+};
+
+struct flash_dev *flash_instantiation(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(fl_devices); i++) {
+ struct flash_dev *fl = fl_devices[i];
+ if (fl->init && fl->init() == 0)
+ return fl;
+ }
+ return NULL;
+}
+
+int flash_set_mode(struct flash_dev *fl, int mode)
+{
+ return (fl && fl->set_mode) ? fl->set_mode (mode) : -EINVAL;
+}
+
+void flash_destroy(struct flash_dev *fl)
+{
+ if (fl && fl->exit)
+ fl->exit();
+}
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/flash/flash.h b/drivers/media/video/wmt_v4l2/sensors/flash/flash.h
new file mode 100755
index 00000000..38051ebc
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/flash/flash.h
@@ -0,0 +1,36 @@
+/*
+ * --------------------------------------------------------------------------
+ *
+ * Filename: flash.h
+ *
+ * Description:
+ *
+ * Version: 0.01
+ * Created: 2013年07月02日 14时17分16秒
+ *
+ * Author: smmei (),
+ * Company:
+ * --------------------------------------------------------------------------
+ */
+#ifndef __FLASH_H__
+#define __FLASH_H__
+
+struct flash_dev {
+ char name[20];
+ int (*init)(void);
+ int (*set_mode)(int mode);
+ void (*exit)(void);
+};
+
+extern struct flash_dev flash_dev_gpio;
+extern struct flash_dev flash_dev_eup2471;
+extern struct flash_dev flash_dev_eup3618;
+extern struct flash_dev flash_dev_ktd231;
+extern struct flash_dev flash_dev_sgm3780;
+
+extern struct flash_dev *flash_instantiation(void);
+extern int flash_set_mode(struct flash_dev *fl, int mode);
+extern void flash_destroy(struct flash_dev *fl);
+
+#endif /* #ifndef __FLASH_H__ */
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/flash/flash_eup2471.c b/drivers/media/video/wmt_v4l2/sensors/flash/flash_eup2471.c
new file mode 100755
index 00000000..d45daea4
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/flash/flash_eup2471.c
@@ -0,0 +1,131 @@
+
+/* wmt.camera.flash <flash>:<en>:<flen>
+ * wmt.camera.flash eup2471:3:2
+ */
+
+#include <linux/gpio.h>
+#include <mach/wmt_env.h>
+#include "../cmos-subdev.h"
+#include "../../wmt-vid.h"
+#include "flash.h"
+
+struct eup2471_struct {
+ int gpio_en;
+ int gpio_flen;
+};
+
+static struct eup2471_struct *eup;
+
+#define EUP2471_I2CADDR 0x37
+
+/*
+ * TODO register flash as a subdev
+ */
+static int flash_dev_set_mode(int mode)
+{
+ if (!eup)
+ return -EINVAL;
+
+ switch (mode) {
+ case FLASH_MODE_OFF:
+ gpio_direction_output(eup->gpio_en, 0);
+ gpio_direction_output(eup->gpio_flen, 0);
+ break;
+ case FLASH_MODE_ON:
+ gpio_direction_output(eup->gpio_en, 1);
+ gpio_direction_output(eup->gpio_flen, 0);
+ msleep(1);
+ wmt_vid_i2c_write(EUP2471_I2CADDR, 0x00, 0x00);
+ wmt_vid_i2c_write(EUP2471_I2CADDR, 0x01, 0x33);
+ break;
+ case FLASH_MODE_STROBE:
+ gpio_direction_output(eup->gpio_en, 1);
+ gpio_direction_output(eup->gpio_flen, 1);
+ msleep(1);
+ gpio_direction_output(eup->gpio_flen, 0);
+ break;
+ case FLASH_MODE_TORCH:
+ gpio_direction_output(2, 0);
+ gpio_direction_output(3, 1);
+ msleep(1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int parse_charger_param(void)
+{
+ char *dev_name = "eup2471";
+ char *env = "wmt.camera.flash";
+ char s[64];
+ size_t l = sizeof(s);
+ int gpio_en, gpio_flen;
+ int rc;
+
+ if (wmt_getsyspara(env, s, &l)) {
+ //pr_err("read %s fail!\n", env);
+ return -EINVAL;
+ }
+
+ if (strncmp(s, dev_name, strlen(dev_name))) {
+ return -EINVAL;
+ }
+
+ rc = sscanf(s, "eup2471:%d:%d", &gpio_en, &gpio_flen);
+ if (rc < 2) {
+ pr_err("bad uboot env: %s\n", env);
+ return -EINVAL;
+ }
+
+ rc = gpio_request(gpio_en, "flash eup2471 en");
+ if (rc) {
+ pr_err("flash en gpio(%d) request failed\n", gpio_en);
+ return rc;
+ }
+
+ rc = gpio_request(gpio_flen, "flash eup2471 flen");
+ if (rc) {
+ pr_err("flash flen gpio(%d) request failed\n", gpio_flen);
+ gpio_free(gpio_en);
+ return rc;
+ }
+
+ eup = kzalloc(sizeof(*eup), GFP_KERNEL);
+ if (!eup)
+ return -ENOMEM;
+
+ eup->gpio_en = gpio_en;
+ eup->gpio_flen = gpio_flen;
+
+ printk("flash eup2471 register ok: en %d, flen %d\n",
+ eup->gpio_en, eup->gpio_flen);
+ return 0;
+}
+
+static int flash_dev_init(void)
+{
+ if (eup)
+ return -EINVAL;
+
+ return parse_charger_param();
+}
+
+static void flash_dev_exit(void)
+{
+ if (eup) {
+ gpio_free(eup->gpio_en);
+ gpio_free(eup->gpio_flen);
+ kfree(eup);
+ eup = NULL;
+ }
+}
+
+struct flash_dev flash_dev_eup2471 = {
+ .name = "eup2471",
+ .init = flash_dev_init,
+ .set_mode = flash_dev_set_mode,
+ .exit = flash_dev_exit,
+};
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/flash/flash_eup3618.c b/drivers/media/video/wmt_v4l2/sensors/flash/flash_eup3618.c
new file mode 100755
index 00000000..f8b48ae8
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/flash/flash_eup3618.c
@@ -0,0 +1,124 @@
+
+/* wmt.camera.flash <flash>:<en>:<flen>
+ * wmt.camera.flash eup3618:14:15
+ */
+
+#include <linux/gpio.h>
+#include <mach/wmt_env.h>
+#include "../cmos-subdev.h"
+#include "../../wmt-vid.h"
+#include "flash.h"
+
+struct eup3618_struct {
+ int gpio_en;
+ int gpio_flen;
+};
+
+static struct eup3618_struct *eup;
+
+/*
+ * TODO register flash as a subdev
+ */
+static int flash_dev_set_mode(int mode)
+{
+ if (!eup)
+ return -EINVAL;
+
+ switch (mode) {
+ case FLASH_MODE_OFF:
+ gpio_direction_output(eup->gpio_en, 0);
+ gpio_direction_output(eup->gpio_flen, 0);
+ break;
+ case FLASH_MODE_ON:
+ gpio_direction_output(eup->gpio_en, 1);
+ gpio_direction_output(eup->gpio_flen, 1);
+ break;
+ case FLASH_MODE_STROBE:
+ gpio_direction_output(eup->gpio_en, 0);
+ gpio_direction_output(eup->gpio_flen, 0);
+ break;
+ case FLASH_MODE_TORCH:
+ gpio_direction_output(eup->gpio_en, 1);
+ gpio_direction_output(eup->gpio_flen, 1);
+ msleep(1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int parse_charger_param(void)
+{
+ char *dev_name = "eup3618";
+ char *env = "wmt.camera.flash";
+ char s[64];
+ size_t l = sizeof(s);
+ int gpio_en, gpio_flen;
+ int rc;
+
+ if (wmt_getsyspara(env, s, &l)) {
+ // pr_err("read %s fail!\n", env);
+ return -EINVAL;
+ }
+
+ if (strncmp(s, dev_name, strlen(dev_name))) {
+ return -EINVAL;
+ }
+
+ rc = sscanf(s, "eup3618:%d:%d", &gpio_en, &gpio_flen);
+ if (rc < 2) {
+ pr_err("bad uboot env: %s\n", env);
+ return -EINVAL;
+ }
+
+ rc = gpio_request(gpio_en, "flash eup3618 en");
+ if (rc) {
+ pr_err("flash en gpio(%d) request failed\n", gpio_en);
+ return rc;
+ }
+
+ rc = gpio_request(gpio_flen, "flash eup3618 flen");
+ if (rc) {
+ pr_err("flash flen gpio(%d) request failed\n", gpio_flen);
+ gpio_free(gpio_en);
+ return rc;
+ }
+
+ eup = kzalloc(sizeof(*eup), GFP_KERNEL);
+ if (!eup)
+ return -ENOMEM;
+
+ eup->gpio_en = gpio_en;
+ eup->gpio_flen = gpio_flen;
+
+ printk("flash eup3618 register ok: en %d, flen %d\n",
+ eup->gpio_en, eup->gpio_flen);
+ return 0;
+}
+
+static int flash_dev_init(void)
+{
+ if (eup)
+ return -EINVAL;
+
+ return parse_charger_param();
+}
+
+static void flash_dev_exit(void)
+{
+ if (eup) {
+ gpio_free(eup->gpio_en);
+ gpio_free(eup->gpio_flen);
+ kfree(eup);
+ eup = NULL;
+ }
+}
+
+struct flash_dev flash_dev_eup3618 = {
+ .name = "eup3618",
+ .init = flash_dev_init,
+ .set_mode = flash_dev_set_mode,
+ .exit = flash_dev_exit,
+};
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/flash/flash_gpio.c b/drivers/media/video/wmt_v4l2/sensors/flash/flash_gpio.c
new file mode 100755
index 00000000..7e29306d
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/flash/flash_gpio.c
@@ -0,0 +1,103 @@
+/*
+ * ==========================================================================
+ *
+ * Filename: flash_gpio.c
+ *
+ * Description: wmt.camera.flash gpio:6
+ *
+ * Version: 0.01
+ * Created: 2013年07月02日 15时00分12秒
+ *
+ * Author: smmei (),
+ * Company:
+ *
+ * ==========================================================================
+ */
+
+#include <linux/gpio.h>
+#include <mach/wmt_env.h>
+#include "../cmos-subdev.h"
+#include "flash.h"
+
+static int fl_gpio = -1;
+
+static int flash_dev_set_mode(int mode)
+{
+ if (fl_gpio < 0)
+ return -EINVAL;
+
+ switch (mode) {
+ case FLASH_MODE_OFF:
+ gpio_direction_output(fl_gpio, 0);
+ break;
+ case FLASH_MODE_ON:
+ gpio_direction_output(fl_gpio, 1);
+ break;
+ case FLASH_MODE_STROBE:
+ gpio_direction_output(fl_gpio, 1);
+ break;
+ case FLASH_MODE_TORCH:
+ gpio_direction_output(fl_gpio, 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int parse_charger_param(void)
+{
+ char *dev_name = "gpio";
+ char *env = "wmt.camera.flash";
+ char s[64];
+ size_t l = sizeof(s);
+ int gpio;
+ int rc;
+
+ if (wmt_getsyspara(env, s, &l)) {
+ //pr_err("read %s fail!\n", env);
+ return -EINVAL;
+ }
+
+ if (strncmp(s, dev_name, strlen(dev_name))) {
+ return -EINVAL;
+ }
+
+ rc = sscanf(s, "gpio:%d", &gpio);
+ if (rc < 1) {
+ pr_err("bad uboot env: %s\n", env);
+ return -EINVAL;
+ }
+
+ rc = gpio_request(gpio, "flash gpio");
+ if (rc) {
+ pr_err("flash gpio(%d) request failed\n", gpio);
+ return rc;
+ }
+
+ fl_gpio = gpio;
+ printk("flash gpio%d register success\n", fl_gpio);
+ return 0;
+}
+
+static int flash_dev_init(void)
+{
+ return parse_charger_param();
+}
+
+static void flash_dev_exit(void)
+{
+ if (fl_gpio >= 0) {
+ gpio_free(fl_gpio);
+ fl_gpio = -1;
+ }
+}
+
+struct flash_dev flash_dev_gpio = {
+ .name = "gpio",
+ .init = flash_dev_init,
+ .set_mode = flash_dev_set_mode,
+ .exit = flash_dev_exit,
+};
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/flash/flash_ktd231.c b/drivers/media/video/wmt_v4l2/sensors/flash/flash_ktd231.c
new file mode 100755
index 00000000..a0926e4e
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/flash/flash_ktd231.c
@@ -0,0 +1,156 @@
+
+/* wmt.camera.flash <flash>:<en>:<flen>
+ * wmt.camera.flash ktd231:2
+ */
+
+#include <linux/gpio.h>
+#include <mach/wmt_env.h>
+#include <linux/pwm.h>
+#include "../cmos-subdev.h"
+#include "../../wmt-vid.h"
+#include "flash.h"
+#include <asm/io.h>
+
+struct ktd231_struct {
+ int gpio_en;
+ struct pwm_device *pwm;
+};
+
+static struct ktd231_struct *ktd;
+
+static void config_pwm1_pin(int enable)
+{
+ int val;
+ if(enable) {
+ val = readb(0xd8110200+WMT_MMAP_OFFSET);
+ val &= ~(1 << 7);
+ writeb(val, 0xd8110200+WMT_MMAP_OFFSET);
+ }else{
+ val = readb(0xd8110200+WMT_MMAP_OFFSET);
+ val |= (1 << 7);
+ writeb(val, 0xd8110200+WMT_MMAP_OFFSET);
+ }
+}
+
+static void enable_pwm1_32KHz(int enable)
+{
+ if(enable) {
+ pwm_config(ktd->pwm, 15625, 31250);// configuration output 32Khz
+ pwm_enable(ktd->pwm);
+ //config_pwm1_pin(0x01);
+ printk("enable 32khz output\n");
+ }else{
+ pwm_disable(ktd->pwm);
+ //config_pwm1_pin(0x00);
+ printk("disable 32khz output\n");
+ }
+}
+
+/*
+ * TODO register flash as a subdev
+ */
+static int flash_dev_set_mode(int mode)
+{
+ if (!ktd)
+ return -EINVAL;
+
+ switch (mode) {
+ case FLASH_MODE_OFF:
+ gpio_direction_output(ktd->gpio_en, 0);
+ enable_pwm1_32KHz(0);
+ break;
+ case FLASH_MODE_ON:
+ gpio_direction_output(ktd->gpio_en, 1);
+ enable_pwm1_32KHz(0);
+ break;
+ case FLASH_MODE_STROBE:
+ break;
+ case FLASH_MODE_TORCH:
+ gpio_direction_output(ktd->gpio_en, 0);
+ enable_pwm1_32KHz(1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int parse_charger_param(void)
+{
+ char *dev_name = "ktd231";
+ char *env = "wmt.camera.flash";
+ char s[64];
+ size_t l = sizeof(s);
+ int gpio_en;
+ int rc;
+ struct pwm_device *pwm;
+
+ if (wmt_getsyspara(env, s, &l)) {
+ // pr_err("read %s fail!\n", env);
+ return -EINVAL;
+ }
+
+ if (strncmp(s, dev_name, strlen(dev_name))) {
+ return -EINVAL;
+ }
+
+ rc = sscanf(s, "ktd231:%d", &gpio_en);
+ if (rc < 1) {
+ pr_err("bad uboot env: %s\n", env);
+ return -EINVAL;
+ }
+
+ rc = gpio_request(gpio_en, "flash ktd231 en");
+ if (rc) {
+ pr_err("flash en gpio(%d) request failed\n", gpio_en);
+ return rc;
+ }
+ gpio_direction_output(gpio_en, 0);
+
+ pwm = pwm_request(1, "pwm_flash");
+ if (IS_ERR(pwm)) {
+ pr_err("unable to request PWM for flash\n");
+ gpio_free(gpio_en);
+ return -EINVAL;
+ }
+
+ ktd = kzalloc(sizeof(*ktd), GFP_KERNEL);
+ if (!ktd)
+ return -ENOMEM;
+
+ config_pwm1_pin(0x01);
+
+ ktd->gpio_en = gpio_en;
+ ktd->pwm = pwm;
+ enable_pwm1_32KHz(0);
+ printk("flash ktd231 register ok: en %d\n",ktd->gpio_en);
+
+ return 0;
+}
+
+static int flash_dev_init(void)
+{
+ if (ktd)
+ return -EINVAL;
+
+ return parse_charger_param();
+}
+
+static void flash_dev_exit(void)
+{
+ if (ktd) {
+ enable_pwm1_32KHz(0);
+ gpio_free(ktd->gpio_en);
+ pwm_free(ktd->pwm);
+ kfree(ktd);
+ ktd = NULL;
+ }
+}
+
+struct flash_dev flash_dev_ktd231 = {
+ .name = "ktd231",
+ .init = flash_dev_init,
+ .set_mode = flash_dev_set_mode,
+ .exit = flash_dev_exit,
+};
+
diff --git a/drivers/media/video/wmt_v4l2/sensors/flash/flash_sgm3780.c b/drivers/media/video/wmt_v4l2/sensors/flash/flash_sgm3780.c
new file mode 100755
index 00000000..42353545
--- /dev/null
+++ b/drivers/media/video/wmt_v4l2/sensors/flash/flash_sgm3780.c
@@ -0,0 +1,207 @@
+
+/* wmt.camera.flash <flash>:<en>:<flen>:<torch_key>
+ * wmt.camera.flash sgm3780:3:2:12
+ */
+
+#include <linux/gpio.h>
+#include <mach/wmt_iomux.h>
+#include <linux/irq.h>
+#include <mach/wmt_env.h>
+#include "../cmos-subdev.h"
+#include "../../wmt-vid.h"
+#include "flash.h"
+
+enum key_status {
+ Idle,Pending,Pressure
+};
+
+struct key_struct{
+ int gpio;
+ enum key_status sts;
+ bool need_on;
+ struct work_struct work;
+};
+
+struct sgm3780_struct {
+ int gpio_en;
+ int gpio_flen;
+ struct key_struct torch_key;
+};
+
+static struct sgm3780_struct *eup;
+
+/*
+ * TODO register flash as a subdev
+ */
+static int flash_dev_set_mode(int mode)
+{
+ if (!eup)
+ return -EINVAL;
+
+ switch (mode) {
+ case FLASH_MODE_OFF:
+ gpio_direction_output(eup->gpio_en, 0);
+ gpio_direction_output(eup->gpio_flen, 0);
+ break;
+ case FLASH_MODE_ON:
+ gpio_direction_output(eup->gpio_en, 1);
+ gpio_direction_output(eup->gpio_flen, 1);
+ break;
+ case FLASH_MODE_STROBE:
+ gpio_direction_output(eup->gpio_en, 0);
+ gpio_direction_output(eup->gpio_flen, 0);
+ break;
+ case FLASH_MODE_TORCH:
+ gpio_direction_output(eup->gpio_en, 1);
+ gpio_direction_output(eup->gpio_flen, 0);
+ msleep(1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void flash_key_scan_work(struct work_struct *work)
+{
+ struct sgm3780_struct *peup = container_of(work, struct sgm3780_struct,torch_key.work);
+
+ if(peup->torch_key.sts !=Idle){
+ pr_err("torch key is busy!!!\n");
+ goto work_done;
+ }
+ peup->torch_key.sts = Pending;
+ msleep(50);
+ if(peup->torch_key.sts == Pending){
+ if(!gpio_get_value(peup->torch_key.gpio)){
+ peup->torch_key.sts = Pressure;
+ }
+ }
+
+ if(peup->torch_key.sts == Pressure){
+ if(peup->torch_key.need_on == true){
+ flash_dev_set_mode(FLASH_MODE_TORCH);
+ peup->torch_key.need_on = false;
+ }else{
+ flash_dev_set_mode(FLASH_MODE_OFF);
+ peup->torch_key.need_on = true;
+ }
+ }
+
+work_done:
+ peup->torch_key.sts = Idle;
+ wmt_gpio_unmask_irq(peup->torch_key.gpio);
+}
+
+static irqreturn_t flash_key_ext_irq (int irq, void *dev_id)
+{
+ struct sgm3780_struct *peup = dev_id;
+
+ if(!is_gpio_irqenable(peup->torch_key.gpio) || !gpio_irqstatus(peup->torch_key.gpio))
+ return IRQ_NONE;
+
+ wmt_gpio_ack_irq(peup->torch_key.gpio);
+ wmt_gpio_mask_irq(peup->torch_key.gpio);
+ schedule_work(&peup->torch_key.work);
+
+ return IRQ_HANDLED;
+}
+
+static void key_setup_extirq(struct sgm3780_struct *peup)
+{
+ int ret;
+
+ wmt_gpio_setpull(peup->torch_key.gpio,WMT_GPIO_PULL_UP);
+ wmt_gpio_set_irq_type(peup->torch_key.gpio,IRQ_TYPE_EDGE_FALLING);
+ wmt_gpio_mask_irq(peup->torch_key.gpio);
+ wmt_gpio_ack_irq(peup->torch_key.gpio);
+ ret = request_irq(IRQ_GPIO, flash_key_ext_irq, IRQF_SHARED,"sgm3780_key_irq", peup);
+ if (ret) {
+ printk("request irq type IRQ_TYPE_EDGE_FALLING fail!\n");
+ return;
+ }
+ wmt_gpio_ack_irq(peup->torch_key.gpio);
+ wmt_gpio_unmask_irq(peup->torch_key.gpio);
+}
+
+static int parse_charger_param(void)
+{
+ char *dev_name = "sgm3780";
+ char *env = "wmt.camera.flash";
+ char s[64];
+ size_t l = sizeof(s);
+ int gpio_en, gpio_flen,gpio_key;
+ int rc;
+
+ if (wmt_getsyspara(env, s, &l)) {
+ // pr_err("read %s fail!\n", env);
+ return -EINVAL;
+ }
+
+ if (strncmp(s, dev_name, strlen(dev_name))) {
+ return -EINVAL;
+ }
+
+ rc = sscanf(s, "sgm3780:%d:%d:%d", &gpio_en, &gpio_flen,&gpio_key);
+ if (rc < 2) {
+ pr_err("bad uboot env: %s\n", env);
+ return -EINVAL;
+ }
+
+ rc = gpio_request(gpio_en, "flash sgm3780 en");
+ if (rc) {
+ pr_err("flash en gpio(%d) request failed\n", gpio_en);
+ return rc;
+ }
+
+ rc = gpio_request(gpio_flen, "flash sgm3780 flen");
+ if (rc) {
+ pr_err("flash flen gpio(%d) request failed\n", gpio_flen);
+ gpio_free(gpio_en);
+ return rc;
+ }
+
+ eup = kzalloc(sizeof(*eup), GFP_KERNEL);
+ if (!eup)
+ return -ENOMEM;
+
+ eup->gpio_en = gpio_en;
+ eup->gpio_flen = gpio_flen;
+ eup->torch_key.gpio = gpio_key;
+ eup->torch_key.need_on = true;
+ INIT_WORK(&eup->torch_key.work,flash_key_scan_work);
+ key_setup_extirq(eup);
+
+ printk("flash sgm3780 register ok: en %d, flen %d, key %d\n",
+ eup->gpio_en, eup->gpio_flen,eup->torch_key.gpio);
+
+ return 0;
+}
+
+static int flash_dev_init(void)
+{
+ if (eup)
+ return -EINVAL;
+
+ return parse_charger_param();
+}
+
+static void flash_dev_exit(void)
+{
+ if (eup) {
+ gpio_free(eup->gpio_en);
+ gpio_free(eup->gpio_flen);
+ cancel_work_sync(&eup->torch_key.work);
+ free_irq(IRQ_GPIO,eup);
+ kfree(eup);
+ eup = NULL;
+ }
+}
+
+struct flash_dev flash_dev_sgm3780 = {
+ .name = "sgm3780",
+ .init = flash_dev_init,
+ .set_mode = flash_dev_set_mode,
+ .exit = flash_dev_exit,
+};
+