1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * |
4 | * Backlight driver for HP Jornada 700 series (710/720/728) |
5 | * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com> |
6 | */ |
7 | |
8 | #include <linux/backlight.h> |
9 | #include <linux/device.h> |
10 | #include <linux/fb.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> |
14 | |
15 | #include <mach/jornada720.h> |
16 | #include <mach/hardware.h> |
17 | |
18 | #include <video/s1d13xxxfb.h> |
19 | |
20 | #define BL_MAX_BRIGHT 255 |
21 | #define BL_DEF_BRIGHT 25 |
22 | |
23 | static int jornada_bl_get_brightness(struct backlight_device *bd) |
24 | { |
25 | int ret; |
26 | |
27 | /* check if backlight is on */ |
28 | if (!(PPSR & PPC_LDD1)) |
29 | return 0; |
30 | |
31 | jornada_ssp_start(); |
32 | |
33 | /* cmd should return txdummy */ |
34 | ret = jornada_ssp_byte(GETBRIGHTNESS); |
35 | |
36 | if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) { |
37 | dev_err(&bd->dev, "get brightness timeout\n" ); |
38 | jornada_ssp_end(); |
39 | return -ETIMEDOUT; |
40 | } |
41 | |
42 | /* exchange txdummy for value */ |
43 | ret = jornada_ssp_byte(TXDUMMY); |
44 | |
45 | jornada_ssp_end(); |
46 | |
47 | return BL_MAX_BRIGHT - ret; |
48 | } |
49 | |
50 | static int jornada_bl_update_status(struct backlight_device *bd) |
51 | { |
52 | int ret = 0; |
53 | |
54 | jornada_ssp_start(); |
55 | |
56 | /* If backlight is off then really turn it off */ |
57 | if (backlight_is_blank(bd)) { |
58 | ret = jornada_ssp_byte(BRIGHTNESSOFF); |
59 | if (ret != TXDUMMY) { |
60 | dev_info(&bd->dev, "brightness off timeout\n" ); |
61 | /* turn off backlight */ |
62 | PPSR &= ~PPC_LDD1; |
63 | PPDR |= PPC_LDD1; |
64 | ret = -ETIMEDOUT; |
65 | } |
66 | } else /* turn on backlight */ |
67 | PPSR |= PPC_LDD1; |
68 | |
69 | /* send command to our mcu */ |
70 | if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) { |
71 | dev_info(&bd->dev, "failed to set brightness\n" ); |
72 | ret = -ETIMEDOUT; |
73 | goto out; |
74 | } |
75 | |
76 | /* |
77 | * at this point we expect that the mcu has accepted |
78 | * our command and is waiting for our new value |
79 | * please note that maximum brightness is 255, |
80 | * but due to physical layout it is equal to 0, so we simply |
81 | * invert the value (MAX VALUE - NEW VALUE). |
82 | */ |
83 | if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) |
84 | != TXDUMMY) { |
85 | dev_err(&bd->dev, "set brightness failed\n" ); |
86 | ret = -ETIMEDOUT; |
87 | } |
88 | |
89 | /* |
90 | * If infact we get an TXDUMMY as output we are happy and dont |
91 | * make any further comments about it |
92 | */ |
93 | out: |
94 | jornada_ssp_end(); |
95 | |
96 | return ret; |
97 | } |
98 | |
99 | static const struct backlight_ops jornada_bl_ops = { |
100 | .get_brightness = jornada_bl_get_brightness, |
101 | .update_status = jornada_bl_update_status, |
102 | .options = BL_CORE_SUSPENDRESUME, |
103 | }; |
104 | |
105 | static int jornada_bl_probe(struct platform_device *pdev) |
106 | { |
107 | struct backlight_properties props; |
108 | int ret; |
109 | struct backlight_device *bd; |
110 | |
111 | memset(&props, 0, sizeof(struct backlight_properties)); |
112 | props.type = BACKLIGHT_RAW; |
113 | props.max_brightness = BL_MAX_BRIGHT; |
114 | |
115 | bd = devm_backlight_device_register(dev: &pdev->dev, S1D_DEVICENAME, |
116 | parent: &pdev->dev, NULL, ops: &jornada_bl_ops, |
117 | props: &props); |
118 | if (IS_ERR(ptr: bd)) { |
119 | ret = PTR_ERR(ptr: bd); |
120 | dev_err(&pdev->dev, "failed to register device, err=%x\n" , ret); |
121 | return ret; |
122 | } |
123 | |
124 | bd->props.power = FB_BLANK_UNBLANK; |
125 | bd->props.brightness = BL_DEF_BRIGHT; |
126 | /* |
127 | * note. make sure max brightness is set otherwise |
128 | * you will get seemingly non-related errors when |
129 | * trying to change brightness |
130 | */ |
131 | jornada_bl_update_status(bd); |
132 | |
133 | platform_set_drvdata(pdev, data: bd); |
134 | dev_info(&pdev->dev, "HP Jornada 700 series backlight driver\n" ); |
135 | |
136 | return 0; |
137 | } |
138 | |
139 | static struct platform_driver jornada_bl_driver = { |
140 | .probe = jornada_bl_probe, |
141 | .driver = { |
142 | .name = "jornada_bl" , |
143 | }, |
144 | }; |
145 | |
146 | module_platform_driver(jornada_bl_driver); |
147 | |
148 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>" ); |
149 | MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver" ); |
150 | MODULE_LICENSE("GPL" ); |
151 | |