|
7 | 7 | * Based on drivers/gpu/drm/panel/panel-himax-hx8394.c |
8 | 8 | */ |
9 | 9 |
|
| 10 | +#include <linux/backlight.h> |
10 | 11 | #include <linux/delay.h> |
11 | 12 | #include <linux/gpio/consumer.h> |
12 | 13 | #include <linux/module.h> |
@@ -76,6 +77,8 @@ struct hx83102_panel_desc { |
76 | 77 | unsigned int height_mm; |
77 | 78 | } size; |
78 | 79 |
|
| 80 | + bool has_backlight; |
| 81 | + |
79 | 82 | int (*init)(struct hx83102 *ctx); |
80 | 83 | }; |
81 | 84 |
|
@@ -913,6 +916,7 @@ static const struct hx83102_panel_desc holitech_htf065h045_desc = { |
913 | 916 | .width_mm = 68, |
914 | 917 | .height_mm = 151, |
915 | 918 | }, |
| 919 | + .has_backlight = true, |
916 | 920 | .init = holitech_htf065h045_init, |
917 | 921 | }; |
918 | 922 |
|
@@ -1049,6 +1053,59 @@ static const struct drm_panel_funcs hx83102_drm_funcs = { |
1049 | 1053 | .get_orientation = hx83102_get_orientation, |
1050 | 1054 | }; |
1051 | 1055 |
|
| 1056 | +static int hx83102_bl_update_status(struct backlight_device *bl) |
| 1057 | +{ |
| 1058 | + struct mipi_dsi_device *dsi = bl_get_data(bl); |
| 1059 | + u16 brightness = backlight_get_brightness(bl); |
| 1060 | + int ret; |
| 1061 | + |
| 1062 | + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; |
| 1063 | + |
| 1064 | + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); |
| 1065 | + if (ret < 0) |
| 1066 | + return ret; |
| 1067 | + |
| 1068 | + dsi->mode_flags |= MIPI_DSI_MODE_LPM; |
| 1069 | + |
| 1070 | + return 0; |
| 1071 | +} |
| 1072 | + |
| 1073 | +static int hx83102_bl_get_brightness(struct backlight_device *bl) |
| 1074 | +{ |
| 1075 | + struct mipi_dsi_device *dsi = bl_get_data(bl); |
| 1076 | + u16 brightness; |
| 1077 | + int ret; |
| 1078 | + |
| 1079 | + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; |
| 1080 | + |
| 1081 | + ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness); |
| 1082 | + if (ret < 0) |
| 1083 | + return ret; |
| 1084 | + |
| 1085 | + dsi->mode_flags |= MIPI_DSI_MODE_LPM; |
| 1086 | + |
| 1087 | + return brightness; |
| 1088 | +} |
| 1089 | + |
| 1090 | +static const struct backlight_ops hx83102_bl_ops = { |
| 1091 | + .update_status = hx83102_bl_update_status, |
| 1092 | + .get_brightness = hx83102_bl_get_brightness, |
| 1093 | +}; |
| 1094 | + |
| 1095 | +static struct backlight_device * |
| 1096 | +hx83102_create_dcs_backlight(struct mipi_dsi_device *dsi) |
| 1097 | +{ |
| 1098 | + struct device *dev = &dsi->dev; |
| 1099 | + const struct backlight_properties props = { |
| 1100 | + .type = BACKLIGHT_RAW, |
| 1101 | + .brightness = 4095, |
| 1102 | + .max_brightness = 4095, |
| 1103 | + }; |
| 1104 | + |
| 1105 | + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, |
| 1106 | + &hx83102_bl_ops, &props); |
| 1107 | +} |
| 1108 | + |
1052 | 1109 | static int hx83102_panel_add(struct hx83102 *ctx) |
1053 | 1110 | { |
1054 | 1111 | struct device *dev = &ctx->dsi->dev; |
@@ -1080,6 +1137,14 @@ static int hx83102_panel_add(struct hx83102 *ctx) |
1080 | 1137 | if (err) |
1081 | 1138 | return err; |
1082 | 1139 |
|
| 1140 | + /* Use DSI-based backlight as fallback if available */ |
| 1141 | + if (ctx->desc->has_backlight && !ctx->base.backlight) { |
| 1142 | + ctx->base.backlight = hx83102_create_dcs_backlight(ctx->dsi); |
| 1143 | + if (IS_ERR(ctx->base.backlight)) |
| 1144 | + return dev_err_probe(dev, PTR_ERR(ctx->base.backlight), |
| 1145 | + "Failed to create backlight\n"); |
| 1146 | + } |
| 1147 | + |
1083 | 1148 | ctx->base.funcs = &hx83102_drm_funcs; |
1084 | 1149 | ctx->base.dev = &ctx->dsi->dev; |
1085 | 1150 |
|
|
0 commit comments