media: video: tegra: max flash/torch current
Charlie Huang [Mon, 8 Jul 2013 22:29:27 +0000 (15:29 -0700)]
the peak flash/torch current can be set from the board file.
devices: as364x, lm3565, max77387, max77665.

bug 1322024

Change-Id: I3121e39e07c1ff9a7e7dc76ff76f41df84868983
Signed-off-by: Charlie Huang <chahuang@nvidia.com>
Reviewed-on: http://git-master/r/246319
(cherry picked from commit d2520eb46fea2885271aabda1ecb0ff547042b82)
Reviewed-on: http://git-master/r/250874
Reviewed-by: Riham Haidar <rhaidar@nvidia.com>
Tested-by: Riham Haidar <rhaidar@nvidia.com>

drivers/media/video/tegra/as364x.c
drivers/media/video/tegra/lm3565.c
drivers/media/video/tegra/max77387.c
drivers/media/video/tegra/max77665-flash.c
include/media/as364x.h
include/media/lm3565.h

index 7ffeecc..81f80a5 100644 (file)
@@ -35,7 +35,6 @@
 
 /* #define DEBUG_I2C_TRAFFIC */
 
-#define LEDS_SUPPORTED                 2
 #define AS364X_MAX_FLASH_LEVEL         256
 #define AS364X_MAX_TORCH_LEVEL         128
 
@@ -83,8 +82,8 @@
                        (sizeof(struct nvc_torch_timer_capabilities_v1) \
                        + sizeof(struct nvc_torch_timeout_v1) \
                        * AS364X_FLASH_TIMER_NUM)
