mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jacek Anaszewski <j.anaszewski@samsung.com>
To: "Kim, Milo" <milo.kim@ti.com>
Cc: robh+dt@kernel.org, lee.jones@linaro.org, broonie@kernel.org,
	devicetree@vger.kernel.org, linux-leds@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 8/9] leds: add LM3633 driver
Date: Mon, 30 Nov 2015 13:26:59 +0100	[thread overview]
Message-ID: <565C4093.9010802@samsung.com> (raw)
In-Reply-To: <565C0D6F.9000709@ti.com>

On 11/30/2015 09:48 AM, Kim, Milo wrote:
> Hi Jacek,
>
> Thanks for your detailed feedback. Please refer to my comments below.
>
> On 11/27/2015 8:19 PM, Jacek Anaszewski wrote:
>> Hi Milo,
>>
>> Thanks for the update. I have few comments below.
>>
>>> diff --git a/drivers/leds/leds-lm3633.c b/drivers/leds/leds-lm3633.c
>>> new file mode 100644
>>> index 0000000..9c391ca
>>> --- /dev/null
>>> +++ b/drivers/leds/leds-lm3633.c
>>> @@ -0,0 +1,840 @@
>>> +/*
>>> + * TI LM3633 LED driver
>>> + *
>>> + * Copyright 2015 Texas Instruments
>>> + *
>>> + * Author: Milo Kim <milo.kim@ti.com>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +
>>> +#include <linux/bitops.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/leds.h>
>>> +#include <linux/mfd/ti-lmu.h>
>>> +#include <linux/mfd/ti-lmu-register.h>
>>> +#include <linux/module.h>
>>> +#include <linux/mutex.h>
>>> +#include <linux/notifier.h>
>>> +#include <linux/of.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/slab.h>
>>> +
>>> +#define LM3633_MAX_PWM                255
>>> +#define LM3633_MIN_CURRENT            5000
>>> +#define LM3633_MAX_CURRENT            30000
>>> +#define LM3633_MAX_PERIOD            9700
>>> +#define LM3633_SHORT_TIMESTEP            16
>>> +#define LM3633_LONG_TIMESTEP            131
>>> +#define LM3633_TIME_OFFSET            61
>>> +#define LM3633_PATTERN_REG_OFFSET        16
>>> +#define LM3633_IMAX_OFFSET            6
>>> +
>>> +enum lm3633_led_bank_id {
>>> +    LM3633_LED_BANK_C,
>>> +    LM3633_LED_BANK_D,
>>> +    LM3633_LED_BANK_E,
>>> +    LM3633_LED_BANK_F,
>>> +    LM3633_LED_BANK_G,
>>> +    LM3633_LED_BANK_H,
>>> +    LM3633_MAX_LEDS,
>>> +};
>>> +
>>> +/**
>>> + * struct ti_lmu_led_chip
>>> + *
>>> + * @dev:        Parent device pointer
>>> + * @lmu:        LMU structure. Used for register R/W access.
>>> + * @lock:        Secure handling for multiple user interface access
>>> + * @lmu_led:        Multiple LED strings
>>
>> Could you clarify what "string" means here?
>>
>>> + * @num_leds:        Number of LED strings
>>
>> and here?
>
> Oops! I forgot to replace this term with 'output channel'. Thanks for
> catching this.
>
>>> +static u8 lm3633_convert_time_to_index(unsigned int msec)
>>> +{
>>> +    u8 idx, offset;
>>> +
>>> +    /*
>>> +     * Find an approximate index
>>
>> I think that we shouldn't approximate but clamp the msec
>> to the nearest possible device setting.
>>
>>> +     *
>>> +     *      0 <= time <= 1000 : 16ms step
>>> +     *   1000 <  time <= 9700 : 131ms step, base index is 61
>>> +     */
>>> +
>>> +    msec = min_t(int, msec, LM3633_MAX_PERIOD);
>>> +
>>> +    if (msec <= 1000) {
>>> +        idx = msec / LM3633_SHORT_TIMESTEP;
>>> +        if (idx > 1)
>>> +            idx--;
>>> +        offset = 0;
>>> +    } else {
>>> +        idx = (msec - 1000) / LM3633_LONG_TIMESTEP;
>>> +        offset = LM3633_TIME_OFFSET;
>>> +    }
>>> +
>>> +    return idx + offset;
>>> +}
>>> +
>>> +static u8 lm3633_convert_ramp_to_index(unsigned int msec)
>>> +{
>>> +    const int ramp_table[] = { 2, 250, 500, 1000, 2000, 4000, 8000,
>>> 16000 };
>>> +    int size = ARRAY_SIZE(ramp_table);
>>> +    int i;
>>> +
>>> +    if (msec <= ramp_table[0])
>>> +        return 0;
>>> +
>>> +    if (msec > ramp_table[size - 1])
>>> +        return size - 1;
>>> +
>>> +    for (i = 1; i < size; i++) {
>>> +        if (msec == ramp_table[i])
>>> +            return i;
>>> +
>>> +        /* Find an approximate index by looking up the table */
>>
>> Similarly here. So you should have an array of the possible msec
>> values and iterate through it to look for the nearest one.
>
> Driver uses 'ramp_table[]' for this purpose. Could you describe it in
> more details?

Right, but why the values don't match the ones from the documentation?
e.g.: 2, 262, 524, 1049, 2097 etc.

And regarding sysfs attributes - they should be readable and return
the aligned value.

>>> +
>>> +static int lm3633_led_brightness_set(struct led_classdev *cdev,
>>> +                     enum led_brightness brightness)
>>> +{
>>> +    struct ti_lmu_led *lmu_led = container_of(cdev, struct ti_lmu_led,
>>> +                          cdev);
>>> +    struct ti_lmu_led_chip *chip = lmu_led->chip;
>>> +    struct regmap *regmap = chip->lmu->regmap;
>>> +    u8 reg = LM3633_REG_BRT_LVLED_BASE + lmu_led->bank_id;
>>> +    int ret;
>>> +
>>> +    mutex_lock(&chip->lock);
>>> +
>>> +    ret = regmap_write(regmap, reg, brightness);
>>> +    if (ret) {
>>> +        mutex_unlock(&chip->lock);
>>> +        return ret;
>>> +    }
>>> +
>>> +    if (brightness == 0)
>>> +        lm3633_led_disable_bank(lmu_led);
>>
>> This should be checked at first, as I suppose that disabling
>> a bank suffices to turn the LED off.
>
> Well, it's not a big deal when turn off the LED. However, our silicon
> designer recommended brightness update should be done prior to enabling
> LED bank. Let me share some block diagram.
>
> [I2C logic] - [brightness control] - [control bank] - [output channel]
>
> If control bank is enabled first, then previous brightness value in
> register can be used instead of new updated brightness. So brightness
> update should be done first.

So, call "regmap_write(regmap, reg, brightness)" only if brightness > 0.

How about below (error handling skipped):

if (brightness > 0) {
         regmap_write(regmap, reg, brightness);
	lm3633_led_enable_bank(lmu_led);
} else {
	lm3633_led_disable_bank(lmu_led);
}


>
>>> +static u8 lm3633_led_scale_max_brightness(struct ti_lmu_led
>>> *lmu_led, u32 imax)
>>> +{
>>> +    u8 max_current = lm3633_led_convert_current_to_index(imax);
>>> +    const u8 max_brightness_table[] = {
>>> +        [LMU_IMAX_5mA]  = 191,
>>> +        [LMU_IMAX_6mA]  = 197,
>>> +        [LMU_IMAX_7mA]  = 203,
>>> +        [LMU_IMAX_8mA]  = 208,
>>> +        [LMU_IMAX_9mA]  = 212,
>>> +        [LMU_IMAX_10mA] = 216,
>>> +        [LMU_IMAX_11mA] = 219,
>>> +        [LMU_IMAX_12mA] = 222,
>>> +        [LMU_IMAX_13mA] = 225,
>>> +        [LMU_IMAX_14mA] = 228,
>>> +        [LMU_IMAX_15mA] = 230,
>>> +        [LMU_IMAX_16mA] = 233,
>>> +        [LMU_IMAX_17mA] = 235,
>>> +        [LMU_IMAX_18mA] = 237,
>>> +        [LMU_IMAX_19mA] = 239,
>>> +        [LMU_IMAX_20mA] = 241,
>>> +        [LMU_IMAX_21mA] = 242,
>>> +        [LMU_IMAX_22mA] = 244,
>>> +        [LMU_IMAX_23mA] = 246,
>>> +        [LMU_IMAX_24mA] = 247,
>>> +        [LMU_IMAX_25mA] = 249,
>>> +        [LMU_IMAX_26mA] = 250,
>>> +        [LMU_IMAX_27mA] = 251,
>>> +        [LMU_IMAX_28mA] = 253,
>>> +        [LMU_IMAX_29mA] = 254,
>>> +        [LMU_IMAX_30mA] = 255,
>>> +    };
>>
>> After analyzing the subject one more time I think that we need to
>> change the approach regarding max brightness issue.
>>
>> At first - we shouldn't fix max current to max possible register value.
>> Instead we should take led-max-microamp property and write its value
>> to the [0x22 + bank offset] registers.
>>
>> With this approach whole 0-255 range of brightness levels will be
>> valid for the driver.
>>
>> In effect all LMU_IMAX* enums seem to be not needed.
>
> Good to hear that, it's the most simplest work for the device ;)
> Let me update the driver. Thanks!
>
> Best regards,
> Milo
>
>


-- 
Best Regards,
Jacek Anaszewski

  reply	other threads:[~2015-11-30 12:27 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-26  6:56 [PATCH v2 0/9] Support TI LMU devices Milo Kim
2015-11-26  6:56 ` [PATCH v2 1/9] Documentation: dt-bindings: mfd: add TI LMU device binding information Milo Kim
2015-11-27 20:55   ` Rob Herring
2016-01-11  9:46   ` Lee Jones
2015-11-26  6:56 ` [PATCH v2 2/9] Documentation: dt-bindings: leds: backlight: add TI LMU backlight " Milo Kim
2016-01-11  9:53   ` Lee Jones
2015-11-26  6:56 ` [PATCH v2 3/9] Documentation: dt-bindings: leds: add LM3633 LED " Milo Kim
2015-11-27 11:19   ` Jacek Anaszewski
2015-11-30  8:19     ` Kim, Milo
2015-11-30 12:26       ` Jacek Anaszewski
2015-12-07  8:46         ` Kim, Milo
2015-12-07 10:50           ` Jacek Anaszewski
2015-11-26  6:57 ` [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator " Milo Kim
2015-11-27 12:37   ` Mark Brown
2015-11-27 20:44     ` Rob Herring
2015-11-27 22:07       ` Mark Brown
2015-11-27 12:55   ` Applied "regulator: lm363x: add LM363x regulator binding information" to the regulator tree Mark Brown
2015-11-27 20:57   ` [PATCH v2 4/9] Documentation: dt-bindings: regulator: add LM363x regulator binding information Rob Herring
2015-11-26  6:57 ` [PATCH v2 5/9] mfd: add TI LMU driver Milo Kim
2016-01-11 10:17   ` Lee Jones
2015-11-26  6:57 ` [PATCH v2 6/9] mfd: add TI LMU hardware fault monitoring driver Milo Kim
2016-01-11 10:21   ` Lee Jones
2016-01-12  3:36     ` Milo Kim
2016-01-12  7:37       ` Lee Jones
2015-11-26  6:57 ` [PATCH v2 7/9] backlight: add TI LMU backlight driver Milo Kim
2016-01-11  9:57   ` Lee Jones
2016-01-11 23:32     ` Milo Kim
2015-11-26  6:57 ` [PATCH v2 8/9] leds: add LM3633 driver Milo Kim
2015-11-27 11:19   ` Jacek Anaszewski
2015-11-28  8:28     ` Jacek Anaszewski
2015-11-30  8:48     ` Kim, Milo
2015-11-30 12:26       ` Jacek Anaszewski [this message]
2015-11-26  6:57 ` [PATCH v2 9/9] regulator: add LM363X driver Milo Kim
2015-11-27 12:55   ` Applied "regulator: add LM363X driver" to the regulator tree Mark Brown
2016-01-14  7:56   ` [PATCH v2 9/9] regulator: add LM363X driver Milo Kim
2016-01-14 10:27     ` Mark Brown
2016-01-14 23:41       ` Kim, Milo
2016-01-06  7:20 ` [PATCH v2 0/9] Support TI LMU devices Milo Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=565C4093.9010802@samsung.com \
    --to=j.anaszewski@samsung.com \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=milo.kim@ti.com \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome