config/patches/kmods/ddcci-driver/global-control-device.patch

119 lines
4.9 KiB
Diff

diff --git a/ddcci-backlight/ddcci-backlight.c b/ddcci-backlight/ddcci-backlight.c
index 7a98522..e518bfc 100644
--- a/ddcci-backlight/ddcci-backlight.c
+++ b/ddcci-backlight/ddcci-backlight.c
@@ -29,6 +29,12 @@
#define DDCCI_MONITOR_BACKLIGHT 0x13
#define DDCCI_MONITOR_BL_WHITE 0x6B
+#define DDCCI_BL_MUX_MAX_DEVICES 8
+
+static struct backlight_device *ddcci_bl_global_control = NULL;
+static struct backlight_device *ddcci_bl_mux_devices[DDCCI_BL_MUX_MAX_DEVICES] = {NULL};
+static int ddcci_bl_mux_device_count = 0;
+
static bool convenience_symlink = true;
struct ddcci_monitor_drv_data {
@@ -101,13 +107,21 @@ static int ddcci_backlight_update_status(struct backlight_device *bl)
struct ddcci_monitor_drv_data *drv_data = bl_get_data(bl);
int brightness = bl->props.brightness;
int ret;
+ int i;
- if (bl->props.power != FB_BLANK_UNBLANK ||
- bl->props.state & BL_CORE_FBBLANK)
- brightness = 0;
+ if (drv_data == NULL) {
+ for (i = 0; i < ddcci_bl_mux_device_count; ++i) {
+ ddcci_bl_mux_devices[i]->props.brightness = bl->props.brightness;
+ ddcci_backlight_update_status(ddcci_bl_mux_devices[i]);
+ }
+ } else {
+ if (bl->props.power != FB_BLANK_UNBLANK ||
+ bl->props.state & BL_CORE_FBBLANK)
+ brightness = 0;
- ret = ddcci_monitor_writectrl(drv_data->device, drv_data->used_vcp,
- brightness);
+ ret = ddcci_monitor_writectrl(drv_data->device, drv_data->used_vcp,
+ brightness);
+ }
if (ret > 0)
ret = 0;
return ret;
@@ -119,6 +133,10 @@ static int ddcci_backlight_get_brightness(struct backlight_device *bl)
int ret;
struct ddcci_monitor_drv_data *drv_data = bl_get_data(bl);
+ if (drv_data == NULL) {
+ return bl->props.brightness;
+ }
+
ret = ddcci_monitor_readctrl(drv_data->device, drv_data->used_vcp,
&value, &maxval);
if (ret < 0)
@@ -277,6 +295,7 @@ static int ddcci_monitor_probe(struct ddcci_device *dev,
{
struct ddcci_monitor_drv_data *drv_data;
struct backlight_properties props;
+ struct backlight_properties cprops;
struct backlight_device *bl = NULL;
int ret = 0;
bool support_luminance, support_bl_white;
@@ -369,6 +388,27 @@ static int ddcci_monitor_probe(struct ddcci_device *dev,
ddcci_backlight_create_symlink(dev);
}
+ if (ddcci_bl_global_control == NULL) {
+ printk(KERN_INFO "ddcci-backlight: registering global controller with brightness=%d, max_brightness=%d\n",
+ brightness, max_brightness);
+ cprops.type = BACKLIGHT_FIRMWARE;
+ cprops.max_brightness = max_brightness;
+ cprops.brightness = brightness;
+ ddcci_bl_global_control = devm_backlight_device_register(&dev->dev, "0000-ddcci_backlight_global_control",
+ &dev->dev, NULL,
+ &ddcci_backlight_ops, &cprops);
+ };
+
+ if(ddcci_bl_mux_device_count < DDCCI_BL_MUX_MAX_DEVICES) {
+ dev_info(&dev->dev, "registering backlight device %s as mux slave #%d",
+ dev_name(&dev->dev), ddcci_bl_mux_device_count);
+ ddcci_bl_mux_devices[ddcci_bl_mux_device_count] = bl;
+ dev_info(&dev->dev, "registered mux slave #%d successfully", ddcci_bl_mux_device_count);
+ ++ddcci_bl_mux_device_count;
+ } else {
+ dev_info(&dev->dev, "new backlight device added, but mux slave array is at max capacity. global control will not work for this device.");
+ }
+
goto end;
err_free:
devm_kfree(&dev->dev, drv_data);
@@ -378,8 +418,27 @@ end:
static int ddcci_monitor_remove(struct ddcci_device *dev)
{
+ int i,j;
+
dev_dbg(&dev->dev, "removing device\n");
ddcci_backlight_remove_symlink(dev);
+
+ for (i = 0; i < ddcci_bl_mux_device_count; ++i) {
+ struct backlight_device *bl = ddcci_bl_mux_devices[i];
+ printk(KERN_INFO "ddcci-backlight: scan for remove global device %d from control array\n", i);
+ if (dev == (struct ddcci_device*) bl_get_data(bl)) {
+ printk(KERN_INFO "ddcci-backlight: removing global device %d from control array\n", i);
+ ddcci_bl_mux_devices[i] = NULL;
+ for (j = i+1; j < ddcci_bl_mux_device_count; ++j) {
+ if(ddcci_bl_mux_devices[j] != NULL) {
+ printk(KERN_INFO "ddcci-backlight: adjusting global devices %d -> %d\n", j, j-1);
+ ddcci_bl_mux_devices[j-1] = ddcci_bl_mux_devices[j];
+ }
+ }
+ --ddcci_bl_mux_device_count;
+ }
+ }
+
return 0;
}