summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/compat/linuxkpi/common/include/linux/backlight.h94
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device.h4
-rw-r--r--sys/compat/linuxkpi/common/src/linux_kmod.c1
-rw-r--r--sys/compat/linuxkpi/common/src/linux_pci.c83
-rw-r--r--sys/conf/kmod.mk1
5 files changed, 183 insertions, 0 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/backlight.h b/sys/compat/linuxkpi/common/include/linux/backlight.h
new file mode 100644
index 000000000000..1d2224811124
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/backlight.h
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2020 The FreeBSD Foundation
+ *
+ * This software was developed by Emmanuel Vadot under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LINUX_BACKLIGHT_H_
+#define _LINUX_BACKLIGHT_H_
+
+#include <linux/notifier.h>
+
+struct backlight_device;
+
+enum backlight_type {
+ BACKLIGHT_RAW = 0,
+};
+
+struct backlight_properties {
+ int type;
+ int max_brightness;
+ int brightness;
+ int power;
+};
+
+enum backlight_notification {
+ BACKLIGHT_REGISTERED,
+ BACKLIGHT_UNREGISTERED,
+};
+
+enum backlight_update_reason {
+ BACKLIGHT_UPDATE_HOTKEY = 0
+};
+
+struct backlight_ops {
+ int options;
+#define BL_CORE_SUSPENDRESUME 1
+ int (*update_status)(struct backlight_device *);
+ int (*get_brightness)(struct backlight_device *);
+};
+
+struct backlight_device {
+ const struct backlight_ops *ops;
+ struct backlight_properties props;
+ void *data;
+ struct device *dev;
+ char *name;
+};
+
+#define bl_get_data(bd) (bd)->data
+
+struct backlight_device *linux_backlight_device_register(const char *name,
+ struct device *dev, void *data, const struct backlight_ops *ops, struct backlight_properties *props);
+void linux_backlight_device_unregister(struct backlight_device *bd);
+#define backlight_device_register(name, dev, data, ops, props) \
+ linux_backlight_device_register(name, dev, data, ops, props)
+#define backlight_device_unregister(bd) linux_backlight_device_unregister(bd)
+
+static inline void
+backlight_update_status(struct backlight_device *bd)
+{
+ bd->ops->update_status(bd);
+}
+
+static inline void
+backlight_force_update(struct backlight_device *bd, int reason)
+{
+ bd->props.brightness = bd->ops->get_brightness(bd);
+}
+
+#endif /* _LINUX_BACKLIGHT_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h
index 5361236baea8..a55f6b0215ce 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -41,9 +41,11 @@
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/kdev_t.h>
+#include <linux/backlight.h>
#include <asm/atomic.h>
#include <sys/bus.h>
+#include <sys/backlight.h>
struct device;
struct fwnode_handle;
@@ -114,6 +116,8 @@ struct device {
unsigned int irq_end;
const struct attribute_group **groups;
struct fwnode_handle *fwnode;
+ struct cdev *backlight_dev;
+ struct backlight_device *bd;
spinlock_t devres_lock;
struct list_head devres_head;
diff --git a/sys/compat/linuxkpi/common/src/linux_kmod.c b/sys/compat/linuxkpi/common/src/linux_kmod.c
index 4e395ae5e1b2..b9a916da650f 100644
--- a/sys/compat/linuxkpi/common/src/linux_kmod.c
+++ b/sys/compat/linuxkpi/common/src/linux_kmod.c
@@ -31,4 +31,5 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
MODULE_VERSION(linuxkpi, 1);
+MODULE_DEPEND(linuxkpi, backlight, 1, 1, 1);
MODULE_DEPEND(linuxkpi, pci, 1, 1, 1);
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index ed04d47c462a..b7962f3bdbaf 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/pci/pci_private.h>
#include <dev/pci/pci_iov.h>
+#include <dev/backlight/backlight.h>
#include <linux/kobject.h>
#include <linux/device.h>
@@ -64,6 +65,10 @@ __FBSDID("$FreeBSD$");
#include <linux/pci.h>
#include <linux/compat.h>
+#include <linux/backlight.h>
+
+#include "backlight_if.h"
+
static device_probe_t linux_pci_probe;
static device_attach_t linux_pci_attach;
static device_detach_t linux_pci_detach;
@@ -73,6 +78,9 @@ static device_shutdown_t linux_pci_shutdown;
static pci_iov_init_t linux_pci_iov_init;
static pci_iov_uninit_t linux_pci_iov_uninit;
static pci_iov_add_vf_t linux_pci_iov_add_vf;
+static int linux_backlight_get_status(device_t dev, struct backlight_props *props);
+static int linux_backlight_update_status(device_t dev, struct backlight_props *props);
+static int linux_backlight_get_info(device_t dev, struct backlight_info *info);
static device_method_t pci_methods[] = {
DEVMETHOD(device_probe, linux_pci_probe),
@@ -84,6 +92,11 @@ static device_method_t pci_methods[] = {
DEVMETHOD(pci_iov_init, linux_pci_iov_init),
DEVMETHOD(pci_iov_uninit, linux_pci_iov_uninit),
DEVMETHOD(pci_iov_add_vf, linux_pci_iov_add_vf),
+
+ /* backlight interface */
+ DEVMETHOD(backlight_update_status, linux_backlight_update_status),
+ DEVMETHOD(backlight_get_status, linux_backlight_get_status),
+ DEVMETHOD(backlight_get_info, linux_backlight_get_info),
DEVMETHOD_END
};
@@ -951,3 +964,73 @@ linux_dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma_addr)
uma_zfree_arg(pool->pool_zone, obj, pool);
}
+
+static int
+linux_backlight_get_status(device_t dev, struct backlight_props *props)
+{
+ struct pci_dev *pdev;
+
+ linux_set_current(curthread);
+ pdev = device_get_softc(dev);
+
+ props->brightness = pdev->dev.bd->props.brightness;
+ props->brightness = props->brightness * 100 / pdev->dev.bd->props.max_brightness;
+ props->nlevels = 0;
+
+ return (0);
+}
+
+static int
+linux_backlight_get_info(device_t dev, struct backlight_info *info)
+{
+ struct pci_dev *pdev;
+
+ linux_set_current(curthread);
+ pdev = device_get_softc(dev);
+
+ info->type = BACKLIGHT_TYPE_PANEL;
+ strlcpy(info->name, pdev->dev.bd->name, BACKLIGHTMAXNAMELENGTH);
+ return (0);
+}
+
+static int
+linux_backlight_update_status(device_t dev, struct backlight_props *props)
+{
+ struct pci_dev *pdev;
+
+ linux_set_current(curthread);
+ pdev = device_get_softc(dev);
+
+ pdev->dev.bd->props.brightness = pdev->dev.bd->props.max_brightness *
+ props->brightness / 100;
+ return (pdev->dev.bd->ops->update_status(pdev->dev.bd));
+}
+
+struct backlight_device *
+linux_backlight_device_register(const char *name, struct device *dev,
+ void *data, const struct backlight_ops *ops, struct backlight_properties *props)
+{
+
+ dev->bd = malloc(sizeof(*dev->bd), M_DEVBUF, M_WAITOK | M_ZERO);
+ dev->bd->ops = ops;
+ dev->bd->props.type = props->type;
+ dev->bd->props.max_brightness = props->max_brightness;
+ dev->bd->props.brightness = props->brightness;
+ dev->bd->props.power = props->power;
+ dev->bd->data = data;
+ dev->bd->dev = dev;
+ dev->bd->name = strdup(name, M_DEVBUF);
+
+ dev->backlight_dev = backlight_register(name, dev->bsddev);
+
+ return (dev->bd);
+}
+
+void
+linux_backlight_device_unregister(struct backlight_device *bd)
+{
+
+ backlight_destroy(bd->dev->backlight_dev);
+ free(bd->name, M_DEVBUF);
+ free(bd, M_DEVBUF);
+}
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index e60e49dc9eb5..7d89975c0479 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -91,6 +91,7 @@ CFLAGS+= -fno-strict-aliasing
WERROR?= -Werror
LINUXKPI_GENSRCS+= \
+ backlight_if.h \
bus_if.h \
device_if.h \
pci_if.h \