1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/backlight.h>
#include <drm/drm_device.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_mode.h>
#include <drm/drm_modes.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <video/mipi_display.h>
struct summit_data {
struct mipi_dsi_device *dsi;
struct backlight_device *bl;
struct drm_panel panel;
};
static int summit_set_brightness(struct device *dev)
{
struct summit_data *s_data = dev_get_drvdata(dev);
int level = backlight_get_brightness(s_data->bl);
return mipi_dsi_dcs_set_display_brightness(s_data->dsi, level);
}
static int summit_bl_update_status(struct backlight_device *dev)
{
return summit_set_brightness(&dev->dev);
}
static const struct backlight_ops summit_bl_ops = {
.update_status = summit_bl_update_status,
};
static struct drm_display_mode summit_mode = {
.vdisplay = 2008,
.hdisplay = 60,
.hsync_start = 60 + 8,
.hsync_end = 60 + 8 + 80,
.htotal = 60 + 8 + 80 + 40,
.vsync_start = 2008 + 1,
.vsync_end = 2008 + 1 + 15,
.vtotal = 2008 + 1 + 15 + 6,
.clock = ((60 + 8 + 80 + 40) * (2008 + 1 + 15 + 6) * 60) / 1000,
.type = DRM_MODE_TYPE_DRIVER,
.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC,
};
static int summit_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
connector->display_info.non_desktop = true;
drm_object_property_set_value(&connector->base,
connector->dev->mode_config.non_desktop_property,
connector->display_info.non_desktop);
return drm_connector_helper_get_modes_fixed(connector, &summit_mode);
}
static const struct drm_panel_funcs summit_panel_funcs = {
.get_modes = summit_get_modes,
};
static int summit_probe(struct mipi_dsi_device *dsi)
{
struct backlight_properties props = { 0 };
struct device *dev = &dsi->dev;
struct summit_data *s_data;
int ret;
s_data = devm_kzalloc(dev, sizeof(*s_data), GFP_KERNEL);
if (!s_data)
return -ENOMEM;
mipi_dsi_set_drvdata(dsi, s_data);
s_data->dsi = dsi;
ret = device_property_read_u32(dev, "max-brightness", &props.max_brightness);
if (ret)
return ret;
props.type = BACKLIGHT_RAW;
s_data->bl = devm_backlight_device_register(dev, dev_name(dev),
dev, s_data, &summit_bl_ops, &props);
if (IS_ERR(s_data->bl))
return PTR_ERR(s_data->bl);
drm_panel_init(&s_data->panel, dev, &summit_panel_funcs,
DRM_MODE_CONNECTOR_DSI);
drm_panel_add(&s_data->panel);
return mipi_dsi_attach(dsi);
}
static void summit_remove(struct mipi_dsi_device *dsi)
{
struct summit_data *s_data = mipi_dsi_get_drvdata(dsi);
mipi_dsi_detach(dsi);
drm_panel_remove(&s_data->panel);
}
static int summit_suspend(struct device *dev)
{
struct summit_data *s_data = dev_get_drvdata(dev);
return mipi_dsi_dcs_set_display_brightness(s_data->dsi, 0);
}
static DEFINE_SIMPLE_DEV_PM_OPS(summit_pm_ops, summit_suspend,
summit_set_brightness);
static const struct of_device_id summit_of_match[] = {
{ .compatible = "apple,summit" },
{},
};
MODULE_DEVICE_TABLE(of, summit_of_match);
static struct mipi_dsi_driver summit_driver = {
.probe = summit_probe,
.remove = summit_remove,
.driver = {
.name = "panel-summit",
.of_match_table = summit_of_match,
.pm = pm_sleep_ptr(&summit_pm_ops),
},
};
module_mipi_dsi_driver(summit_driver);
MODULE_DESCRIPTION("Summit Display Panel Driver");
MODULE_LICENSE("GPL");
|