2 * Copyright (c) 2016 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <backlight.h>
13 #include <power/regulator.h>
15 DECLARE_GLOBAL_DATA_PTR
;
17 struct pwm_backlight_priv
{
19 struct gpio_desc enable
;
28 static int pwm_backlight_enable(struct udevice
*dev
)
30 struct pwm_backlight_priv
*priv
= dev_get_priv(dev
);
34 debug("%s: Enable '%s', regulator '%s'\n", __func__
, dev
->name
,
36 ret
= regulator_set_enable(priv
->reg
, true);
38 debug("%s: Cannot enable regulator for PWM '%s'\n", __func__
,
44 duty_cycle
= priv
->period_ns
* (priv
->default_level
- priv
->min_level
) /
45 (priv
->max_level
- priv
->min_level
+ 1);
46 ret
= pwm_set_config(priv
->pwm
, priv
->channel
, priv
->period_ns
,
50 ret
= pwm_set_enable(priv
->pwm
, priv
->channel
, true);
54 dm_gpio_set_value(&priv
->enable
, 1);
59 static int pwm_backlight_ofdata_to_platdata(struct udevice
*dev
)
61 struct pwm_backlight_priv
*priv
= dev_get_priv(dev
);
62 struct fdtdec_phandle_args args
;
63 const void *blob
= gd
->fdt_blob
;
64 int node
= dev_of_offset(dev
);
65 int index
, ret
, count
, len
;
68 ret
= uclass_get_device_by_phandle(UCLASS_REGULATOR
, dev
,
69 "power-supply", &priv
->reg
);
71 debug("%s: Cannot get power supply: ret=%d\n", __func__
, ret
);
74 ret
= gpio_request_by_name(dev
, "enable-gpios", 0, &priv
->enable
,
77 debug("%s: Warning: cannot get enable GPIO: ret=%d\n",
82 ret
= fdtdec_parse_phandle_with_args(blob
, node
, "pwms", "#pwm-cells",
85 debug("%s: Cannot get PWM phandle: ret=%d\n", __func__
, ret
);
89 ret
= uclass_get_device_by_of_offset(UCLASS_PWM
, args
.node
, &priv
->pwm
);
91 debug("%s: Cannot get PWM: ret=%d\n", __func__
, ret
);
94 priv
->channel
= args
.args
[0];
95 priv
->period_ns
= args
.args
[1];
97 index
= fdtdec_get_int(blob
, node
, "default-brightness-level", 255);
98 cell
= fdt_getprop(blob
, node
, "brightness-levels", &len
);
99 count
= len
/ sizeof(u32
);
100 if (cell
&& count
> index
) {
101 priv
->default_level
= fdt32_to_cpu(cell
[index
]);
102 priv
->max_level
= fdt32_to_cpu(cell
[count
- 1]);
104 priv
->default_level
= index
;
105 priv
->max_level
= 255;
112 static int pwm_backlight_probe(struct udevice
*dev
)
117 static const struct backlight_ops pwm_backlight_ops
= {
118 .enable
= pwm_backlight_enable
,
121 static const struct udevice_id pwm_backlight_ids
[] = {
122 { .compatible
= "pwm-backlight" },
126 U_BOOT_DRIVER(pwm_backlight
) = {
127 .name
= "pwm_backlight",
128 .id
= UCLASS_PANEL_BACKLIGHT
,
129 .of_match
= pwm_backlight_ids
,
130 .ops
= &pwm_backlight_ops
,
131 .ofdata_to_platdata
= pwm_backlight_ofdata_to_platdata
,
132 .probe
= pwm_backlight_probe
,
133 .priv_auto_alloc_size
= sizeof(struct pwm_backlight_priv
),