Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'backlight-next-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight

Pull backlight updates from Lee Jones:
"New Drivers:
- Add support for Monolithic Power Systems MP3309C WLED Step-up Converter

Fix-ups:
- Use/convert to new/better APIs/helpers/MACROs instead of
hand-rolling implementations
- Device Tree Binding updates
- Demote non-kerneldoc header comments
- Improve error handling; return proper error values, simplify, avoid
duplicates, etc
- Convert over to the new (kinda) GPIOD API

Bug Fixes:
- Fix uninitialised local variable"

* tag 'backlight-next-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight:
backlight: hx8357: Convert to agnostic GPIO API
backlight: ili922x: Add an error code check in ili922x_write()
backlight: ili922x: Drop kernel-doc for local macros
backlight: mp3309c: Fix uninitialized local variable
backlight: pwm_bl: Use dev_err_probe
backlight: mp3309c: Add support for MPS MP3309C
dt-bindings: backlight: mp3309c: Remove two required properties

+515 -78
+4 -6
Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml
··· 14 14 programmable switching frequency to optimize efficiency. 15 15 It supports two different dimming modes: 16 16 17 - - analog mode, via I2C commands (default) 18 - - PWM controlled mode. 17 + - analog mode, via I2C commands, as default mode (32 dimming levels) 18 + - PWM controlled mode (optional) 19 19 20 20 The datasheet is available at: 21 21 https://www.monolithicpower.com/en/mp3309c.html ··· 50 50 required: 51 51 - compatible 52 52 - reg 53 - - max-brightness 54 - - default-brightness 55 53 56 54 unevaluatedProperties: false 57 55 ··· 64 66 compatible = "mps,mp3309c"; 65 67 reg = <0x17>; 66 68 pwms = <&pwm1 0 3333333 0>; /* 300 Hz --> (1/f) * 1*10^9 */ 67 - max-brightness = <100>; 68 - default-brightness = <80>; 69 + brightness-levels = <0 4 8 16 32 64 128 255>; 70 + default-brightness = <6>; 69 71 mps,overvoltage-protection-microvolt = <24000000>; 70 72 }; 71 73 };
+7
MAINTAINERS
··· 14804 14804 F: Documentation/driver-api/tty/moxa-smartio.rst 14805 14805 F: drivers/tty/mxser.* 14806 14806 14807 + MP3309C BACKLIGHT DRIVER 14808 + M: Flavio Suligoi <f.suligoi@asem.it> 14809 + L: dri-devel@lists.freedesktop.org 14810 + S: Maintained 14811 + F: Documentation/devicetree/bindings/leds/backlight/mps,mp3309c.yaml 14812 + F: drivers/video/backlight/mp3309c.c 14813 + 14807 14814 MR800 AVERMEDIA USB FM RADIO DRIVER 14808 14815 M: Alexey Klimov <klimov.linux@gmail.com> 14809 14816 L: linux-media@vger.kernel.org
+2 -2
drivers/gpio/gpiolib-of.c
··· 184 184 const char *propname; 185 185 bool active_high; 186 186 } gpios[] = { 187 - #if !IS_ENABLED(CONFIG_LCD_HX8357) 187 + #if IS_ENABLED(CONFIG_LCD_HX8357) 188 188 /* 189 189 * Himax LCD controllers used incorrectly named 190 190 * "gpios-reset" property and also specified wrong ··· 478 478 */ 479 479 const char *compatible; 480 480 } gpios[] = { 481 - #if !IS_ENABLED(CONFIG_LCD_HX8357) 481 + #if IS_ENABLED(CONFIG_LCD_HX8357) 482 482 /* Himax LCD controllers used "gpios-reset" */ 483 483 { "reset", "gpios-reset", "himax,hx8357" }, 484 484 { "reset", "gpios-reset", "himax,hx8369" },
+11
drivers/video/backlight/Kconfig
··· 395 395 help 396 396 This supports TI LP8788 backlight driver. 397 397 398 + config BACKLIGHT_MP3309C 399 + tristate "Backlight Driver for MPS MP3309C" 400 + depends on I2C && PWM 401 + select REGMAP_I2C 402 + help 403 + This supports MPS MP3309C backlight WLED driver in both PWM and 404 + analog/I2C dimming modes. 405 + 406 + To compile this driver as a module, choose M here: the module will 407 + be called mp3309c. 408 + 398 409 config BACKLIGHT_PANDORA 399 410 tristate "Backlight driver for Pandora console" 400 411 depends on TWL4030_CORE
+1
drivers/video/backlight/Makefile
··· 43 43 obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o 44 44 obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o 45 45 obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o 46 + obj-$(CONFIG_BACKLIGHT_MP3309C) += mp3309c.o 46 47 obj-$(CONFIG_BACKLIGHT_MT6370) += mt6370-backlight.o 47 48 obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o 48 49 obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
+22 -52
drivers/video/backlight/hx8357.c
··· 6 6 */ 7 7 8 8 #include <linux/delay.h> 9 + #include <linux/gpio/consumer.h> 9 10 #include <linux/lcd.h> 10 11 #include <linux/module.h> 11 12 #include <linux/of.h> 12 13 #include <linux/of_device.h> 13 - #include <linux/of_gpio.h> 14 14 #include <linux/spi/spi.h> 15 15 16 16 #define HX8357_NUM_IM_PINS 3 ··· 83 83 #define HX8369_SET_GAMMA_CURVE_RELATED 0xe0 84 84 85 85 struct hx8357_data { 86 - unsigned im_pins[HX8357_NUM_IM_PINS]; 87 - unsigned reset; 86 + struct gpio_descs *im_pins; 87 + struct gpio_desc *reset; 88 88 struct spi_device *spi; 89 89 int state; 90 - bool use_im_pins; 91 90 }; 92 91 93 92 static u8 hx8357_seq_power[] = { ··· 320 321 struct hx8357_data *lcd = lcd_get_data(lcdev); 321 322 322 323 /* Reset the screen */ 323 - gpio_set_value(lcd->reset, 1); 324 + gpiod_set_value(lcd->reset, 0); 324 325 usleep_range(10000, 12000); 325 - gpio_set_value(lcd->reset, 0); 326 + gpiod_set_value(lcd->reset, 1); 326 327 usleep_range(10000, 12000); 327 - gpio_set_value(lcd->reset, 1); 328 + gpiod_set_value(lcd->reset, 0); 328 329 329 330 /* The controller needs 120ms to recover from reset */ 330 331 msleep(120); ··· 339 340 * Set the interface selection pins to SPI mode, with three 340 341 * wires 341 342 */ 342 - if (lcd->use_im_pins) { 343 - gpio_set_value_cansleep(lcd->im_pins[0], 1); 344 - gpio_set_value_cansleep(lcd->im_pins[1], 0); 345 - gpio_set_value_cansleep(lcd->im_pins[2], 1); 343 + if (lcd->im_pins) { 344 + gpiod_set_value_cansleep(lcd->im_pins->desc[0], 1); 345 + gpiod_set_value_cansleep(lcd->im_pins->desc[1], 0); 346 + gpiod_set_value_cansleep(lcd->im_pins->desc[2], 1); 346 347 } 347 348 348 349 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power, ··· 579 580 580 581 static int hx8357_probe(struct spi_device *spi) 581 582 { 583 + struct device *dev = &spi->dev; 582 584 struct lcd_device *lcdev; 583 585 struct hx8357_data *lcd; 584 586 const struct of_device_id *match; ··· 601 601 if (!match || !match->data) 602 602 return -EINVAL; 603 603 604 - lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0); 605 - if (!gpio_is_valid(lcd->reset)) { 606 - dev_err(&spi->dev, "Missing dt property: gpios-reset\n"); 607 - return -EINVAL; 608 - } 604 + lcd->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 605 + if (IS_ERR(lcd->reset)) 606 + return dev_err_probe(dev, PTR_ERR(lcd->reset), "failed to request reset GPIO\n"); 607 + gpiod_set_consumer_name(lcd->reset, "hx8357-reset"); 609 608 610 - ret = devm_gpio_request_one(&spi->dev, lcd->reset, 611 - GPIOF_OUT_INIT_HIGH, 612 - "hx8357-reset"); 613 - if (ret) { 614 - dev_err(&spi->dev, 615 - "failed to request gpio %d: %d\n", 616 - lcd->reset, ret); 617 - return -EINVAL; 618 - } 609 + lcd->im_pins = devm_gpiod_get_array_optional(dev, "im", GPIOD_OUT_LOW); 610 + if (IS_ERR(lcd->im_pins)) 611 + return dev_err_probe(dev, PTR_ERR(lcd->im_pins), "failed to request im GPIOs\n"); 612 + if (lcd->im_pins->ndescs < HX8357_NUM_IM_PINS) 613 + return dev_err_probe(dev, -EINVAL, "not enough im GPIOs\n"); 619 614 620 - if (of_property_present(spi->dev.of_node, "im-gpios")) { 621 - lcd->use_im_pins = 1; 622 - 623 - for (i = 0; i < HX8357_NUM_IM_PINS; i++) { 624 - lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, 625 - "im-gpios", i); 626 - if (lcd->im_pins[i] == -EPROBE_DEFER) { 627 - dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n"); 628 - return -EPROBE_DEFER; 629 - } 630 - if (!gpio_is_valid(lcd->im_pins[i])) { 631 - dev_err(&spi->dev, "Missing dt property: im-gpios\n"); 632 - return -EINVAL; 633 - } 634 - 635 - ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i], 636 - GPIOF_OUT_INIT_LOW, 637 - "im_pins"); 638 - if (ret) { 639 - dev_err(&spi->dev, "failed to request gpio %d: %d\n", 640 - lcd->im_pins[i], ret); 641 - return -EINVAL; 642 - } 643 - } 644 - } else { 645 - lcd->use_im_pins = 0; 646 - } 615 + for (i = 0; i < HX8357_NUM_IM_PINS; i++) 616 + gpiod_set_consumer_name(lcd->im_pins->desc[i], "im_pins"); 647 617 648 618 lcdev = devm_lcd_device_register(&spi->dev, "mxsfb", &spi->dev, lcd, 649 619 &hx8357_ops);
+6 -2
drivers/video/backlight/ili922x.c
··· 81 81 #define START_RW_WRITE 0 82 82 #define START_RW_READ 1 83 83 84 - /** 84 + /* 85 85 * START_BYTE(id, rs, rw) 86 86 * 87 87 * Set the start byte according to the required operation. ··· 100 100 #define START_BYTE(id, rs, rw) \ 101 101 (0x70 | (((id) & 0x01) << 2) | (((rs) & 0x01) << 1) | ((rw) & 0x01)) 102 102 103 - /** 103 + /* 104 104 * CHECK_FREQ_REG(spi_device s, spi_transfer x) - Check the frequency 105 105 * for the SPI transfer. According to the datasheet, the controller 106 106 * accept higher frequency for the GRAM transfer, but it requires ··· 269 269 spi_message_add_tail(&xfer_regindex, &msg); 270 270 271 271 ret = spi_sync(spi, &msg); 272 + if (ret < 0) { 273 + dev_err(&spi->dev, "Error sending SPI message 0x%x", ret); 274 + return ret; 275 + } 272 276 273 277 spi_message_init(&msg); 274 278 tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_REG,
+444
drivers/video/backlight/mp3309c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for MPS MP3309C White LED driver with I2C interface 4 + * 5 + * This driver support both analog (by I2C commands) and PWM dimming control 6 + * modes. 7 + * 8 + * Copyright (C) 2023 ASEM Srl 9 + * Author: Flavio Suligoi <f.suligoi@asem.it> 10 + * 11 + * Based on pwm_bl.c 12 + */ 13 + 14 + #include <linux/backlight.h> 15 + #include <linux/delay.h> 16 + #include <linux/gpio/consumer.h> 17 + #include <linux/i2c.h> 18 + #include <linux/pwm.h> 19 + #include <linux/regmap.h> 20 + 21 + #define REG_I2C_0 0x00 22 + #define REG_I2C_1 0x01 23 + 24 + #define REG_I2C_0_EN 0x80 25 + #define REG_I2C_0_D0 0x40 26 + #define REG_I2C_0_D1 0x20 27 + #define REG_I2C_0_D2 0x10 28 + #define REG_I2C_0_D3 0x08 29 + #define REG_I2C_0_D4 0x04 30 + #define REG_I2C_0_RSRV1 0x02 31 + #define REG_I2C_0_RSRV2 0x01 32 + 33 + #define REG_I2C_1_RSRV1 0x80 34 + #define REG_I2C_1_DIMS 0x40 35 + #define REG_I2C_1_SYNC 0x20 36 + #define REG_I2C_1_OVP0 0x10 37 + #define REG_I2C_1_OVP1 0x08 38 + #define REG_I2C_1_VOS 0x04 39 + #define REG_I2C_1_LEDO 0x02 40 + #define REG_I2C_1_OTP 0x01 41 + 42 + #define ANALOG_I2C_NUM_LEVELS 32 /* 0..31 */ 43 + #define ANALOG_I2C_REG_MASK 0x7c 44 + 45 + #define MP3309C_PWM_DEFAULT_NUM_LEVELS 256 /* 0..255 */ 46 + 47 + enum mp3309c_status_value { 48 + FIRST_POWER_ON, 49 + BACKLIGHT_OFF, 50 + BACKLIGHT_ON, 51 + }; 52 + 53 + enum mp3309c_dimming_mode_value { 54 + DIMMING_PWM, 55 + DIMMING_ANALOG_I2C, 56 + }; 57 + 58 + struct mp3309c_platform_data { 59 + unsigned int max_brightness; 60 + unsigned int default_brightness; 61 + unsigned int *levels; 62 + u8 dimming_mode; 63 + u8 over_voltage_protection; 64 + bool sync_mode; 65 + u8 status; 66 + }; 67 + 68 + struct mp3309c_chip { 69 + struct device *dev; 70 + struct mp3309c_platform_data *pdata; 71 + struct backlight_device *bl; 72 + struct gpio_desc *enable_gpio; 73 + struct regmap *regmap; 74 + struct pwm_device *pwmd; 75 + }; 76 + 77 + static const struct regmap_config mp3309c_regmap = { 78 + .name = "mp3309c_regmap", 79 + .reg_bits = 8, 80 + .reg_stride = 1, 81 + .val_bits = 8, 82 + .max_register = REG_I2C_1, 83 + }; 84 + 85 + static int mp3309c_enable_device(struct mp3309c_chip *chip) 86 + { 87 + u8 reg_val; 88 + int ret; 89 + 90 + /* I2C register #0 - Device enable */ 91 + ret = regmap_update_bits(chip->regmap, REG_I2C_0, REG_I2C_0_EN, 92 + REG_I2C_0_EN); 93 + if (ret) 94 + return ret; 95 + 96 + /* 97 + * I2C register #1 - Set working mode: 98 + * - set one of the two dimming mode: 99 + * - PWM dimming using an external PWM dimming signal 100 + * - analog dimming using I2C commands 101 + * - enable/disable synchronous mode 102 + * - set overvoltage protection (OVP) 103 + */ 104 + reg_val = 0x00; 105 + if (chip->pdata->dimming_mode == DIMMING_PWM) 106 + reg_val |= REG_I2C_1_DIMS; 107 + if (chip->pdata->sync_mode) 108 + reg_val |= REG_I2C_1_SYNC; 109 + reg_val |= chip->pdata->over_voltage_protection; 110 + ret = regmap_write(chip->regmap, REG_I2C_1, reg_val); 111 + if (ret) 112 + return ret; 113 + 114 + return 0; 115 + } 116 + 117 + static int mp3309c_bl_update_status(struct backlight_device *bl) 118 + { 119 + struct mp3309c_chip *chip = bl_get_data(bl); 120 + int brightness = backlight_get_brightness(bl); 121 + struct pwm_state pwmstate; 122 + unsigned int analog_val, bits_val; 123 + int i, ret; 124 + 125 + if (chip->pdata->dimming_mode == DIMMING_PWM) { 126 + /* 127 + * PWM control mode 128 + */ 129 + pwm_get_state(chip->pwmd, &pwmstate); 130 + pwm_set_relative_duty_cycle(&pwmstate, 131 + chip->pdata->levels[brightness], 132 + chip->pdata->levels[chip->pdata->max_brightness]); 133 + pwmstate.enabled = true; 134 + ret = pwm_apply_state(chip->pwmd, &pwmstate); 135 + if (ret) 136 + return ret; 137 + 138 + switch (chip->pdata->status) { 139 + case FIRST_POWER_ON: 140 + case BACKLIGHT_OFF: 141 + /* 142 + * After 20ms of low pwm signal level, the chip turns 143 + * off automatically. In this case, before enabling the 144 + * chip again, we must wait about 10ms for pwm signal to 145 + * stabilize. 146 + */ 147 + if (brightness > 0) { 148 + msleep(10); 149 + mp3309c_enable_device(chip); 150 + chip->pdata->status = BACKLIGHT_ON; 151 + } else { 152 + chip->pdata->status = BACKLIGHT_OFF; 153 + } 154 + break; 155 + case BACKLIGHT_ON: 156 + if (brightness == 0) 157 + chip->pdata->status = BACKLIGHT_OFF; 158 + break; 159 + } 160 + } else { 161 + /* 162 + * Analog (by I2C command) control mode 163 + * 164 + * The first time, before setting brightness, we must enable the 165 + * device 166 + */ 167 + if (chip->pdata->status == FIRST_POWER_ON) 168 + mp3309c_enable_device(chip); 169 + 170 + /* 171 + * Dimming mode I2C command (fixed dimming range 0..31) 172 + * 173 + * The 5 bits of the dimming analog value D4..D0 is allocated 174 + * in the I2C register #0, in the following way: 175 + * 176 + * +--+--+--+--+--+--+--+--+ 177 + * |EN|D0|D1|D2|D3|D4|XX|XX| 178 + * +--+--+--+--+--+--+--+--+ 179 + */ 180 + analog_val = brightness; 181 + bits_val = 0; 182 + for (i = 0; i <= 5; i++) 183 + bits_val += ((analog_val >> i) & 0x01) << (6 - i); 184 + ret = regmap_update_bits(chip->regmap, REG_I2C_0, 185 + ANALOG_I2C_REG_MASK, bits_val); 186 + if (ret) 187 + return ret; 188 + 189 + if (brightness > 0) 190 + chip->pdata->status = BACKLIGHT_ON; 191 + else 192 + chip->pdata->status = BACKLIGHT_OFF; 193 + } 194 + 195 + return 0; 196 + } 197 + 198 + static const struct backlight_ops mp3309c_bl_ops = { 199 + .update_status = mp3309c_bl_update_status, 200 + }; 201 + 202 + static int pm3309c_parse_dt_node(struct mp3309c_chip *chip, 203 + struct mp3309c_platform_data *pdata) 204 + { 205 + struct device_node *node = chip->dev->of_node; 206 + struct property *prop_pwms; 207 + struct property *prop_levels = NULL; 208 + int length = 0; 209 + int ret, i; 210 + unsigned int num_levels, tmp_value; 211 + 212 + if (!node) { 213 + dev_err(chip->dev, "failed to get DT node\n"); 214 + return -ENODEV; 215 + } 216 + 217 + /* 218 + * Dimming mode: the MP3309C provides two dimming control mode: 219 + * 220 + * - PWM mode 221 + * - Analog by I2C control mode (default) 222 + * 223 + * I2C control mode is assumed as default but, if the pwms property is 224 + * found in the backlight node, the mode switches to PWM mode. 225 + */ 226 + pdata->dimming_mode = DIMMING_ANALOG_I2C; 227 + prop_pwms = of_find_property(node, "pwms", &length); 228 + if (prop_pwms) { 229 + chip->pwmd = devm_pwm_get(chip->dev, NULL); 230 + if (IS_ERR(chip->pwmd)) 231 + return dev_err_probe(chip->dev, PTR_ERR(chip->pwmd), 232 + "error getting pwm data\n"); 233 + pdata->dimming_mode = DIMMING_PWM; 234 + pwm_apply_args(chip->pwmd); 235 + } 236 + 237 + /* 238 + * In I2C control mode the dimming levels (0..31) are fixed by the 239 + * hardware, while in PWM control mode they can be chosen by the user, 240 + * to allow nonlinear mappings. 241 + */ 242 + if (pdata->dimming_mode == DIMMING_ANALOG_I2C) { 243 + /* 244 + * Analog (by I2C commands) control mode: fixed 0..31 brightness 245 + * levels 246 + */ 247 + num_levels = ANALOG_I2C_NUM_LEVELS; 248 + 249 + /* Enable GPIO used in I2C dimming mode only */ 250 + chip->enable_gpio = devm_gpiod_get(chip->dev, "enable", 251 + GPIOD_OUT_HIGH); 252 + if (IS_ERR(chip->enable_gpio)) 253 + return dev_err_probe(chip->dev, 254 + PTR_ERR(chip->enable_gpio), 255 + "error getting enable gpio\n"); 256 + } else { 257 + /* 258 + * PWM control mode: check for brightness level in DT 259 + */ 260 + prop_levels = of_find_property(node, "brightness-levels", 261 + &length); 262 + if (prop_levels) { 263 + /* Read brightness levels from DT */ 264 + num_levels = length / sizeof(u32); 265 + if (num_levels < 2) 266 + return -EINVAL; 267 + } else { 268 + /* Use default brightness levels */ 269 + num_levels = MP3309C_PWM_DEFAULT_NUM_LEVELS; 270 + } 271 + } 272 + 273 + /* Fill brightness levels array */ 274 + pdata->levels = devm_kcalloc(chip->dev, num_levels, 275 + sizeof(*pdata->levels), GFP_KERNEL); 276 + if (!pdata->levels) 277 + return -ENOMEM; 278 + if (prop_levels) { 279 + ret = of_property_read_u32_array(node, "brightness-levels", 280 + pdata->levels, 281 + num_levels); 282 + if (ret < 0) 283 + return ret; 284 + } else { 285 + for (i = 0; i < num_levels; i++) 286 + pdata->levels[i] = i; 287 + } 288 + 289 + pdata->max_brightness = num_levels - 1; 290 + 291 + ret = of_property_read_u32(node, "default-brightness", 292 + &pdata->default_brightness); 293 + if (ret) 294 + pdata->default_brightness = pdata->max_brightness; 295 + if (pdata->default_brightness > pdata->max_brightness) { 296 + dev_err(chip->dev, 297 + "default brightness exceeds max brightness\n"); 298 + pdata->default_brightness = pdata->max_brightness; 299 + } 300 + 301 + /* 302 + * Over-voltage protection (OVP) 303 + * 304 + * This (optional) property values are: 305 + * 306 + * - 13.5V 307 + * - 24V 308 + * - 35.5V (hardware default setting) 309 + * 310 + * If missing, the default value for OVP is 35.5V 311 + */ 312 + pdata->over_voltage_protection = REG_I2C_1_OVP1; 313 + if (!of_property_read_u32(node, "mps,overvoltage-protection-microvolt", 314 + &tmp_value)) { 315 + switch (tmp_value) { 316 + case 13500000: 317 + pdata->over_voltage_protection = 0x00; 318 + break; 319 + case 24000000: 320 + pdata->over_voltage_protection = REG_I2C_1_OVP0; 321 + break; 322 + case 35500000: 323 + pdata->over_voltage_protection = REG_I2C_1_OVP1; 324 + break; 325 + default: 326 + return -EINVAL; 327 + } 328 + } 329 + 330 + /* Synchronous (default) and non-synchronous mode */ 331 + pdata->sync_mode = true; 332 + if (of_property_read_bool(node, "mps,no-sync-mode")) 333 + pdata->sync_mode = false; 334 + 335 + return 0; 336 + } 337 + 338 + static int mp3309c_probe(struct i2c_client *client) 339 + { 340 + struct mp3309c_platform_data *pdata = dev_get_platdata(&client->dev); 341 + struct mp3309c_chip *chip; 342 + struct backlight_properties props; 343 + struct pwm_state pwmstate; 344 + int ret; 345 + 346 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 347 + dev_err(&client->dev, "failed to check i2c functionality\n"); 348 + return -EOPNOTSUPP; 349 + } 350 + 351 + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 352 + if (!chip) 353 + return -ENOMEM; 354 + 355 + chip->dev = &client->dev; 356 + 357 + chip->regmap = devm_regmap_init_i2c(client, &mp3309c_regmap); 358 + if (IS_ERR(chip->regmap)) 359 + return dev_err_probe(&client->dev, PTR_ERR(chip->regmap), 360 + "failed to allocate register map\n"); 361 + 362 + i2c_set_clientdata(client, chip); 363 + 364 + if (!pdata) { 365 + pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL); 366 + if (!pdata) 367 + return -ENOMEM; 368 + 369 + ret = pm3309c_parse_dt_node(chip, pdata); 370 + if (ret) 371 + return ret; 372 + } 373 + chip->pdata = pdata; 374 + 375 + /* Backlight properties */ 376 + props.brightness = pdata->default_brightness; 377 + props.max_brightness = pdata->max_brightness; 378 + props.scale = BACKLIGHT_SCALE_LINEAR; 379 + props.type = BACKLIGHT_RAW; 380 + props.power = FB_BLANK_UNBLANK; 381 + props.fb_blank = FB_BLANK_UNBLANK; 382 + chip->bl = devm_backlight_device_register(chip->dev, "mp3309c", 383 + chip->dev, chip, 384 + &mp3309c_bl_ops, &props); 385 + if (IS_ERR(chip->bl)) 386 + return dev_err_probe(chip->dev, PTR_ERR(chip->bl), 387 + "error registering backlight device\n"); 388 + 389 + /* In PWM dimming mode, enable pwm device */ 390 + if (chip->pdata->dimming_mode == DIMMING_PWM) { 391 + pwm_init_state(chip->pwmd, &pwmstate); 392 + pwm_set_relative_duty_cycle(&pwmstate, 393 + chip->pdata->default_brightness, 394 + chip->pdata->max_brightness); 395 + pwmstate.enabled = true; 396 + ret = pwm_apply_state(chip->pwmd, &pwmstate); 397 + if (ret) 398 + return dev_err_probe(chip->dev, ret, 399 + "error setting pwm device\n"); 400 + } 401 + 402 + chip->pdata->status = FIRST_POWER_ON; 403 + backlight_update_status(chip->bl); 404 + 405 + return 0; 406 + } 407 + 408 + static void mp3309c_remove(struct i2c_client *client) 409 + { 410 + struct mp3309c_chip *chip = i2c_get_clientdata(client); 411 + struct backlight_device *bl = chip->bl; 412 + 413 + bl->props.power = FB_BLANK_POWERDOWN; 414 + bl->props.brightness = 0; 415 + backlight_update_status(chip->bl); 416 + } 417 + 418 + static const struct of_device_id mp3309c_match_table[] = { 419 + { .compatible = "mps,mp3309c", }, 420 + { }, 421 + }; 422 + MODULE_DEVICE_TABLE(of, mp3309c_match_table); 423 + 424 + static const struct i2c_device_id mp3309c_id[] = { 425 + { "mp3309c", 0 }, 426 + { } 427 + }; 428 + MODULE_DEVICE_TABLE(i2c, mp3309c_id); 429 + 430 + static struct i2c_driver mp3309c_i2c_driver = { 431 + .driver = { 432 + .name = KBUILD_MODNAME, 433 + .of_match_table = mp3309c_match_table, 434 + }, 435 + .probe = mp3309c_probe, 436 + .remove = mp3309c_remove, 437 + .id_table = mp3309c_id, 438 + }; 439 + 440 + module_i2c_driver(mp3309c_i2c_driver); 441 + 442 + MODULE_DESCRIPTION("Backlight Driver for MPS MP3309C"); 443 + MODULE_AUTHOR("Flavio Suligoi <f.suligoi@asem.it>"); 444 + MODULE_LICENSE("GPL");
+18 -16
drivers/video/backlight/pwm_bl.c
··· 461 461 462 462 if (!data) { 463 463 ret = pwm_backlight_parse_dt(&pdev->dev, &defdata); 464 - if (ret < 0) { 465 - dev_err(&pdev->dev, "failed to find platform data\n"); 466 - return ret; 467 - } 464 + if (ret < 0) 465 + return dev_err_probe(&pdev->dev, ret, 466 + "failed to find platform data\n"); 468 467 469 468 data = &defdata; 470 469 } ··· 492 493 pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", 493 494 GPIOD_ASIS); 494 495 if (IS_ERR(pb->enable_gpio)) { 495 - ret = PTR_ERR(pb->enable_gpio); 496 + ret = dev_err_probe(&pdev->dev, PTR_ERR(pb->enable_gpio), 497 + "failed to acquire enable GPIO\n"); 496 498 goto err_alloc; 497 499 } 498 500 499 501 pb->power_supply = devm_regulator_get_optional(&pdev->dev, "power"); 500 502 if (IS_ERR(pb->power_supply)) { 501 503 ret = PTR_ERR(pb->power_supply); 502 - if (ret == -ENODEV) 504 + if (ret == -ENODEV) { 503 505 pb->power_supply = NULL; 504 - else 506 + } else { 507 + dev_err_probe(&pdev->dev, ret, 508 + "failed to acquire power regulator\n"); 505 509 goto err_alloc; 510 + } 506 511 } 507 512 508 513 pb->pwm = devm_pwm_get(&pdev->dev, NULL); 509 514 if (IS_ERR(pb->pwm)) { 510 - ret = PTR_ERR(pb->pwm); 511 - if (ret != -EPROBE_DEFER) 512 - dev_err(&pdev->dev, "unable to request PWM\n"); 515 + ret = dev_err_probe(&pdev->dev, PTR_ERR(pb->pwm), 516 + "unable to request PWM\n"); 513 517 goto err_alloc; 514 518 } 515 519 ··· 532 530 533 531 ret = pwm_apply_might_sleep(pb->pwm, &state); 534 532 if (ret) { 535 - dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", 536 - ret); 533 + dev_err_probe(&pdev->dev, ret, 534 + "failed to apply initial PWM state"); 537 535 goto err_alloc; 538 536 } 539 537 ··· 570 568 ret = pwm_backlight_brightness_default(&pdev->dev, data, 571 569 state.period); 572 570 if (ret < 0) { 573 - dev_err(&pdev->dev, 574 - "failed to setup default brightness table\n"); 571 + dev_err_probe(&pdev->dev, ret, 572 + "failed to setup default brightness table\n"); 575 573 goto err_alloc; 576 574 } 577 575 ··· 599 597 bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, 600 598 &pwm_backlight_ops, &props); 601 599 if (IS_ERR(bl)) { 602 - dev_err(&pdev->dev, "failed to register backlight\n"); 603 - ret = PTR_ERR(bl); 600 + ret = dev_err_probe(&pdev->dev, PTR_ERR(bl), 601 + "failed to register backlight\n"); 604 602 goto err_alloc; 605 603 } 606 604