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
);
31 struct dm_regulator_uclass_platdata
*plat
;
35 plat
= dev_get_uclass_platdata(priv
->reg
);
36 debug("%s: Enable '%s', regulator '%s'/'%s'\n", __func__
, dev
->name
,
37 priv
->reg
->name
, plat
->name
);
38 ret
= regulator_set_enable(priv
->reg
, true);
40 debug("%s: Cannot enable regulator for PWM '%s'\n", __func__
,
46 duty_cycle
= priv
->period_ns
* (priv
->default_level
- priv
->min_level
) /
47 (priv
->max_level
- priv
->min_level
+ 1);
48 ret
= pwm_set_config(priv
->pwm
, priv
->channel
, priv
->period_ns
,
52 ret
= pwm_set_enable(priv
->pwm
, priv
->channel
, true);
56 dm_gpio_set_value(&priv
->enable
, 1);
61 static int pwm_backlight_ofdata_to_platdata(struct udevice
*dev
)
63 struct pwm_backlight_priv
*priv
= dev_get_priv(dev
);
64 struct ofnode_phandle_args args
;
65 int index
, ret
, count
, len
;
68 debug("%s: start\n", __func__
);
69 ret
= uclass_get_device_by_phandle(UCLASS_REGULATOR
, dev
,
70 "power-supply", &priv
->reg
);
72 debug("%s: Cannot get power supply: ret=%d\n", __func__
, ret
);
75 ret
= gpio_request_by_name(dev
, "enable-gpios", 0, &priv
->enable
,
78 debug("%s: Warning: cannot get enable GPIO: ret=%d\n",
83 ret
= dev_read_phandle_with_args(dev
, "pwms", "#pwm-cells", 0, 0,
86 debug("%s: Cannot get PWM phandle: ret=%d\n", __func__
, ret
);
90 ret
= uclass_get_device_by_ofnode(UCLASS_PWM
, args
.node
, &priv
->pwm
);
92 debug("%s: Cannot get PWM: ret=%d\n", __func__
, ret
);
95 priv
->channel
= args
.args
[0];
96 priv
->period_ns
= args
.args
[1];
98 index
= dev_read_u32_default(dev
, "default-brightness-level", 255);
99 cell
= dev_read_prop(dev
, "brightness-levels", &len
);
100 count
= len
/ sizeof(u32
);
101 if (cell
&& count
> index
) {
102 priv
->default_level
= fdt32_to_cpu(cell
[index
]);
103 priv
->max_level
= fdt32_to_cpu(cell
[count
- 1]);
105 priv
->default_level
= index
;
106 priv
->max_level
= 255;
108 debug("%s: done\n", __func__
);
114 static int pwm_backlight_probe(struct udevice
*dev
)
119 static const struct backlight_ops pwm_backlight_ops
= {
120 .enable
= pwm_backlight_enable
,
123 static const struct udevice_id pwm_backlight_ids
[] = {
124 { .compatible
= "pwm-backlight" },
128 U_BOOT_DRIVER(pwm_backlight
) = {
129 .name
= "pwm_backlight",
130 .id
= UCLASS_PANEL_BACKLIGHT
,
131 .of_match
= pwm_backlight_ids
,
132 .ops
= &pwm_backlight_ops
,
133 .ofdata_to_platdata
= pwm_backlight_ofdata_to_platdata
,
134 .probe
= pwm_backlight_probe
,
135 .priv_auto_alloc_size
= sizeof(struct pwm_backlight_priv
),