-#define as364x_max_flash_cap_size (as364x_flash_cap_size * LEDS_SUPPORTED \
-                       + as364x_flash_timeout_size * LEDS_SUPPORTED)
+#define as364x_max_flash_cap_size (as364x_flash_cap_size * 2 \
+                       + as364x_flash_timeout_size * 2)
 
 #define as364x_torch_cap_size \
                        (sizeof(struct nvc_torch_torch_capabilities_v1) \
@@ -94,8 +93,8 @@
                        (sizeof(struct nvc_torch_timer_capabilities_v1) \
                        + sizeof(struct nvc_torch_timeout_v1) \
                        * AS364X_TORCH_TIMER_NUM)
-#define as364x_max_torch_cap_size (as364x_torch_timeout_size * LEDS_SUPPORTED\
-                       + as364x_torch_timeout_size * LEDS_SUPPORTED)
+#define as364x_max_torch_cap_size (as364x_torch_timeout_size * 2\
+                       + as364x_torch_timeout_size * 2)
 
 struct as364x_caps_struct {
        char *name;
@@ -135,16 +134,18 @@ struct as364x_info {
        struct as364x_platform_data *pdata;
        const struct as364x_caps_struct *dev_cap;
        struct nvc_torch_capability_query query;
-       struct nvc_torch_flash_capabilities_v1 *flash_cap[LEDS_SUPPORTED];
-       struct nvc_torch_timer_capabilities_v1 *flash_timeouts[LEDS_SUPPORTED];
-       struct nvc_torch_torch_capabilities_v1 *torch_cap[LEDS_SUPPORTED];
-       struct nvc_torch_timer_capabilities_v1 *torch_timeouts[LEDS_SUPPORTED];
+       struct nvc_torch_flash_capabilities_v1 *flash_cap[2];
+       struct nvc_torch_timer_capabilities_v1 *flash_timeouts[2];
+       struct nvc_torch_torch_capabilities_v1 *torch_cap[2];
+       struct nvc_torch_timer_capabilities_v1 *torch_timeouts[2];
        struct as364x_config config;
        struct as364x_reg_cache regs;
        atomic_t in_use;
        int flash_cap_size;
        int torch_cap_size;
        int pwr_state;
+       u8 max_flash[2];
+       u8 max_torch[2];
        u8 s_mode;
        u8 op_mode;
        u8 led_num;
@@ -308,22 +309,22 @@ static int as364x_set_leds(struct as364x_info *info,
 
        if (mask & 1) {
                if (info->op_mode == AS364X_REG_CONTROL_MODE_FLASH) {
-                       if (curr1 >= info->flash_cap[0]->numberoflevels)
-                               curr1 = info->flash_cap[0]->numberoflevels - 1;
+                       if (curr1 >= info->max_flash[0])
+                               curr1 = info->max_flash[0];
                } else {
-                       if (curr1 >= info->torch_cap[0]->numberoflevels)
-                               curr1 = info->torch_cap[0]->numberoflevels - 1;
+                       if (curr1 >= info->max_torch[0])
+                               curr1 = info->max_torch[0];
                }
        } else
                curr1 = 0;
 
        if (mask & 2 && info->dev_cap->led2_support) {
                if (info->op_mode == AS364X_REG_CONTROL_MODE_FLASH) {
-                       if (curr2 >= info->flash_cap[0]->numberoflevels)
-                               curr2 = info->flash_cap[0]->numberoflevels - 1;
+                       if (curr2 >= info->max_flash[1])
+                               curr2 = info->max_flash[1];
                } else {
-                       if (curr2 >= info->torch_cap[0]->numberoflevels)
-                               curr2 = info->torch_cap[0]->numberoflevels - 1;
+                       if (curr2 >= info->max_torch[1])
+                               curr2 = info->max_torch[1];
                }
        } else
                curr2 = 0;
@@ -478,6 +479,9 @@ static void as364x_config_init(struct as364x_info *info)
        if (pcfg_cust->max_peak_current_mA)
                pcfg->max_peak_current_mA = pcfg_cust->max_peak_current_mA;
 
+       if (pcfg_cust->max_torch_current_mA)
+               pcfg->max_torch_current_mA = pcfg_cust->max_torch_current_mA;
+
        if (pcfg_cust->max_peak_duration_ms)
                pcfg->max_peak_duration_ms = pcfg_cust->max_peak_duration_ms;
 
@@ -488,7 +492,7 @@ static void as364x_config_init(struct as364x_info *info)
        if (pcfg_cust->min_current_mA)
                pcfg->min_current_mA = pcfg_cust->min_current_mA;
 
-       for (i = 0; i < LEDS_SUPPORTED; i++) {
+       for (i = 0; i < 2; i++) {
                if (pcfg_cust->led_config[i].flash_levels &&
                        pcfg_cust->led_config[i].flash_torch_ratio &&
                        pcfg_cust->led_config[i].granularity &&
@@ -592,7 +596,7 @@ static int as364x_configure(struct as364x_info *info, bool update)
        info->led_num = 1;
        if (!pcfg->synchronized_led && pcap->led2_support &&
                (info->led_mask & 3) == 3)
-               info->led_num = LEDS_SUPPORTED;
+               info->led_num = 2;
 
        pqry->version = NVC_TORCH_CAPABILITY_VER_1;
        pqry->flash_num = info->led_num;
@@ -631,39 +635,39 @@ static int as364x_configure(struct as364x_info *info, bool update)
                        pcap->max_indicator_curr_mA;
        }
 
-       if (pcfg->boost_mode)
-               val = pcap->curr_step_uA;
-       else
-               val = pcap->curr_step_boost_uA;
-
        for (i = 0; i < pqry->flash_num; i++) {
                pfcap = info->flash_cap[i];
                pfcap->version = NVC_TORCH_CAPABILITY_VER_1;
                pfcap->led_idx = i;
                pfcap->attribute = 0;
-               pfcap->numberoflevels = pcfg->led_config[i].flash_levels + 1;
                pfcap->granularity = pcfg->led_config[i].granularity;
                pfcap->timeout_num = ARRAY_SIZE(as364x_flash_timer);
                ptmcap = info->flash_timeouts[i];
                pfcap->timeout_off = (void *)ptmcap - (void *)pfcap;
                pfcap->flash_torch_ratio =
                                pcfg->led_config[i].flash_torch_ratio;
-               dev_dbg(info->dev,
-                       "%s flash#%d, attr: %x, levels: %d, g: %d, ratio: %d\n",
-                       __func__, pfcap->led_idx, pfcap->attribute,
-                       pfcap->numberoflevels, pfcap->granularity,
-                       pfcap->flash_torch_ratio);
 
                plvls = pcfg->led_config[i].lumi_levels;
                pfcap->levels[0].guidenum = AS364X_LEVEL_OFF;
                pfcap->levels[0].luminance = 0;
-               for (j = 1; j < pfcap->numberoflevels; j++) {
+               for (j = 1; j < pcfg->led_config[i].flash_levels + 1; j++) {
+                       if (GET_CURRENT_BY_INDEX(info, plvls[j - 1].guidenum) >
+                               pcfg->max_peak_current_mA)
+                               break;
+
                        pfcap->levels[j].guidenum = plvls[j - 1].guidenum;
                        pfcap->levels[j].luminance = plvls[j - 1].luminance;
+                       info->max_flash[i] = plvls[j - 1].guidenum;
                        dev_dbg(info->dev, "%03d - %d\n",
                                pfcap->levels[j].guidenum,
                                pfcap->levels[j].luminance);
                }
+               pfcap->numberoflevels = j;
+               dev_dbg(info->dev,
+                       "%s flash#%d, attr: %x, levels: %d, g: %d, ratio: %d\n",
+                       __func__, pfcap->led_idx, pfcap->attribute,
+                       pfcap->numberoflevels, pfcap->granularity,
+                       pfcap->flash_torch_ratio);
 
                ptmcap->timeout_num = pfcap->timeout_num;
                for (j = 0; j < ptmcap->timeout_num; j++) {
@@ -678,27 +682,32 @@ static int as364x_configure(struct as364x_info *info, bool update)
                ptcap->version = NVC_TORCH_CAPABILITY_VER_1;
                ptcap->led_idx = i;
                ptcap->attribute = 0;
-               ptcap->numberoflevels = pcfg->led_config[i].flash_levels + 1;
-               if (ptcap->numberoflevels > AS364X_MAX_TORCH_LEVEL)
-                       ptcap->numberoflevels = AS364X_MAX_TORCH_LEVEL;
                ptcap->granularity = pcfg->led_config[i].granularity;
                ptcap->timeout_num = ARRAY_SIZE(as364x_torch_timer);
                ptmcap = info->torch_timeouts[i];
                ptcap->timeout_off = (void *)ptmcap - (void *)ptcap;
-               dev_dbg(info->dev, "torch#%d, attr: %x, levels: %d, g: %d\n",
-                       ptcap->led_idx, ptcap->attribute,
-                       ptcap->numberoflevels, ptcap->granularity);
 
                plvls = pcfg->led_config[i].lumi_levels;
                ptcap->levels[0].guidenum = AS364X_LEVEL_OFF;
                ptcap->levels[0].luminance = 0;
-               for (j = 1; j < ptcap->numberoflevels; j++) {
+               for (j = 1; j < pcfg->led_config[i].flash_levels + 1; j++) {
+                       if (GET_CURRENT_BY_INDEX(info, plvls[j - 1].guidenum) >
+                               pcfg->max_torch_current_mA)
+                               break;
+
                        ptcap->levels[j].guidenum = plvls[j - 1].guidenum;
                        ptcap->levels[j].luminance = plvls[j - 1].luminance;
+                       info->max_torch[i] = plvls[j - 1].guidenum;
                        dev_dbg(info->dev, "%03d - %d\n",
                                ptcap->levels[j].guidenum,
                                ptcap->levels[j].luminance);
                }
+               ptcap->numberoflevels = j;
+               if (ptcap->numberoflevels > AS364X_MAX_TORCH_LEVEL)
+                       ptcap->numberoflevels = AS364X_MAX_TORCH_LEVEL;
+               dev_dbg(info->dev, "torch#%d, attr: %x, levels: %d, g: %d\n",
+                       ptcap->led_idx, ptcap->attribute,
+                       ptcap->numberoflevels, ptcap->granularity);
 
                ptmcap->timeout_num = ptcap->timeout_num;
                for (j = 0; j < ptmcap->timeout_num; j++) {
@@ -1292,14 +1301,14 @@ static void as364x_caps_layout(struct as364x_info *info)
        int i;
 
        start_ptr = (void *)info + sizeof(*info);
-       for (i = 0; i < LEDS_SUPPORTED; i++) {
+       for (i = 0; i < 2; i++) {
                info->flash_cap[i] = start_ptr;
                info->flash_timeouts[i] = start_ptr + as364x_flash_cap_size;
                start_ptr += AS364X_FLASH_CAP_TIMEOUT_SIZE;
        }
        info->flash_cap_size = AS364X_FLASH_CAP_TIMEOUT_SIZE;
 
-       for (i = 0; i < LEDS_SUPPORTED; i++) {
+       for (i = 0; i < 2; i++) {
                info->torch_cap[i] = start_ptr;
                info->torch_timeouts[i] = start_ptr + as364x_torch_cap_size;
                start_ptr += AS364X_TORCH_CAP_TIMEOUT_SIZE;
index 0920cd5..9143108 100644 (file)
@@ -137,6 +137,8 @@ struct lm3565_info {
        atomic_t in_use;
        unsigned int edp_state;
        int pwr_state;
+       u8 max_flash;
+       u8 max_torch;
        u8 op_mode;
        u8 power_on;
        u8 new_timer;
@@ -415,8 +417,6 @@ static int lm3565_get_lut_index(u16 val, const u16 *lut, int num)
 
 static int lm3565_set_leds(struct lm3565_info *info, u8 curr)
 {
-       struct nvc_torch_flash_capabilities_v1 *pfcap = &info->flash_cap;
-       struct nvc_torch_torch_capabilities_v1 *ptcap = &info->torch_cap;
        int err = 0;
        u8 regs[6];
        u8 om;
@@ -437,13 +437,13 @@ static int lm3565_set_leds(struct lm3565_info *info, u8 curr)
                goto set_leds_end;
 
        if (info->op_mode == LM3565_MODE_FLASH) {
-               if (curr >= pfcap->numberoflevels - 1)
-                       curr = pfcap->numberoflevels - 2;
+               if (curr >= info->max_flash)
+                       curr = info->max_flash;
                om = 0x0b;
                stb = info->flash_strobe;
        } else {
-               if (curr >= ptcap->numberoflevels - 1)
-                       curr = ptcap->numberoflevels - 2;
+               if (curr >= info->max_torch)
+                       curr = info->max_torch;
                curr <<= 4;
                om = 0x0a;
                stb = 0;
@@ -572,6 +572,9 @@ static void lm3565_config_init(struct lm3565_info *info)
        if (pcfg_cust->max_peak_duration_ms)
                pcfg->max_peak_duration_ms = pcfg_cust->max_peak_duration_ms;
 
+       if (pcfg_cust->max_torch_current_mA)
+               pcfg->max_torch_current_mA = pcfg_cust->max_torch_current_mA;
+
        if (pcfg_cust->max_sustained_current_mA)
                pcfg->max_sustained_current_mA =
                        pcfg_cust->max_sustained_current_mA;
@@ -641,12 +644,13 @@ static int lm3565_configure(struct lm3565_info *info, bool update)
        pfcap->levels[0].luminance = 0;
        plvls = pcfg->led_config.lumi_levels;
        for (i = 1; i < LM3565_MAX_FLASH_LEVEL; i++) {
-               pfcap->levels[i].guidenum = plvls[i - 1].guidenum;
-               if (pfcap->levels[i].guidenum > pcfg->max_peak_current_mA) {
-                       pfcap->levels[i].guidenum = 0;
+               if (lm3565_get_current_mA(plvls[i - 1].guidenum) >
+                       pcfg->max_peak_current_mA)
                        break;
-               }
+
+               pfcap->levels[i].guidenum = plvls[i - 1].guidenum;
                pfcap->levels[i].luminance = plvls[i - 1].luminance;
+               info->max_flash = plvls[i - 1].guidenum;
                dev_dbg(info->dev, "%02d - %d\n",
                        pfcap->levels[i].guidenum, pfcap->levels[i].luminance);
        }
@@ -669,8 +673,13 @@ static int lm3565_configure(struct lm3565_info *info, bool update)
        ptcap->levels[0].guidenum = LM3565_LEVEL_OFF;
        ptcap->levels[0].luminance = 0;
        for (i = 1; i < LM3565_MAX_TORCH_LEVEL; i++) {
+               if (torch_levels[i - 1].luminance / 1000 >
+                       pcfg->max_torch_current_mA)
+                       break;
+
                ptcap->levels[i].guidenum = torch_levels[i - 1].guidenum;
                ptcap->levels[i].luminance = torch_levels[i - 1].luminance;
+               info->max_torch = torch_levels[i - 1].guidenum;
        }
        ptcap->numberoflevels = i;
        ptcap->timeout_num = LM3565_TORCH_TIMER_NUM;
index 2537e12..901d796 100644 (file)
 #define max77387_max_torch_cap_size (max77387_torch_timeout_size * 2\
                        + max77387_torch_timeout_size * 2)
 
-#define GET_CURRENT_BY_INDEX(c)        ((c) * 125 / 8)         /* mul 15.625 mA */
-#define GET_INDEX_BY_CURRENT(c)        ((c) * 8 / 125)         /* div by 15.625 mA */
+/* mul 15625 uA */
+#define GET_CURRENT_UA_INDEX(c)        ((c) * max77387_caps.curr_step_uA)
+/* mul 15.625 mA */
+#define GET_CURRENT_BY_INDEX(c)        ((c) * max77387_caps.curr_step_uA / 1000)
+/* div by 15.625 mA */
+#define GET_INDEX_BY_CURRENT(c)        ((c) * 1000 / max77387_caps.curr_step_uA)
 
 struct max77387_caps_struct {
        u32 curr_step_uA;
@@ -258,6 +262,8 @@ struct max77387_info {
        int flash_cap_size;
        int torch_cap_size;
        int pwr_state;
+       u8 max_flash[2];
+       u8 max_torch[2];
        u16 chip_id;
        u8 op_mode;
        u8 power_is_on;
@@ -505,10 +511,6 @@ static int max77387_set_leds(struct max77387_info *info,
                u8 mask, u8 curr1, u8 curr2)
 {
        struct max77387_settings *pst = &info->settings;
-       u32 f_levels1 = info->flash_cap[0]->numberoflevels - 2;
-       u32 f_levels2 = info->flash_cap[1]->numberoflevels - 2;
-       u32 t_levels1 = info->torch_cap[0]->numberoflevels - 2;
-       u32 t_levels2 = info->torch_cap[1]->numberoflevels - 2;
        int err = 0;
        u8 fled_en = 0;
        u8 regs[11];
@@ -536,13 +538,13 @@ static int max77387_set_leds(struct max77387_info *info,
 
        if (mask & 1) {
                if (info->op_mode == MAXFLASH_MODE_FLASH) {
-                       if (curr1 > f_levels1)
-                               curr1 = f_levels1;
+                       if (curr1 > info->max_flash[0])
+                               curr1 = info->max_flash[0];
                        fled_en |= (pst->fled_trig & FLASH_TRIG_MASK);
                        regs[0] = FLASH_CURRENT(curr1);
                } else {
-                       if (curr1 > t_levels1)
-                               curr1 = t_levels1;
+                       if (curr1 > info->max_torch[0])
+                               curr1 = info->max_torch[0];
                        fled_en |= (pst->fled_trig & TORCH_TRIG_MASK);
                        regs[2] = TORCH_CURRENT(curr1);
                }
@@ -550,13 +552,13 @@ static int max77387_set_leds(struct max77387_info *info,
 
        if (mask & 2) {
                if (info->op_mode == MAXFLASH_MODE_FLASH) {
-                       if (curr2 > f_levels2)
-                               curr2 = f_levels2;
+                       if (curr2 > info->max_flash[1])
+                               curr2 = info->max_flash[1];
                        fled_en |= (pst->fled_trig & FLASH_TRIG_MASK);
                        regs[1] = FLASH_CURRENT(curr2);
                } else {
-                       if (curr2 > t_levels2)
-                               curr2 = t_levels2;
+                       if (curr2 > info->max_torch[1])
+                               curr2 = info->max_torch[1];
                        fled_en |= (pst->fled_trig & TORCH_TRIG_MASK);
                        regs[3] = TORCH_CURRENT(curr2);
                }
@@ -625,7 +627,7 @@ static void max77387_update_config(struct max77387_info *info)
        for (i = 0; i < ARRAY_SIZE(max77387_def_flash_levels); i++) {
                max77387_def_flash_levels[i].guidenum = i;
                max77387_def_flash_levels[i].luminance =
-                       (i + 1) * max77387_caps.curr_step_uA;
+                       GET_CURRENT_UA_INDEX(i + 1);
                dev_dbg(info->dev, "0x%02x - %d\n",
                        i, max77387_def_flash_levels[i].luminance);
        }
@@ -992,29 +994,34 @@ static int max77387_configure(struct max77387_info *info, bool update)
                pfcap->version = NVC_TORCH_CAPABILITY_VER_1;
                pfcap->led_idx = i;
                pfcap->attribute = 0;
-               pfcap->numberoflevels = pcfg->led_config[i].flash_levels + 1;
                pfcap->granularity = pcfg->led_config[i].granularity;
                pfcap->timeout_num = ARRAY_SIZE(max77387_flash_timer);
                ptmcap = info->flash_timeouts[i];
                pfcap->timeout_off = (void *)ptmcap - (void *)pfcap;
                pfcap->flash_torch_ratio =
                                pcfg->led_config[i].flash_torch_ratio;
-               dev_dbg(info->dev,
-                       "%s flash#%d, attr: %x, levels: %d, g: %d, ratio: %d\n",
-                       __func__, pfcap->led_idx, pfcap->attribute,
-                       pfcap->numberoflevels, pfcap->granularity,
-                       pfcap->flash_torch_ratio);
 
                plvls = pcfg->led_config[i].lumi_levels;
                pfcap->levels[0].guidenum = MAX77387_LEVEL_OFF;
                pfcap->levels[0].luminance = 0;
-               for (j = 1; j < pfcap->numberoflevels; j++) {
+               for (j = 1; j < pcfg->led_config[i].flash_levels + 1; j++) {
+                       if (GET_CURRENT_BY_INDEX(plvls[j - 1].guidenum) >
+                               pcfg->max_peak_current_mA)
+                               break;
+
                        pfcap->levels[j].guidenum = plvls[j - 1].guidenum;
                        pfcap->levels[j].luminance = plvls[j - 1].luminance;
+                       info->max_flash[i] = plvls[j - 1].guidenum;
                        dev_dbg(info->dev, "%02d - %d\n",
                                pfcap->levels[j].guidenum,
                                pfcap->levels[j].luminance);
                }
+               pfcap->numberoflevels = j;
+               dev_dbg(info->dev,
+                       "%s flash#%d, attr: %x, levels: %d, g: %d, ratio: %d\n",
+                       __func__, pfcap->led_idx, pfcap->attribute,
+                       pfcap->numberoflevels, pfcap->granularity,
+                       pfcap->flash_torch_ratio);
 
                ptmcap->timeout_num = pfcap->timeout_num;
                for (j = 0; j < ptmcap->timeout_num; j++) {
@@ -1029,25 +1036,30 @@ static int max77387_configure(struct max77387_info *info, bool update)
                ptcap->version = NVC_TORCH_CAPABILITY_VER_1;
                ptcap->led_idx = i;
                ptcap->attribute = 0;
-               ptcap->numberoflevels = pcfg->led_config[i].flash_levels + 1;
                ptcap->granularity = pcfg->led_config[i].granularity;
                ptcap->timeout_num = ARRAY_SIZE(max77387_torch_timer);
                ptmcap = info->torch_timeouts[i];
                ptcap->timeout_off = (void *)ptmcap - (void *)ptcap;
-               dev_dbg(info->dev, "torch#%d, attr: %x, levels: %d, g: %d\n",
-                       ptcap->led_idx, ptcap->attribute,
-                       ptcap->numberoflevels, ptcap->granularity);
 
                plvls = pcfg->led_config[i].lumi_levels;
                ptcap->levels[0].guidenum = MAX77387_LEVEL_OFF;
                ptcap->levels[0].luminance = 0;
                for (j = 1; j < ptcap->numberoflevels; j++) {
+                       if (GET_CURRENT_BY_INDEX(plvls[j - 1].guidenum) >
+                               pcfg->max_torch_current_mA)
+                               break;
+
                        ptcap->levels[j].guidenum = plvls[j - 1].guidenum;
                        ptcap->levels[j].luminance = plvls[j - 1].luminance;
+                       info->max_torch[i] = plvls[j - 1].guidenum;
                        dev_dbg(info->dev, "%02d - %d\n",
                                ptcap->levels[j].guidenum,
                                ptcap->levels[j].luminance);
                }
+               ptcap->numberoflevels = j;
+               dev_dbg(info->dev, "torch#%d, attr: %x, levels: %d, g: %d\n",
+                       ptcap->led_idx, ptcap->attribute,
+                       ptcap->numberoflevels, ptcap->granularity);
 
                ptmcap->timeout_num = ptcap->timeout_num;
                for (j = 0; j < ptmcap->timeout_num; j++) {
index fbcf6a8..419dceb 100644 (file)
 #define BOOST_VOLT_CEILING             5500 /* mV */
 #define BOOST_VOLT_STEP                        25 /* mV */
 
-#define MAX77665_F_LED_NUM             2
 #define MAX77665_F_MAX_FLASH_LEVEL     ((1 << 6) + 1)
 #define MAX77665_F_MAX_TORCH_LEVEL     ((1 << 4) + 1)
 
@@ -268,6 +267,8 @@ struct max77665_f_info {
        int flash_cap_size;
        int torch_cap_size;
        int pwr_state;
+       u8 max_flash[2];
+       u8 max_torch[2];
        u8 fled_settings;
        u8 op_mode;
        u8 power_is_on;
@@ -492,10 +493,6 @@ static int max77665_f_set_leds(struct max77665_f_info *info,
                u8 mask, u8 curr1, u8 curr2)
 {
        int err = 0;
-       u32 f_levels1 = info->flash_cap[0]->numberoflevels - 2;
-       u32 f_levels2 = info->flash_cap[1]->numberoflevels - 2;
-       u32 t_levels1 = info->torch_cap[0]->numberoflevels - 2;
-       u32 t_levels2 = info->torch_cap[1]->numberoflevels - 2;
        u8 fled_en = 0;
        u8 t_curr = 0;
        u8 regs[6];
@@ -517,13 +514,13 @@ static int max77665_f_set_leds(struct max77665_f_info *info,
 
        if (mask & 1) {
                if (info->op_mode == MAXFLASH_MODE_FLASH) {
-                       if (curr1 > f_levels1)
-                               curr1 = f_levels1;
+                       if (curr1 > info->max_flash[0])
+                               curr1 = info->max_flash[0];
                        fled_en |= (info->fled_settings & LED1_FLASH_TRIG_MASK);
                        regs[0] = curr1;
                } else {
-                       if (curr1 > t_levels1)
-                               curr1 = t_levels1;
+                       if (curr1 > info->max_torch[0])
+                               curr1 = info->max_torch[0];
                        fled_en |= (info->fled_settings & LED1_TORCH_TRIG_MASK);
                        t_curr = curr1;
                }
@@ -531,13 +528,13 @@ static int max77665_f_set_leds(struct max77665_f_info *info,
 
        if (mask & 2) {
                if (info->op_mode == MAXFLASH_MODE_FLASH) {
-                       if (curr2 > f_levels2)
-                               curr2 = f_levels2;
+                       if (curr2 > info->max_flash[1])
+                               curr2 = info->max_flash[1];
                        fled_en |= (info->fled_settings & LED2_FLASH_TRIG_MASK);
                        regs[1] = curr2;
                } else {
-                       if (curr2 > t_levels2)
-                               curr2 = t_levels2;
+                       if (curr2 > info->max_torch[1])
+                               curr2 = info->max_torch[1];
                        fled_en |= (info->fled_settings & LED2_TORCH_TRIG_MASK);
                        t_curr |= curr2 << 4;
                }
@@ -666,7 +663,7 @@ static void max77665_f_update_config(struct max77665_f_info *info)
                pcfg->max_flash_lbdly_r_uS =
                                pcfg_cust->max_flash_lbdly_r_uS;
 
-       for (i = 0; i < MAX77665_F_LED_NUM; i++) {
+       for (i = 0; i < 2; i++) {
                if (pcfg_cust->led_config[i].flash_levels &&
                        pcfg_cust->led_config[i].flash_torch_ratio &&
                        pcfg_cust->led_config[i].granularity &&
@@ -855,29 +852,34 @@ static int max77665_f_configure(struct max77665_f_info *info, bool update)
                pfcap->version = NVC_TORCH_CAPABILITY_VER_1;
                pfcap->led_idx = i;
                pfcap->attribute = 0;
-               pfcap->numberoflevels = pcfg->led_config[i].flash_levels + 1;
                pfcap->granularity = pcfg->led_config[i].granularity;
                pfcap->timeout_num = MAX77665_F_FLASH_TIMER_NUM;
                ptmcap = info->flash_timeouts[i];
                pfcap->timeout_off = (void *)ptmcap - (void *)pfcap;
                pfcap->flash_torch_ratio =
                                pcfg->led_config[i].flash_torch_ratio;
-               dev_dbg(info->dev,
-                       "%s flash#%d, attr: %x, levels: %d, g: %d, ratio: %d\n",
-                       __func__, pfcap->led_idx, pfcap->attribute,
-                       pfcap->numberoflevels, pfcap->granularity,
-                       pfcap->flash_torch_ratio);
 
                plvls = pcfg->led_config[i].lumi_levels;
                pfcap->levels[0].guidenum = MAX77665_F_LEVEL_OFF;
                pfcap->levels[0].luminance = 0;
-               for (j = 1; j < pfcap->numberoflevels; j++) {
+               for (j = 1; j < pcfg->led_config[i].flash_levels + 1; j++) {
+                       if (GET_CURRENT_BY_INDEX(plvls[j - 1].guidenum) >
+                               pcfg->max_peak_current_mA)
+                               break;
+
                        pfcap->levels[j].guidenum = plvls[j - 1].guidenum;
                        pfcap->levels[j].luminance = plvls[j - 1].luminance;
+                       info->max_flash[i] = plvls[j - 1].guidenum;
                        dev_dbg(info->dev, "%02d - %d\n",
                                pfcap->levels[j].guidenum,
                                pfcap->levels[j].luminance);
                }
+               pfcap->numberoflevels = j;
+               dev_dbg(info->dev,
+                       "%s flash#%d, attr: %x, levels: %d, g: %d, ratio: %d\n",
+                       __func__, pfcap->led_idx, pfcap->attribute,
+                       pfcap->numberoflevels, pfcap->granularity,
+                       pfcap->flash_torch_ratio);
 
                ptmcap->timeout_num = pfcap->timeout_num;
                for (j = 0; j < ptmcap->timeout_num; j++) {
@@ -892,25 +894,30 @@ static int max77665_f_configure(struct max77665_f_info *info, bool update)
                ptcap->version = NVC_TORCH_CAPABILITY_VER_1;
                ptcap->led_idx = i;
                ptcap->attribute = 0;
-               ptcap->numberoflevels = pcfg->led_config[i].flash_levels + 1;
                ptcap->granularity = pcfg->led_config[i].granularity;
                ptcap->timeout_num = MAX77665_F_TORCH_TIMER_NUM;
                ptmcap = info->torch_timeouts[i];
                ptcap->timeout_off = (void *)ptmcap - (void *)ptcap;
-               dev_dbg(info->dev, "torch#%d, attr: %x, levels: %d, g: %d\n",
-                       ptcap->led_idx, ptcap->attribute,
-                       ptcap->numberoflevels, ptcap->granularity);
 
                plvls = pcfg->led_config[i].lumi_levels;
                ptcap->levels[0].guidenum = MAX77665_F_LEVEL_OFF;
                ptcap->levels[0].luminance = 0;
-               for (j = 1; j < ptcap->numberoflevels; j++) {
+               for (j = 1; j < pcfg->led_config[i].flash_levels + 1; j++) {
+                       if (GET_CURRENT_BY_INDEX(plvls[j - 1].guidenum) >
+                               pcfg->max_torch_current_mA)
+                               break;
+
                        ptcap->levels[j].guidenum = plvls[j - 1].guidenum;
                        ptcap->levels[j].luminance = plvls[j - 1].luminance;
+                       info->max_torch[i] = plvls[j - 1].guidenum;
                        dev_dbg(info->dev, "%02d - %d\n",
                                ptcap->levels[j].guidenum,
                                ptcap->levels[j].luminance);
                }
+               ptcap->numberoflevels = j;
+               dev_dbg(info->dev, "torch#%d, attr: %x, levels: %d, g: %d\n",
+                       ptcap->led_idx, ptcap->attribute,
+                       ptcap->numberoflevels, ptcap->granularity);
 
                ptmcap->timeout_num = ptcap->timeout_num;
                for (j = 0; j < ptmcap->timeout_num; j++) {
index 9b0cb3b..be887ad 100644 (file)
@@ -58,6 +58,7 @@ struct as364x_config {
        /* LED configuration, two identical leds must be connected. */
        u16 max_total_current_mA; /* Both leds' maximum peak current in mA */
        u16 max_peak_current_mA; /* This led's maximum peak current in mA */
+       u16 max_torch_current_mA; /* This leds maximum torch current in mA */
        u16 max_peak_duration_ms; /* the maximum duration max_peak_current_mA
                                     can be applied */
        u16 max_sustained_current_mA; /* This leds maximum sustained current
index 24e17e8..d69d025 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2012 - 2013, NVIDIA CORPORATION.  All rights reserved.
 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -37,6 +37,7 @@ struct lm3565_config {
        u16 max_peak_current_mA; /* This led's maximum peak current in mA */
        u16 max_peak_duration_ms; /* the maximum duration max_peak_current_mA
                                     can be applied */
+       u16 max_torch_current_mA; /* This leds maximum torch current in mA */
        u16 max_sustained_current_mA; /* This leds maximum sustained current
                                         in mA */
        u16 min_current_mA; /* This leds minimum current in mA, desired