blob: dbb2752c0d254917040a22253cd870155683646a [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 MediaTek Inc.
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#if IS_ENABLED(CONFIG_LEDS_MTK_DISP)
9#include "mtk_leds_drv.h"
10#include "leds-mtk-disp.h"
11#elif IS_ENABLED(CONFIG_LEDS_MTK_PWM)
12#include <mtk_leds_drv.h>
13#include <leds-mtk-pwm.h>
14#endif
15
16
17#define MET_USER_EVENT_SUPPORT
18#include "met_drv.h"
19#include "trace.h"
20
21static int met_backlight_enable;
22static DEFINE_SPINLOCK(met_backlight_lock);
23static struct kobject *kobj_met_backlight;
24
25static ssize_t bl_tag_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
26static ssize_t bl_tag_enable_store(struct kobject *kobj,
27 struct kobj_attribute *attr, const char *buf, size_t n);
28static struct kobj_attribute bl_tag_enable_attr =
29__ATTR(backlight_tag_enable, 0664, bl_tag_enable_show, bl_tag_enable_store);
30
31#if IS_ENABLED(CONFIG_LEDS_MTK_DISP) || IS_ENABLED(CONFIG_LEDS_MTK_PWM)
32static int led_brightness_changed_event(struct notifier_block *nb,
33 unsigned long event, void *v)
34{
35 struct led_conf_info *led_conf;
36
37 led_conf = (struct led_conf_info *)v;
38
39 switch (event) {
40 case 1:
41 output_met_backlight_tag_real(led_conf->cdev.brightness);
42 break;
43 default:
44 break;
45 }
46
47 return NOTIFY_DONE;
48}
49
50static struct notifier_block leds_change_notifier = {
51 .notifier_call = led_brightness_changed_event,
52};
53#endif
54
55int enable_met_backlight_tag_real(void)
56{
57 return met_backlight_enable;
58}
59
60int output_met_backlight_tag_real(int level)
61{
62 int ret;
63 unsigned long flags;
64
65 spin_lock_irqsave(&met_backlight_lock, flags);
66#ifdef CONFIG_MET_MODULE
67 ret = met_tag_oneshot_real(33880, "_MM_BL_", level);
68#else
69 ret = met_tag_oneshot(33880, "_MM_BL_", level);
70#endif
71 spin_unlock_irqrestore(&met_backlight_lock, flags);
72
73 return ret;
74}
75
76static ssize_t bl_tag_enable_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
77{
78 int ret;
79
80 ret = snprintf(buf, PAGE_SIZE, "%d\n", met_backlight_enable);
81
82 return ret;
83}
84
85static ssize_t bl_tag_enable_store(struct kobject *kobj,
86 struct kobj_attribute *attr, const char *buf, size_t n)
87{
88 int value;
89
90 if ((n == 0) || (buf == NULL))
91 return -EINVAL;
92
93 if (kstrtoint(buf, 0, &value) != 0)
94 return -EINVAL;
95
96 if (value < 0)
97 return -EINVAL;
98
99#if IS_ENABLED(CONFIG_LEDS_MTK_DISP) || IS_ENABLED(CONFIG_LEDS_MTK_PWM)
100 if (value == 1) {
101 mtk_leds_register_notifier(&leds_change_notifier);
102 } else if (value == 0) {
103 mtk_leds_unregister_notifier(&leds_change_notifier);
104 }
105#endif
106 met_backlight_enable = value;
107
108 return n;
109}
110
111static int met_backlight_create(struct kobject *parent)
112{
113 int ret = 0;
114
115 kobj_met_backlight = parent;
116
117 ret = sysfs_create_file(kobj_met_backlight, &bl_tag_enable_attr.attr);
118 if (ret != 0) {
119 pr_debug("Failed to create montype0 in sysfs\n");
120 return ret;
121 }
122
123 return ret;
124}
125
126static void met_backlight_delete(void)
127{
128 sysfs_remove_file(kobj_met_backlight, &bl_tag_enable_attr.attr);
129 kobj_met_backlight = NULL;
130}
131
132struct metdevice met_backlight = {
133 .name = "backlight",
134 .owner = THIS_MODULE,
135 .type = MET_TYPE_BUS,
136 .create_subfs = met_backlight_create,
137 .delete_subfs = met_backlight_delete,
138 .cpu_related = 0,
139};
140EXPORT_SYMBOL(met_backlight);