On Fri, Feb 11, 2022 at 10:19:24AM +0100, Javier Martinez Canillas wrote: > This adds a DRM driver for SSD1305, SSD1306, SSD1307 and SSD1309 Solomon > OLED display controllers. > > It's only the core part of the driver and a bus specific driver is needed > for each transport interface supported by the display controllers. ... > +#include <linux/backlight.h> > +#include <linux/bitfield.h> bits.h (FYI, specifically sent a patch few days ago to add explicitly the inclusions that needed for bitfield operations in the example inside bitfield.h). > +#include <linux/delay.h> > +#include <linux/gpio/consumer.h> > +#include <linux/property.h> > +#include <linux/pwm.h> > +#include <linux/regulator/consumer.h> ... > +#define SSD130X_SET_ADDRESS_MODE_HORIZONTAL (0x00) > +#define SSD130X_SET_ADDRESS_MODE_VERTICAL (0x01) > +#define SSD130X_SET_ADDRESS_MODE_PAGE (0x02) > + > +#define SSD130X_SET_AREA_COLOR_MODE_ENABLE (0x1e) > +#define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER (0x05) Do the parentheses add anything here? ... > +/* > + * Helper to write command (SSD130X_COMMAND). The fist variadic argument > + * is the command to write and the following are the command options. This is not correct explanation. Please, rephrase to show that _each_ of the options is sent with a preceding command. > + */ > +static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, > + /* u8 cmd, u8 option, ... */...) > +{ > + va_list ap; > + u8 value; > + int ret; > + > + va_start(ap, count); > + > + do { > + value = va_arg(ap, int); > + ret = regmap_write(ssd130x->regmap, SSD130X_COMMAND, (u8)value); > + if (ret) > + goto out_end; > + } while (--count); > + > +out_end: > + va_end(ap); > + > + return ret; > +} ... > + if (ssd130x->device_info->need_pwm) { Yeah, unfortunately we still don't have pwm_get_optional()... > + ret = ssd130x_pwm_enable(ssd130x); > + if (ret) { > + dev_err(dev, "Failed to enable PWM: %d\n", ret); > + regulator_disable(ssd130x->vcc_reg); > + return ret; > + } > + } ... > +static void ssd130x_power_off(struct ssd130x_device *ssd130x) > +{ > + if (ssd130x->device_info->need_pwm) { Redundant check. The two below are NULL-aware. > + pwm_disable(ssd130x->pwm); > + pwm_put(ssd130x->pwm); > + } > + > + regulator_disable(ssd130x->vcc_reg); > +} ... > + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_COM_PINS_CONFIG, compins); > + if (ret < 0) > + return ret; > + > + One blank line is enough. ... > + for (i = y / 8; i < y / 8 + pages; i++) { > + int m = 8; > + > + /* Last page may be partial */ > + if (8 * (i + 1) > ssd130x->height) > + m = ssd130x->height % 8; Perhaps it can be moved out of the loop with refactored piece below. > + for (j = x; j < x + width; j++) { > + u8 data = 0; > + > + for (k = 0; k < m; k++) { > + u8 byte = buf[(8 * i + k) * line_length + j / 8]; > + u8 bit = (byte >> (j % 8)) & 1; > + > + data |= bit << k; > + } > + data_array[array_idx++] = data; > + } > + } ... > + bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x, > + &ssd130xfb_bl_ops, NULL); > + if (IS_ERR(bl)) { > + ret = PTR_ERR(bl); > + dev_err_probe(dev, ret, "Unable to register backlight device\n"); > + return ERR_PTR(ret); dev_err_probe(dev, PTR_ERR(bl), "Unable to register backlight device\n"); return bl; ? > + } -- With Best Regards, Andy Shevchenko