Thanks a lot for your kind remind, Greg. I repaired the problem using the
checkpatch.pl, please have a look:
This is the patch for the LED Flash Driver, the follow new functions are added:
--LED Mode Selection
--Flash Time Adjust
--Flash Current Adjust
--Torch Current Adjust
--Indicator Current Adjust
--OSPM
--Run-time PM
According to Arjan's comment:
--dev_dbg is removed from set_reg function
--some unnecessary prototypes were cleaned up
According to Alan's comment:
--Check return value of i2c_read/i2c_write
>From 8191350388d021a8635a155aee91ca3bbe0a4d47 Mon Sep 17 00:00:00 2001
From: Tao Jing <[email protected]>
Date: Wed, 13 Oct 2010 15:49:14 +0800
Subject: [PATCH] New functions added to the LED Driver
The Driver supports the following:
--LED Mode Selection
--Flash Time Adjust
--Flash Current Adjust
--Torch Current Adjust
--Indicator Current Adjust
--OSPM
--Run-time PM
Signed-off-by: Tao Jing <[email protected]>
---
drivers/staging/mfld_ledflash/lm3555.h | 160 ++++++++++++++++++
drivers/staging/mfld_ledflash/mfld_ledflash.c | 221 ++++++++++++++++++++++++-
2 files changed, 377 insertions(+), 4 deletions(-)
create mode 100644 drivers/staging/mfld_ledflash/lm3555.h
diff --git a/drivers/staging/mfld_ledflash/lm3555.h
b/drivers/staging/mfld_ledflash/lm3555.h
new file mode 100644
index 0000000..0fc290d
--- /dev/null
+++ b/drivers/staging/mfld_ledflash/lm3555.h
@@ -0,0 +1,160 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LM3555_H
+#define _LM3555_H
+#include <linux/ioctl.h>
+
+/* Design Information Register */
+#define LM3555_DIR 0x0
+
+/* Version Control Register */
+#define LM3555_VCR 0x1
+
+/* Indicator and Timer Register */
+#define LM3555_ITR 0x2
+/* Indicator Current */
+#define LM3555_ITR_IC (0x3 << 6)
+/* Vref Offset Voltage */
+#define LM3555_ITR_VO (0x3 << 4)
+/* Flash Time-out Duration */
+#define LM3555_ITR_FT (0xf << 0)
+
+/* Current Set Register */
+#define LM3555_CSR 0x3
+/* Flash Current Levels */
+#define LM3555_CSR_FC (0xf << 4)
+/* Diode Detection Enable */
+#define LM3555_CSR_DEN (0x1 << 3)
+/* Assist Light Current Levels */
+#define LM3555_CSR_AC (0x7 << 0)
+
+/* Control Register */
+#define LM3555_CR 0x4
+/* Peak Inductor Current Limit Levels */
+#define LM3555_CR_IL (0x1 << 6)
+/* Strobe Signal Usage */
+#define LM3555_CR_SSU (0x1 << 5)
+/* External torch mode enable */
+#define LM3555_CR_TEN (0x1 << 4)
+/* Output Enable */
+#define LM3555_CR_OEN (0x1 << 3)
+/* Strobe Signal Mode */
+#define LM3555_CR_SEN (0x1 << 2)
+/* Output Mode */
+#define LM3555_CR_OM (0x3 << 0)
+
+/* Fault Register */
+#define LM3555_FR 0x5
+/* Over-Voltage Protection */
+#define LM3555_FR_OVP (0x1 << 7)
+/* Circuit Fault */
+#define LM3555_FR_SC (0x1 << 6)
+/* Over-Temperature Protection */
+#define LM3555_FR_OTP (0x1 << 5)
+/* Flash Time-out Fault */
+#define LM3555_FR_TO (0x1 << 4)
+/* Number of LEDs */
+#define LM3555_FR_DN (0x1 << 3)
+/* Indicator LED Fault */
+#define LM3555_FR_IF (0x1 << 2)
+/* Inductor Peak Current Limit Fault */
+#define LM3555_FR_IP (0x1 << 1)
+/* Not Used */
+#define LM3555_FR_RFU (0x1 << 0)
+
+/* value settings for Indicator Current */
+#define IC_2P5_MA 0
+#define IC_5P0_MA 1
+#define IC_7P5_MA 2
+#define IC_10P_MA 3
+
+/* Value settings for Vref Offset Voltages */
+#define VOFF_REF_4P35_V 0
+#define VOFF_REF_4P65_V 1
+#define VOFF_REF_4P05_V 2
+#define VOFF_REF_4P95_V 3
+
+/* Value settings for Flash Time-out Duration*/
+#define FTOUT_100_MS 0
+#define FTOUT_150_MS 1
+#define FTOUT_200_MS 2
+#define FTOUT_250_MS 3
+#define FTOUT_300_MS 4
+#define FTOUT_350_MS 5
+#define FTOUT_400_MS 6
+#define FTOUT_450_MS 7
+#define FTOUT_500_MS 8
+#define FTOUT_550_MS 9
+#define FTOUT_600_MS 10
+#define FTOUT_650_MS 11
+#define FTOUT_700_MS 12
+#define FTOUT_750_MS 13
+#define FTOUT_800_MS 14
+#define FTOUT_850_MS 15
+
+/* Value settings for Flash Current Levels */
+#define FC_200_MA 0
+#define FC_220_MA 1
+#define FC_240_MA 2
+#define FC_260_MA 3
+#define FC_280_MA 4
+#define FC_300_MA 5
+#define FC_320_MA_2LED 6
+#define FC_340_MA 7
+#define FC_360_MA 8
+#define FC_380_MA 9
+#define FC_400_MA_2LED 10
+#define FC_420_MA 11
+#define FC_440_MA 12
+#define FC_460_MA 13
+#define FC_480_MA 14
+#define FC_500_MA 15
+
+/* Value settings for Assit Light Current Levels */
+#define ALC_60_MA 0
+#define ALC_60_MA_2LED 1
+#define ALC_60_MA1 2
+#define ALC_80_MA 3
+#define ALC_100_MA 4
+#define ALC_120_MA 5
+#define ALC_140_MA 6
+#define ALC_160_MA 7
+
+/* Value settings for Peak Inductor Current Limit Levels */
+#define PICL_1p25_A 0
+#define PICL_1p50_A 1
+#define PICL_1p75_A 2
+#define PICL_2p20_A 3
+
+/* Value settings for Output Modes */
+#define OM_EXT_TORCH 0
+#define OM_INDICATOR 1
+#define OM_ASS_LIGHT 2
+#define OM_FLASH_LIGHT 3
+
+/* Field for ioctl */
+/* Flash strobe control */
+#define V4L2_CID_FLASH_STROBE _IOW('v', 1, int)
+/* Flash timeout setting */
+#define V4L2_CID_FLASH_TIMEOUT _IOW('v', 2, int)
+/* Flash intensity setting */
+#define V4L2_CID_FLASH_INTENSITY _IOW('v', 3, int)
+/* Torch intensity setting */
+#define V4L2_CID_TORCH_INTENSITY _IOW('v', 4, int)
+/* Indicator intensity setting */
+#define V4L2_CID_INDICATOR_INTENSITY _IOW('v', 5, int)
+#endif
diff --git a/drivers/staging/mfld_ledflash/mfld_ledflash.c
b/drivers/staging/mfld_ledflash/mfld_ledflash.c
index 624b8b1..3ba6bc1 100644
--- a/drivers/staging/mfld_ledflash/mfld_ledflash.c
+++ b/drivers/staging/mfld_ledflash/mfld_ledflash.c
@@ -27,16 +27,142 @@
#include <linux/input.h>
#include <linux/device.h>
#include <linux/gpio.h>
+#include <linux/pm_runtime.h>
#include <asm/io.h>
+#include "lm3555.h"
+
+static DEFINE_MUTEX(i2c_mutex);
+
+static int set_reg(struct i2c_client *client, u8 reg, u8 mask, u8 value,
+ u8 offset)
+{
+ u8 tmp;
+ int ret;
+
+ mutex_lock(&i2c_mutex);
+
+ ret = i2c_smbus_read_byte_data(client, reg);
+ if (ret < 0) {
+ dev_err(&client->dev, "error read i2c!\n");
+ goto err1;
+ }
+ tmp = (u8) ret;
+ tmp = tmp & (~mask);
+ tmp = tmp | (value << offset);
+ ret = i2c_smbus_write_byte_data(client, reg, tmp);
+ if (ret < 0) {
+ dev_err(&client->dev, "error write i2c!\n");
+ goto err1;
+ }
+err1:
+ mutex_unlock(&i2c_mutex);
+
+ return ret;
+}
+
+/* Set Indicator Current */
+static int mfld_ledflash_set_ic(struct i2c_client *client, u8 value)
+{
+ if (value > IC_10P_MA)
+ return EINVAL;
+
+ return set_reg(client, LM3555_ITR, LM3555_ITR_IC, value, 6);
+}
+
+/* Set Voff Voltage */
+static int mfld_ledflash_set_voff(struct i2c_client *client, u8 value)
+{
+ if (value > VOFF_REF_4P95_V)
+ return EINVAL;
+
+ return set_reg(client, LM3555_ITR, LM3555_ITR_VO, value, 4);
+}
+
+/* set Flash Time out */
+static int mfld_ledflash_set_flashtime(struct i2c_client *client, u8 value)
+{
+ if (value > FTOUT_850_MS)
+ return EINVAL;
+
+ return set_reg(client, LM3555_ITR, LM3555_ITR_FT, value, 0);
+}
+
+/* Set Flash Current */
+static int mfld_ledflash_set_flashcurrent(struct i2c_client *client, u8 value)
+{
+ if (value > FC_500_MA)
+ return EINVAL;
+
+ return set_reg(client, LM3555_CSR, LM3555_CSR_FC, value, 4);
+}
+
+/* Enable Diode DetectionFunction */
+static int mfld_ledflash_set_diodedetection(struct i2c_client *client, u8
value)
+{
+ return set_reg(client, LM3555_CSR, LM3555_CSR_DEN, !!value, 3);
+}
+
+/* Set Assist Light Current */
+static int mfld_ledflash_set_assistlightcurrent(struct i2c_client *client,
+ u8 value)
+{
+ if (value > ALC_160_MA)
+ return EINVAL;
+
+ return set_reg(client, LM3555_CSR, LM3555_CSR_AC, value, 0);
+}
+
+/* Set Pick Inductor Current Limit Levels */
+static int mfld_ledflash_set_inductorcurrentlimit(struct i2c_client *client,
+ u8 value)
+{
+ if (value > PICL_2p20_A)
+ return EINVAL;
+
+ return set_reg(client, LM3555_CR, LM3555_CR_IL, value, 6);
+}
+
+/* Set Led Output mode */
+static int mfld_ledflash_set_outputmode(struct i2c_client *client, u8 value)
+{
+ if (value > OM_FLASH_LIGHT)
+ return EINVAL;
+
+ return set_reg(client, LM3555_CR, LM3555_CR_OM, value, 0);
+}
+
+/* Set Strobe Trige Mode */
+static int mfld_ledflash_set_strobemode(struct i2c_client *client, u8 value)
+{
+ return set_reg(client, LM3555_CR, LM3555_CR_SSU, !!value, 5);
+}
+
+/* Set Externel Torch Enable */
+static int mfld_ledflash_set_exttorch(struct i2c_client *client, u8 value)
+{
+ return set_reg(client, LM3555_CR, LM3555_CR_TEN, !!value, 4);
+}
+
+/* Set Output Enable */
+static int mfld_ledflash_set_outputenable(struct i2c_client *client, u8 value)
+{
+ return set_reg(client, LM3555_CR, LM3555_CR_OEN, !!value, 3);
+}
+
+/* Set Strobe Enable */
+static int mfld_ledflash_set_extstrobe(struct i2c_client *client, u8 value)
+{
+ return set_reg(client, LM3555_CR, LM3555_CR_SEN, !!value, 2);
+}
+
static int mfld_ledflash_detect(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
int ids, version;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-
dev_err(&client->dev, "error checking function\n");
return -ENODEV;
}
@@ -55,6 +181,47 @@ static int mfld_ledflash_detect(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_PM
+static int mfld_ledflash_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ return mfld_ledflash_set_outputenable(client, 0);
+}
+
+static int mfld_ledflash_resume(struct i2c_client *client)
+{
+ return mfld_ledflash_set_outputenable(client, 1);
+}
+
+static void mfld_ledflash_shutdown(struct i2c_client *client)
+{
+ mfld_ledflash_suspend(client, PMSG_SUSPEND);
+}
+
+static int mfld_ledflash_runtime_suspend(struct device *dev)
+{
+ struct i2c_client *i2c;
+
+ i2c = container_of(dev, struct i2c_client, dev);
+ if (i2c)
+ mfld_ledflash_suspend(i2c, PMSG_SUSPEND);
+ return 0;
+}
+
+static int mfld_ledflash_runtime_resume(struct device *dev)
+{
+ struct i2c_client *i2c;
+
+ i2c = container_of(dev, struct i2c_client, dev);
+ if (i2c)
+ mfld_ledflash_resume(i2c);
+ return 0;
+}
+#else
+#define mfld_ledflash_resume NULL
+#define mfld_ledflash_suspend NULL
+#define mfld_ledflash_shutdown NULL
+#endif
+
static int __devinit mfld_ledflash_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -83,8 +250,12 @@ static int __devinit mfld_ledflash_probe(struct i2c_client
*client,
dev_dbg(&client->dev, "Control (0x04): 0x%x\n",
i2c_smbus_read_byte_data(client, 0x04));
- /* request flash GPIO*/
- gpio_request(161, "flash");
+ /* request flash GPIO */
+ err = gpio_request(161, "flash");
+ if (err) {
+ dev_err(&client->dev, "gpio_request failed\n");
+ return err;
+ }
/* Fixme: SW workaround HW issue */
mem = ioremap_nocache(0xff12c854, 24);
@@ -96,6 +267,9 @@ static int __devinit mfld_ledflash_probe(struct i2c_client
*client,
/* Trigger an output from Penwell GP_CORE_65 */
gpio_direction_output(161, 1);
+ /* Enable run-time PM */
+ pm_runtime_enable(&client->dev);
+
return 0;
}
@@ -104,17 +278,56 @@ static int __devexit mfld_ledflash_remove(struct
i2c_client *client)
return 0;
}
+static int mfld_ledflash_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ char *input = arg;
+ int ret = 0;
+
+ switch (cmd) {
+ case V4L2_CID_FLASH_STROBE:
+ ret = mfld_ledflash_set_extstrobe(client, *input);
+ break;
+ case V4L2_CID_FLASH_TIMEOUT:
+ ret = mfld_ledflash_set_flashtime(client, *input);
+ break;
+ case V4L2_CID_FLASH_INTENSITY:
+ ret = mfld_ledflash_set_flashcurrent(client, *input);
+ break;
+ case V4L2_CID_TORCH_INTENSITY:
+ ret = mfld_ledflash_set_assistlightcurrent(client, *input);
+ break;
+ case V4L2_CID_INDICATOR_INTENSITY:
+ ret = mfld_ledflash_set_ic(client, *input);
+ break;
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static const struct i2c_device_id mfld_ledflash_id[] = {
- {"i2c_cam_flash", 0},
+ {"i2c_ledflash", 0},
{}
};
+static const struct dev_pm_ops mfld_ledflash_pm = {
+ .runtime_suspend = mfld_ledflash_runtime_suspend,
+ .runtime_resume = mfld_ledflash_runtime_resume,
+};
+
static struct i2c_driver mfld_ledflash_i2c_driver = {
.driver = {
.name = "mfld_ledflash",
+ .pm = &mfld_ledflash_pm,
},
+ .suspend = mfld_ledflash_suspend,
+ .resume = mfld_ledflash_resume,
.probe = mfld_ledflash_probe,
.remove = __devexit_p(mfld_ledflash_remove),
+ .command = mfld_ledflash_command,
.id_table = mfld_ledflash_id,
};
--
1.7.0.4
-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: Thursday, October 28, 2010 11:26 AM
To: Tao, Jing
Cc: [email protected]
Subject: Re: [Meego-kernel] [PATCH] New functions added to the LED Driver
On Tue, Oct 26, 2010 at 09:56:14AM +0800, Tao, Jing wrote:
> This is the patch for the LED Flash Driver, the follow new functions are
> added:
> --LED Mode Selection
> --Flash Time Adjust
> --Flash Current Adjust
> --Torch Current Adjust
> --Indicator Current Adjust
> --OSPM
> --Run-time PM
>
> According to Arjan's comment:
> --dev_dbg is removed from set_reg function
> --some unnecessary prototypes were cleaned up
>
> According to Alan's comment:
> --Check return value of i2c_read/i2c_write
You forgot to run it through the checkpatch.pl tool :(
_______________________________________________
Meego-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel