-
Notifications
You must be signed in to change notification settings - Fork 916
Add LTC3220 driver #3005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add LTC3220 driver #3005
Conversation
6a5debb to
d57b64f
Compare
|
Could you format your commits so that there are spaces between labels? eg:
Additionally, could you add some more context regarding the commits? You can see more examples here: https://lore.kernel.org/linux-arm-kernel/ |
vasbimpikasadi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That shows great effort! It's a bit sparse on comments and I've noted some changes which I think have to be fixed before this gets approved.
nunojsa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round from me. This one will need some iterations before going upstream. I'm also not that familiar with the LED subsystem so I might give it a look at some point to be more helpful.
drivers/leds/leds-ltc3220.c
Outdated
| MODULE_AUTHOR("Edelweise Escala <edelweise.escala@analog.com>"); | ||
| MODULE_DESCRIPTION("LED driver for LTC3220 controllers"); | ||
| MODULE_LICENSE("GPL"); | ||
| MODULE_ALIAS("platform:leds-ltc3220"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically not used anymore
d01ee06 to
b251647
Compare
|
V2 Changelog: dt-bindings: leds: ltc3220: Document LTC3220 18 channel LED Driver leds: ltc3220: add driver Added leds: ltc3220: Documentation for Custom ABI |
80d038e to
03f6cf2
Compare
|
V4 Changelog: fixed name on SoB dt-bindings: leds: ltc3220: Document LTC3220 18 channel LED Driver leds: ltc3220: add driver leds: ltc3220: Documentation for Custom ABI |
| 0 - Enables mode logic to control mode changes based on dropout signal | ||
| 1 - Forces charge pump into 1.5x mode | ||
| 2 - Forces charge pump into 2x mode | ||
| 3 - Forces charge pump into 1x mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm this one seems something HW specific? Is this something that should change at runtime? If I'm right, consider a devicetree attr
| Contact: Edelweise Escala <edelweise.escala@analog.com> | ||
| Description: LTC3220 shutdown command. If you write 1 it | ||
| shuts down part while preserving data in registers. | ||
| If you write 0 device is in normal operation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like something you should implement under PM (Power management). Either runtime PM or normal suspend. Pick one :)
| which allows parallel write on all 18 LED registers, when data is being written on | ||
| REG1. If you write 1 quick_write is enabled, 0 to disable. | ||
|
|
||
| What: /sys/class/leds/<led>/gradation_speed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this one could be better named gradation_period_ms. Then you would actually pass the period in milliseconds which is a better API for the user. This is possible because we have three distinct periods which match 3 distinct ramp times.
| 2 - Ramp time of 0.48s and Period of 0.625s | ||
| 3 - Ramp time of 0.96s and Period of 1.25s | ||
|
|
||
| What: /sys/class/leds/<led>/gradation_is_increasing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this one I would suggest gradation_mode and accept the strings "ramp_up" and "ramp_down". From the IIO world you could also add an additional gradation_mode_available which would be on RO and you would give the user the available possibilities. An example for debugfs:
https://elixir.bootlin.com/linux/v6.18-rc5/source/drivers/iio/adc/ad9467.c#L998
Here you need something different likely
| (0..3) where: | ||
| 0 - On Time of 0.625s and Period of 1.25s | ||
| 1 - On Time of 0.156s and Period of 1.25s | ||
| 2 - On Time of 0.625s and Period of 2.5s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we somehow implement this with?
https://elixir.bootlin.com/linux/v6.18-rc5/source/include/linux/leds.h#L154
Make sure to look at other drivers and the subsystem to see what can be used.
drivers/leds/leds-ltc3220.c
Outdated
| ret = ltc3220_set_blink_and_gradation(ltc3220_state, | ||
| state, | ||
| ltc3220_state->grad_cfg.gradation_speed, | ||
| ltc3220_state->grad_cfg.is_increasing); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above looks very bad
drivers/leds/leds-ltc3220.c
Outdated
| &dev_attr_gradation_is_increasing.attr, | ||
| &dev_attr_blink_cfg.attr, | ||
| NULL | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be prepared to justify these attributes... I'm still not sure about it
drivers/leds/leds-ltc3220.c
Outdated
| ltc3220_gradation_is_increasing_store); | ||
|
|
||
| static ssize_t ltc3220_blink_cfg_show(struct device *dev, | ||
| struct device_attribute *attr, char *buf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take care about the above
drivers/leds/leds-ltc3220.c
Outdated
|
|
||
| ret = ltc3220_set_blink_and_gradation(ltc3220_state, | ||
| ltc3220_state->blink_cfg, | ||
| ltc3220_state->grad_cfg.gradation_speed, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
drivers/leds/leds-ltc3220.c
Outdated
| ret = ltc3220_set_blink_and_gradation(ltc3220_state, | ||
| ltc3220_state->blink_cfg, | ||
| state, | ||
| ltc3220_state->grad_cfg.is_increasing); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure to fix things like the above (unless my github is rendering this in a very odd way)
03f6cf2 to
e16e6b1
Compare
|
V5 Changelog: dt-bindings: leds: ltc3220: Document LTC3220 18 channel LED Driver leds: ltc3220: add driver leds: ltc3220: Documentation for Custom ABI |
vasbimpikasadi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting really better, loads of great feedback from everyone. This is shaping up quite nicely.
drivers/leds/leds-ltc3220.c
Outdated
|
|
||
| ltc3220_state = devm_kzalloc(&client->dev, sizeof(*ltc3220_state), GFP_KERNEL); | ||
| if (!ltc3220_state) | ||
| return -ENODEV; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Memory allocation failure should return -ENOMEM, not -ENODEV
drivers/leds/leds-ltc3220.c
Outdated
| &init_data); | ||
| if (ret) { | ||
| dev_err(&client->dev, "Fail LED class register\n"); | ||
| return -ENOMEM; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ret should be propagated here to aid root causing issues should things go wrong?
drivers/leds/leds-ltc3220.c
Outdated
| NULL | ||
| }; | ||
|
|
||
| static struct attribute_group device_cfg_group = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should be const? It's never modified during runtime
e16e6b1 to
5f3c45f
Compare
|
V6 Changelog: leds: ltc3220: add driver |
| led@6 { | ||
| reg = <6>; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to have some of the properties coming from common.yaml that the device supports. Otherwise I wonder why we $ref it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added function and function-enumerator.
| Contact: Edelweise Escala <edelweise.escala@analog.com> | ||
| Description: LTC3220 read only command to show possible gradiation mode such as: | ||
| "ramp_up" | ||
| "ramp_down" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not sure about the above ABI. Does it make sense to have these as runtime? I'm tempted to suggest DT but you might see what the maintainer has to say about it. Maybe there's already a way to handle it through the subsystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed custom abi, now uses pattern https://elixir.bootlin.com/linux/v6.17.9/source/include/linux/leds.h#L158
drivers/leds/leds-ltc3220.c
Outdated
| } | ||
| } | ||
|
|
||
| ret = devm_device_add_group(&client->dev, &device_cfg_group); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just return devm_device_add_group()
drivers/leds/leds-ltc3220.c
Outdated
| &init_data); | ||
| if (ret) { | ||
| dev_err(&client->dev, "Fail LED class register\n"); | ||
| return ret; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dev_err_probe()
drivers/leds/leds-ltc3220.c
Outdated
| int ret; | ||
|
|
||
| if (!led_cdev->dev || !led_cdev->dev->parent) | ||
| return -ENODEV; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would double check the above can really happen. If it can, maybe it's a problem on subsystem itself
drivers/leds/leds-ltc3220.c
Outdated
| return -ENODEV; | ||
|
|
||
| if (!parent_dev || strcmp(parent_dev->bus->name, "i2c") != 0) | ||
| return -ENODEV; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, all of the above conditions look questionable to me
drivers/leds/leds-ltc3220.c
Outdated
|
|
||
| client = to_i2c_client(parent_dev); | ||
| uled_cfg = container_of(led_cdev, struct ltc3220_uled_cfg, led_cdev); | ||
| ltc3220_state = i2c_get_clientdata(client); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could also use container_of() to get ltc3220_state from uled_cfg assuming led_index is the position in the uled_cfg array. But still why not making easier and just have a pointer to the main ltc3220_state object from uled_cfg? Then you would just need two lines.
drivers/leds/leds-ltc3220.c
Outdated
| break; | ||
| } | ||
|
|
||
| return sysfs_emit(buf, "%u\n", period_ms); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not returning inline in each case statement? I would save some LOC
drivers/leds/leds-ltc3220.c
Outdated
| } | ||
|
|
||
| static ssize_t ltc3220_gradation_period_ms_show(struct device *dev, | ||
| struct device_attribute *attr, char *buf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odd indentation
|
V7 Changelog Documentation/devicetree/bindings/leds/leds-ltc3220.yaml Removed Custom ABI drivers/leds/leds-ltc3220.c |
machschmitt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello, this is my second round of review.
Besides the comments to the code, I'd also suggest to drop the "ltc3220:" part of
"dt-bindings: leds: ltc3220: Document LTC3220 18 channel LED Driver".
ltc3220 doesn't exist in the kernel, yet.
| adi,force-cpo-mode: | ||
| $ref: /schemas/types.yaml#/definitions/uint32 | ||
| description: | ||
| Force charge pump operation mode. | ||
| 0 = Auto mode (default) - Automatically selects optimal charge pump mode | ||
| 1 = 1.5x mode - 1.5x voltage multiplication | ||
| 2 = 2x mode - 2x voltage multiplication | ||
| 3 = 1x mode - Charge pump bypass | ||
| minimum: 0 | ||
| maximum: 3 | ||
| default: 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this similar to LTC3208 force-cpo-mode ?
b087967#diff-abf16a96d0bb11e1c9ed3b93a7bf72cbd73355ea1d4c95ae5c5bf4df79fcd49dR46
Looks like it is. My suggestion is to make LTC3220 and LTC3208 have the same documentation for their charge pump properties. Also, I'd suggest making it a string like in LTC3208 PR. Sometimes we might be tempted to use integers to simplify the property description and make the value writable to device registers. Though, frequently, new devices are released with a similar feature and different values and register configurations. Leading to different (but similar in semantics) properties with specific sets of allowed values that don't do any favor to dts writers. A string will allow describing any new charge pump configuration with adi,force-cpo-mode (or adi,force-cpo-level, whatever is more comprehensive) with a reasonable property value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
matched naming with ltc3208 and used string . Thank You!
| adi,quick-write-enable: | ||
| type: boolean | ||
| description: | ||
| Enable quick write mode. When enabled, writing to LED D1 (register 0x01) | ||
| will update all 18 LED outputs with the same brightness value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't see why this needs to be in device tree. To me, this sounds more like a device runtime configuration property. What about registering a 19th led? Set led_classdev name to "all". At some point during probe, do something like
ltc3220_state->uled_cfg[<19 or last led index>].led_cdev.name = "all";
ltc3220_state->uled_cfg[i].led_cdev.brightness_set_blocking = ltc3220_set_all_led_data;with ltc3220_set_all_led_data doing the same thing as ltc3220_set_led_data, but with is_quick_write always true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a 19th led in device tree with function as quick-write. Thank You!
drivers/leds/leds-ltc3220.c
Outdated
| return dev_err_probe(&client->dev, -ENOMEM, | ||
| "Failed to allocate memory\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the IIO subsystem people usually just return -ENOMEM in these cases. IIRC, trying to print a message would be of no use if the system is already lacking memory.
drivers/leds/leds-ltc3220.c
Outdated
| ret = device_property_read_u8(&client->dev, "adi,force-cpo-mode", | ||
| <c3220_state->command_cfg.force_cpo_mode); | ||
| if (ret) | ||
| ltc3220_state->command_cfg.force_cpo_mode = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you follow my suggestion and make adi,force-cpo-mode a string, use device_property_match_property_string() to simplify the property parsing.
drivers/leds/leds-ltc3220.c
Outdated
| if (device_property_read_bool(&client->dev, "adi,quick-write-enable")) | ||
| ltc3220_state->command_cfg.is_quick_write = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might hopefully be dropped (see comment in device tree doc).
drivers/leds/leds-ltc3220.c
Outdated
| u8 reg_val; | ||
| int ret; | ||
| struct i2c_client *client = ltc3220_state->client; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally like arranging local variables in reverse xmas tree. Don't know how LED subsystem maintainer might prefer those, though.
drivers/leds/leds-ltc3220.c
Outdated
| #define LTC3220_ULED01 0x01 | ||
| #define LTC3220_ULED02 0x02 | ||
| #define LTC3220_ULED03 0x03 | ||
| #define LTC3220_ULED04 0x04 | ||
| #define LTC3220_ULED05 0x05 | ||
| #define LTC3220_ULED06 0x06 | ||
| #define LTC3220_ULED07 0x07 | ||
| #define LTC3220_ULED08 0x08 | ||
| #define LTC3220_ULED09 0x09 | ||
| #define LTC3220_ULED10 0x0A | ||
| #define LTC3220_ULED11 0x0B | ||
| #define LTC3220_ULED12 0x0C | ||
| #define LTC3220_ULED13 0x0D | ||
| #define LTC3220_ULED14 0x0E | ||
| #define LTC3220_ULED15 0x0F | ||
| #define LTC3220_ULED16 0x10 | ||
| #define LTC3220_ULED17 0x11 | ||
| #define LTC3220_ULED18 0x12 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest
#define LTC3220_ULED(x) (x)
but these seem to have not been used?
If these are really not used, then I suggest to drop.
|
V8 Changelog Documentation/devicetree/bindings/leds/leds-ltc3220.yaml drivers/leds/leds-ltc3220.c |
machschmitt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @edelweiseescala,
Driver looks good overall. A few comments left from my side. I'd suggest to wait one week or so (to give time for fellow ADI devs to review this), then send it to the mailing list.
| led@19 { | ||
| reg = <1>; | ||
| function = "quick-write"; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense I guess. Having virtual hardware described in dt looks a bit unusual, but I'll leave the final word about it for dt maintainers. Also note address 1 (reg = <1>) was already being used by led@1.
drivers/leds/leds-ltc3220.c
Outdated
| static int ltc3220_set_command(struct ltc3220_state *ltc3220_state, | ||
| bool is_shutdown, bool is_quick_write) | ||
| { | ||
| struct i2c_client *client = ltc3220_state->client; | ||
| u8 reg_val; | ||
| int ret; | ||
|
|
||
| reg_val = FIELD_PREP(LTC3220_COMMAND_SHUTDOWN, is_shutdown); | ||
| reg_val |= FIELD_PREP(LTC3220_CPO_COMMAND_MASK, | ||
| ltc3220_state->command_cfg.force_cpo_level); | ||
| reg_val |= FIELD_PREP(LTC3220_COMMAND_QUICK_WRITE, is_quick_write); | ||
| ret = i2c_smbus_write_byte_data(client, LTC3220_COMMAND, reg_val); | ||
| if (ret < 0) { | ||
| dev_err(&client->dev, "Set command fail\n"); | ||
| return ret; | ||
| } | ||
|
|
||
| ltc3220_state->command_cfg.is_shutdown = is_shutdown; | ||
|
|
||
| return 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boolean parameters can often be avoided when smaller tasks can be extracted into helper functions.
There's only one place where ltc3220_set_command is called with is_quick_write == true.
I suggest to extract the i2c_smbus_write_byte_data() part into a helper function (e.g. ltc3220_i2c_write(i2c_client, reg_addr, reg_val), name up to you). Then ltc3220_set_command calls ltc3220_i2c_write without setting quick write while ltc3220_set_quick_command (new function) call ltc3220_i2c_write with quick_write set. I think something similar can be done for the is_shutdown thing too. With those, ltc3220_set_command, ltc3220_set_quick_command, ltc3220_shutdown could be called according to each specific situation.
drivers/leds/leds-ltc3220.c
Outdated
| ret = device_property_read_string(&client->dev, "adi,force-cpo-level", &cpo_level_str); | ||
| if (ret) { | ||
| ltc3220_state->command_cfg.force_cpo_level = 0; | ||
| } else { | ||
| ret = match_string(ltc3220_cpo_levels, ARRAY_SIZE(ltc3220_cpo_levels), cpo_level_str); | ||
| if (ret < 0) | ||
| ltc3220_state->command_cfg.force_cpo_level = 0; | ||
| else | ||
| ltc3220_state->command_cfg.force_cpo_level = ret; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use device_property_match_property_string() (https://elixir.bootlin.com/linux/v6.17.8/source/include/linux/property.h#L132) to simplify property parsing (see ad4000 1, ad7944 2 for examples ). Maybe this is trickier than I think? (don't recall the LTC3220 register details).
| if (is_quick_write_led) { | ||
| led = <c3220_state->quick_write_led; | ||
| led->led_index = 0; | ||
| led->led_mode = QUICK_WRITE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit concerned about how the "quick_write" led will appear in user space? I mean, is it going to be clear for the user that this led will write to all LTC3220 connected leads? If so, then LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No because I found no documentation about it in the bindings 😄
57787f5 to
c4f6a95
Compare
Add dt-binding for ltc3220. LTC3220 18 Channel LED driver Signed-off-by: Edelweise Escala <edelweise.escala@analog.com>
Add driver for ltc3220. LTC3220 18 Channel LED Driver Signed-off-by: Edelweise Escala <edelweise.escala@analog.com>
c4f6a95 to
300225a
Compare
Add entry for LTC3220 driver Signed-off-by: Edelweise Escala <edelweise.escala@analog.com>
300225a to
4265a69
Compare
|
V9 Change Log used device_property_match_property_string |
nunojsa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more comments from me. But we're getting ready for upstream AFAICT
| led@19 { | ||
| reg = <19>; | ||
| function = "quick-write"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm is this something defined in schemas/leds/common.yaml?
| if (!fwnode_property_read_string(child, "function", &function)) { | ||
| if (!strcmp(function, "quick-write")) | ||
| is_quick_write_led = true; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the above is a custom property. Isn't quick write affecting all LEDs? If so this should be a device property and it should have a proper vendor prefix. So, a boolean like "adi,quick-write-enable".
Having said the above I'm still not sure where this feature fits the best... Maybe something worth asking upstream when submitting
| ret = fwnode_property_read_u32(child, "reg", &source); | ||
| if (ret != 0 || !source || source > (LTC3220_NUM_LEDS + 1)) | ||
| return dev_err_probe(&client->dev, ret ? ret : -EINVAL, | ||
| "Couldn't read LED address\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above is a bit weird and hard to read. Simplify it:
ret = fwnode_property_read_u32(...);
if (ret)
return dev_err_probe(dev, ret, ...);
if (!source || source > ...)
return dev_err_probe()
| if (is_quick_write_led) { | ||
| led = <c3220_state->quick_write_led; | ||
| led->led_index = 0; | ||
| led->led_mode = QUICK_WRITE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No because I found no documentation about it in the bindings 😄
| struct gpio_desc *reset_gpio = data; | ||
|
|
||
| if (reset_gpio) | ||
| gpiod_set_value_cansleep(reset_gpio, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said, not sure if we need the above but as a side note for the future:
Note that the action is already only added when the reset gpio is available. So the above condition is redundant
| ret = ltc3220_set_blink_and_gradation(ltc3220_state, | ||
| blink_mode, | ||
| ltc3220_state->grad_cfg.gradation_period_ms, | ||
| ltc3220_state->grad_cfg.is_increasing); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it's github rendering but the above does not look to be properly aligned to the open parenthesis.
| ltc3220_state = uled_cfg->ltc3220_state; | ||
|
|
||
| if (len != 2) | ||
| return -EINVAL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would do this before getting uled_cfg.
| if (ret < 0) { | ||
| dev_err(&client->dev, "Failed to set blink/gradation\n"); | ||
| return ret; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personalty I would simplify and just do return i2c_smbus_write_byte_data()
| uled_cfg = container_of(led_cdev, struct ltc3220_uled_cfg, led_cdev); | ||
| ltc3220_state = uled_cfg->ltc3220_state; | ||
|
|
||
| if (uled_cfg->led_mode == QUICK_WRITE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we change mode once on QUICK_WRITE. If not, do it probe once and be done with it :). IOW, why do we need this dance between ltc3220_enable_quick_write() and restore_command? Might be worth a comment about it
PR Description
PR Type
PR Checklist