Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  Driver for Samsung Q10 and related laptops: controls the backlight
0004  *
0005  *  Copyright (c) 2011 Frederick van der Wyck <fvanderwyck@gmail.com>
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/backlight.h>
0013 #include <linux/dmi.h>
0014 #include <linux/acpi.h>
0015 
0016 #define SAMSUNGQ10_BL_MAX_INTENSITY 7
0017 
0018 static acpi_handle ec_handle;
0019 
0020 static bool force;
0021 module_param(force, bool, 0);
0022 MODULE_PARM_DESC(force,
0023         "Disable the DMI check and force the driver to be loaded");
0024 
0025 static int samsungq10_bl_set_intensity(struct backlight_device *bd)
0026 {
0027 
0028     acpi_status status;
0029     int i;
0030 
0031     for (i = 0; i < SAMSUNGQ10_BL_MAX_INTENSITY; i++) {
0032         status = acpi_evaluate_object(ec_handle, "_Q63", NULL, NULL);
0033         if (ACPI_FAILURE(status))
0034             return -EIO;
0035     }
0036     for (i = 0; i < bd->props.brightness; i++) {
0037         status = acpi_evaluate_object(ec_handle, "_Q64", NULL, NULL);
0038         if (ACPI_FAILURE(status))
0039             return -EIO;
0040     }
0041 
0042     return 0;
0043 }
0044 
0045 static const struct backlight_ops samsungq10_bl_ops = {
0046     .update_status  = samsungq10_bl_set_intensity,
0047 };
0048 
0049 static int samsungq10_probe(struct platform_device *pdev)
0050 {
0051 
0052     struct backlight_properties props;
0053     struct backlight_device *bd;
0054 
0055     memset(&props, 0, sizeof(struct backlight_properties));
0056     props.type = BACKLIGHT_PLATFORM;
0057     props.max_brightness = SAMSUNGQ10_BL_MAX_INTENSITY;
0058     bd = backlight_device_register("samsung", &pdev->dev, NULL,
0059                        &samsungq10_bl_ops, &props);
0060     if (IS_ERR(bd))
0061         return PTR_ERR(bd);
0062 
0063     platform_set_drvdata(pdev, bd);
0064 
0065     return 0;
0066 }
0067 
0068 static int samsungq10_remove(struct platform_device *pdev)
0069 {
0070 
0071     struct backlight_device *bd = platform_get_drvdata(pdev);
0072 
0073     backlight_device_unregister(bd);
0074 
0075     return 0;
0076 }
0077 
0078 static struct platform_driver samsungq10_driver = {
0079     .driver     = {
0080         .name   = KBUILD_MODNAME,
0081     },
0082     .probe      = samsungq10_probe,
0083     .remove     = samsungq10_remove,
0084 };
0085 
0086 static struct platform_device *samsungq10_device;
0087 
0088 static int __init dmi_check_callback(const struct dmi_system_id *id)
0089 {
0090     printk(KERN_INFO KBUILD_MODNAME ": found model '%s'\n", id->ident);
0091     return 1;
0092 }
0093 
0094 static const struct dmi_system_id samsungq10_dmi_table[] __initconst = {
0095     {
0096         .ident = "Samsung Q10",
0097         .matches = {
0098             DMI_MATCH(DMI_SYS_VENDOR, "Samsung"),
0099             DMI_MATCH(DMI_PRODUCT_NAME, "SQ10"),
0100         },
0101         .callback = dmi_check_callback,
0102     },
0103     {
0104         .ident = "Samsung Q20",
0105         .matches = {
0106             DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"),
0107             DMI_MATCH(DMI_PRODUCT_NAME, "SENS Q20"),
0108         },
0109         .callback = dmi_check_callback,
0110     },
0111     {
0112         .ident = "Samsung Q25",
0113         .matches = {
0114             DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"),
0115             DMI_MATCH(DMI_PRODUCT_NAME, "NQ25"),
0116         },
0117         .callback = dmi_check_callback,
0118     },
0119     {
0120         .ident = "Dell Latitude X200",
0121         .matches = {
0122             DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
0123             DMI_MATCH(DMI_PRODUCT_NAME, "X200"),
0124         },
0125         .callback = dmi_check_callback,
0126     },
0127     { },
0128 };
0129 MODULE_DEVICE_TABLE(dmi, samsungq10_dmi_table);
0130 
0131 static int __init samsungq10_init(void)
0132 {
0133     if (!force && !dmi_check_system(samsungq10_dmi_table))
0134         return -ENODEV;
0135 
0136     ec_handle = ec_get_handle();
0137 
0138     if (!ec_handle)
0139         return -ENODEV;
0140 
0141     samsungq10_device = platform_create_bundle(&samsungq10_driver,
0142                            samsungq10_probe,
0143                            NULL, 0, NULL, 0);
0144 
0145     return PTR_ERR_OR_ZERO(samsungq10_device);
0146 }
0147 
0148 static void __exit samsungq10_exit(void)
0149 {
0150     platform_device_unregister(samsungq10_device);
0151     platform_driver_unregister(&samsungq10_driver);
0152 }
0153 
0154 module_init(samsungq10_init);
0155 module_exit(samsungq10_exit);
0156 
0157 MODULE_AUTHOR("Frederick van der Wyck <fvanderwyck@gmail.com>");
0158 MODULE_DESCRIPTION("Samsung Q10 Driver");
0159 MODULE_LICENSE("GPL");