xref: /linux/drivers/video/backlight/max25014.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1*3014ad47SMaud Spierings // SPDX-License-Identifier: GPL-2.0-only
2*3014ad47SMaud Spierings /*
3*3014ad47SMaud Spierings  * Backlight driver for Maxim MAX25014
4*3014ad47SMaud Spierings  *
5*3014ad47SMaud Spierings  * Copyright (C) 2025 GOcontroll B.V.
6*3014ad47SMaud Spierings  * Author: Maud Spierings <maudspierings@gocontroll.com>
7*3014ad47SMaud Spierings  */
8*3014ad47SMaud Spierings 
9*3014ad47SMaud Spierings #include <linux/backlight.h>
10*3014ad47SMaud Spierings #include <linux/gpio/consumer.h>
11*3014ad47SMaud Spierings #include <linux/i2c.h>
12*3014ad47SMaud Spierings #include <linux/regmap.h>
13*3014ad47SMaud Spierings #include <linux/slab.h>
14*3014ad47SMaud Spierings 
15*3014ad47SMaud Spierings #define MAX25014_ISET_DEFAULT_100 11
16*3014ad47SMaud Spierings #define MAX_BRIGHTNESS            100
17*3014ad47SMaud Spierings #define MIN_BRIGHTNESS            0
18*3014ad47SMaud Spierings #define TON_MAX                   130720 /* @153Hz */
19*3014ad47SMaud Spierings #define TON_STEP                  1307 /* @153Hz */
20*3014ad47SMaud Spierings #define TON_MIN                   0
21*3014ad47SMaud Spierings 
22*3014ad47SMaud Spierings #define MAX25014_DEV_ID           0x00
23*3014ad47SMaud Spierings #define MAX25014_REV_ID           0x01
24*3014ad47SMaud Spierings #define MAX25014_ISET             0x02
25*3014ad47SMaud Spierings #define MAX25014_IMODE            0x03
26*3014ad47SMaud Spierings #define MAX25014_TON1H            0x04
27*3014ad47SMaud Spierings #define MAX25014_TON1L            0x05
28*3014ad47SMaud Spierings #define MAX25014_TON2H            0x06
29*3014ad47SMaud Spierings #define MAX25014_TON2L            0x07
30*3014ad47SMaud Spierings #define MAX25014_TON3H            0x08
31*3014ad47SMaud Spierings #define MAX25014_TON3L            0x09
32*3014ad47SMaud Spierings #define MAX25014_TON4H            0x0A
33*3014ad47SMaud Spierings #define MAX25014_TON4L            0x0B
34*3014ad47SMaud Spierings #define MAX25014_TON_1_4_LSB      0x0C
35*3014ad47SMaud Spierings #define MAX25014_SETTING          0x12
36*3014ad47SMaud Spierings #define MAX25014_DISABLE          0x13
37*3014ad47SMaud Spierings #define MAX25014_BSTMON           0x14
38*3014ad47SMaud Spierings #define MAX25014_IOUT1            0x15
39*3014ad47SMaud Spierings #define MAX25014_IOUT2            0x16
40*3014ad47SMaud Spierings #define MAX25014_IOUT3            0x17
41*3014ad47SMaud Spierings #define MAX25014_IOUT4            0x18
42*3014ad47SMaud Spierings #define MAX25014_OPEN             0x1B
43*3014ad47SMaud Spierings #define MAX25014_SHORTGND         0x1C
44*3014ad47SMaud Spierings #define MAX25014_SHORTED_LED      0x1D
45*3014ad47SMaud Spierings #define MAX25014_MASK             0x1E
46*3014ad47SMaud Spierings #define MAX25014_DIAG             0x1F
47*3014ad47SMaud Spierings 
48*3014ad47SMaud Spierings #define MAX25014_ISET_ENA         BIT(5)
49*3014ad47SMaud Spierings #define MAX25014_ISET_PSEN        BIT(4)
50*3014ad47SMaud Spierings #define MAX25014_IMODE_HDIM       BIT(2)
51*3014ad47SMaud Spierings #define MAX25014_SETTING_FPWM     GENMASK(6, 4)
52*3014ad47SMaud Spierings #define MAX25014_DISABLE_DIS_MASK GENMASK(3, 0)
53*3014ad47SMaud Spierings #define MAX25014_DIAG_OT          BIT(0)
54*3014ad47SMaud Spierings #define MAX25014_DIAG_OTW         BIT(1)
55*3014ad47SMaud Spierings #define MAX25014_DIAG_HW_RST      BIT(2)
56*3014ad47SMaud Spierings #define MAX25014_DIAG_BSTOV       BIT(3)
57*3014ad47SMaud Spierings #define MAX25014_DIAG_BSTUV       BIT(4)
58*3014ad47SMaud Spierings #define MAX25014_DIAG_IREFOOR     BIT(5)
59*3014ad47SMaud Spierings 
60*3014ad47SMaud Spierings struct max25014 {
61*3014ad47SMaud Spierings 	struct i2c_client *client;
62*3014ad47SMaud Spierings 	struct backlight_device *bl;
63*3014ad47SMaud Spierings 	struct regmap *regmap;
64*3014ad47SMaud Spierings 	struct gpio_desc *enable;
65*3014ad47SMaud Spierings 	uint32_t iset;
66*3014ad47SMaud Spierings 	uint8_t strings_mask;
67*3014ad47SMaud Spierings };
68*3014ad47SMaud Spierings 
69*3014ad47SMaud Spierings static const struct regmap_config max25014_regmap_config = {
70*3014ad47SMaud Spierings 	.reg_bits = 8,
71*3014ad47SMaud Spierings 	.val_bits = 8,
72*3014ad47SMaud Spierings 	.max_register = MAX25014_DIAG,
73*3014ad47SMaud Spierings };
74*3014ad47SMaud Spierings 
75*3014ad47SMaud Spierings static int max25014_initial_power_state(struct max25014 *maxim)
76*3014ad47SMaud Spierings {
77*3014ad47SMaud Spierings 	uint32_t val;
78*3014ad47SMaud Spierings 	int ret;
79*3014ad47SMaud Spierings 
80*3014ad47SMaud Spierings 	ret = regmap_read(maxim->regmap, MAX25014_ISET, &val);
81*3014ad47SMaud Spierings 	if (ret)
82*3014ad47SMaud Spierings 		return ret;
83*3014ad47SMaud Spierings 
84*3014ad47SMaud Spierings 	return val & MAX25014_ISET_ENA ? BACKLIGHT_POWER_ON : BACKLIGHT_POWER_OFF;
85*3014ad47SMaud Spierings }
86*3014ad47SMaud Spierings 
87*3014ad47SMaud Spierings static int max25014_check_errors(struct max25014 *maxim)
88*3014ad47SMaud Spierings {
89*3014ad47SMaud Spierings 	uint32_t val;
90*3014ad47SMaud Spierings 	uint8_t i;
91*3014ad47SMaud Spierings 	int ret;
92*3014ad47SMaud Spierings 
93*3014ad47SMaud Spierings 	ret = regmap_read(maxim->regmap, MAX25014_OPEN, &val);
94*3014ad47SMaud Spierings 	if (ret)
95*3014ad47SMaud Spierings 		return ret;
96*3014ad47SMaud Spierings 	if (val) {
97*3014ad47SMaud Spierings 		dev_err(&maxim->client->dev, "Open led strings detected on:\n");
98*3014ad47SMaud Spierings 		for (i = 0; i < 4; i++) {
99*3014ad47SMaud Spierings 			if (val & 1 << i)
100*3014ad47SMaud Spierings 				dev_err(&maxim->client->dev, "string %d\n", i + 1);
101*3014ad47SMaud Spierings 		}
102*3014ad47SMaud Spierings 		return -EIO;
103*3014ad47SMaud Spierings 	}
104*3014ad47SMaud Spierings 
105*3014ad47SMaud Spierings 	ret = regmap_read(maxim->regmap, MAX25014_SHORTGND, &val);
106*3014ad47SMaud Spierings 	if (ret)
107*3014ad47SMaud Spierings 		return ret;
108*3014ad47SMaud Spierings 	if (val) {
109*3014ad47SMaud Spierings 		dev_err(&maxim->client->dev, "Short to ground detected on:\n");
110*3014ad47SMaud Spierings 		for (i = 0; i < 4; i++) {
111*3014ad47SMaud Spierings 			if (val & 1 << i)
112*3014ad47SMaud Spierings 				dev_err(&maxim->client->dev, "string %d\n", i + 1);
113*3014ad47SMaud Spierings 		}
114*3014ad47SMaud Spierings 		return -EIO;
115*3014ad47SMaud Spierings 	}
116*3014ad47SMaud Spierings 
117*3014ad47SMaud Spierings 	ret = regmap_read(maxim->regmap, MAX25014_SHORTED_LED, &val);
118*3014ad47SMaud Spierings 	if (ret)
119*3014ad47SMaud Spierings 		return ret;
120*3014ad47SMaud Spierings 	if (val) {
121*3014ad47SMaud Spierings 		dev_err(&maxim->client->dev, "Shorted led detected on:\n");
122*3014ad47SMaud Spierings 		for (i = 0; i < 4; i++) {
123*3014ad47SMaud Spierings 			if (val & 1 << i)
124*3014ad47SMaud Spierings 				dev_err(&maxim->client->dev, "string %d\n", i + 1);
125*3014ad47SMaud Spierings 		}
126*3014ad47SMaud Spierings 		return -EIO;
127*3014ad47SMaud Spierings 	}
128*3014ad47SMaud Spierings 
129*3014ad47SMaud Spierings 	ret = regmap_read(maxim->regmap, MAX25014_DIAG, &val);
130*3014ad47SMaud Spierings 	if (ret)
131*3014ad47SMaud Spierings 		return ret;
132*3014ad47SMaud Spierings 	/*
133*3014ad47SMaud Spierings 	 * The HW_RST bit always starts at 1 after power up.
134*3014ad47SMaud Spierings 	 * It is reset on first read, does not indicate an error.
135*3014ad47SMaud Spierings 	 */
136*3014ad47SMaud Spierings 	if (val && val != MAX25014_DIAG_HW_RST) {
137*3014ad47SMaud Spierings 		if (val & MAX25014_DIAG_OT)
138*3014ad47SMaud Spierings 			dev_err(&maxim->client->dev,
139*3014ad47SMaud Spierings 				"Overtemperature shutdown\n");
140*3014ad47SMaud Spierings 		if (val & MAX25014_DIAG_OTW)
141*3014ad47SMaud Spierings 			dev_err(&maxim->client->dev,
142*3014ad47SMaud Spierings 				 "Chip is getting too hot (>125C)\n");
143*3014ad47SMaud Spierings 		if (val & MAX25014_DIAG_BSTOV)
144*3014ad47SMaud Spierings 			dev_err(&maxim->client->dev,
145*3014ad47SMaud Spierings 				"Boost converter overvoltage\n");
146*3014ad47SMaud Spierings 		if (val & MAX25014_DIAG_BSTUV)
147*3014ad47SMaud Spierings 			dev_err(&maxim->client->dev,
148*3014ad47SMaud Spierings 				"Boost converter undervoltage\n");
149*3014ad47SMaud Spierings 		if (val & MAX25014_DIAG_IREFOOR)
150*3014ad47SMaud Spierings 			dev_err(&maxim->client->dev, "IREF out of range\n");
151*3014ad47SMaud Spierings 		return -EIO;
152*3014ad47SMaud Spierings 	}
153*3014ad47SMaud Spierings 	return 0;
154*3014ad47SMaud Spierings }
155*3014ad47SMaud Spierings 
156*3014ad47SMaud Spierings /*
157*3014ad47SMaud Spierings  * 1. disable unused strings
158*3014ad47SMaud Spierings  * 2. set dim mode
159*3014ad47SMaud Spierings  * 3. set setting register
160*3014ad47SMaud Spierings  * 4. enable the backlight
161*3014ad47SMaud Spierings  */
162*3014ad47SMaud Spierings static int max25014_configure(struct max25014 *maxim, int initial_state)
163*3014ad47SMaud Spierings {
164*3014ad47SMaud Spierings 	uint32_t val;
165*3014ad47SMaud Spierings 	int ret;
166*3014ad47SMaud Spierings 
167*3014ad47SMaud Spierings 	ret = regmap_read(maxim->regmap, MAX25014_DISABLE, &val);
168*3014ad47SMaud Spierings 	if (ret)
169*3014ad47SMaud Spierings 		return ret;
170*3014ad47SMaud Spierings 
171*3014ad47SMaud Spierings 	/*
172*3014ad47SMaud Spierings 	 * Strings can only be disabled when MAX25014_ISET_ENA == 0, check if
173*3014ad47SMaud Spierings 	 * it needs to be changed at all to prevent the backlight flashing when
174*3014ad47SMaud Spierings 	 * it is configured correctly by the bootloader
175*3014ad47SMaud Spierings 	 */
176*3014ad47SMaud Spierings 	if (!((val & MAX25014_DISABLE_DIS_MASK) == maxim->strings_mask)) {
177*3014ad47SMaud Spierings 		if (initial_state == BACKLIGHT_POWER_ON) {
178*3014ad47SMaud Spierings 			ret = regmap_write(maxim->regmap, MAX25014_ISET, 0);
179*3014ad47SMaud Spierings 			if (ret)
180*3014ad47SMaud Spierings 				return ret;
181*3014ad47SMaud Spierings 		}
182*3014ad47SMaud Spierings 		ret = regmap_write(maxim->regmap, MAX25014_DISABLE, maxim->strings_mask);
183*3014ad47SMaud Spierings 		if (ret)
184*3014ad47SMaud Spierings 			return ret;
185*3014ad47SMaud Spierings 	}
186*3014ad47SMaud Spierings 
187*3014ad47SMaud Spierings 	ret = regmap_write(maxim->regmap, MAX25014_IMODE, MAX25014_IMODE_HDIM);
188*3014ad47SMaud Spierings 	if (ret)
189*3014ad47SMaud Spierings 		return ret;
190*3014ad47SMaud Spierings 
191*3014ad47SMaud Spierings 	ret = regmap_read(maxim->regmap, MAX25014_SETTING, &val);
192*3014ad47SMaud Spierings 	if (ret)
193*3014ad47SMaud Spierings 		return ret;
194*3014ad47SMaud Spierings 
195*3014ad47SMaud Spierings 	ret = regmap_write(maxim->regmap, MAX25014_SETTING,
196*3014ad47SMaud Spierings 			   val & ~MAX25014_SETTING_FPWM);
197*3014ad47SMaud Spierings 	if (ret)
198*3014ad47SMaud Spierings 		return ret;
199*3014ad47SMaud Spierings 
200*3014ad47SMaud Spierings 	return regmap_write(maxim->regmap, MAX25014_ISET,
201*3014ad47SMaud Spierings 			   maxim->iset | MAX25014_ISET_ENA |
202*3014ad47SMaud Spierings 			   MAX25014_ISET_PSEN);
203*3014ad47SMaud Spierings }
204*3014ad47SMaud Spierings 
205*3014ad47SMaud Spierings static int max25014_update_status(struct backlight_device *bl_dev)
206*3014ad47SMaud Spierings {
207*3014ad47SMaud Spierings 	struct max25014 *maxim = bl_get_data(bl_dev);
208*3014ad47SMaud Spierings 	uint32_t reg;
209*3014ad47SMaud Spierings 	int ret;
210*3014ad47SMaud Spierings 
211*3014ad47SMaud Spierings 	reg  = TON_STEP * backlight_get_brightness(bl_dev);
212*3014ad47SMaud Spierings 
213*3014ad47SMaud Spierings 	/*
214*3014ad47SMaud Spierings 	 * 18 bit number lowest, 2 bits in first register,
215*3014ad47SMaud Spierings 	 * next lowest 8 in the L register, next 8 in the H register
216*3014ad47SMaud Spierings 	 * Seemingly setting the strength of only one string controls all of
217*3014ad47SMaud Spierings 	 * them, individual settings don't affect the outcome.
218*3014ad47SMaud Spierings 	 */
219*3014ad47SMaud Spierings 	ret = regmap_write(maxim->regmap, MAX25014_TON_1_4_LSB, reg & 0b00000011);
220*3014ad47SMaud Spierings 	if (ret != 0)
221*3014ad47SMaud Spierings 		return ret;
222*3014ad47SMaud Spierings 	ret = regmap_write(maxim->regmap, MAX25014_TON1L, (reg >> 2) & 0b11111111);
223*3014ad47SMaud Spierings 	if (ret != 0)
224*3014ad47SMaud Spierings 		return ret;
225*3014ad47SMaud Spierings 	return regmap_write(maxim->regmap, MAX25014_TON1H, (reg >> 10) & 0b11111111);
226*3014ad47SMaud Spierings }
227*3014ad47SMaud Spierings 
228*3014ad47SMaud Spierings static const struct backlight_ops max25014_bl_ops = {
229*3014ad47SMaud Spierings 	.options = BL_CORE_SUSPENDRESUME,
230*3014ad47SMaud Spierings 	.update_status = max25014_update_status,
231*3014ad47SMaud Spierings };
232*3014ad47SMaud Spierings 
233*3014ad47SMaud Spierings static int max25014_parse_dt(struct max25014 *maxim,
234*3014ad47SMaud Spierings 			     uint32_t *initial_brightness)
235*3014ad47SMaud Spierings {
236*3014ad47SMaud Spierings 	struct device *dev = &maxim->client->dev;
237*3014ad47SMaud Spierings 	struct device_node *node = dev->of_node;
238*3014ad47SMaud Spierings 	uint32_t strings[4];
239*3014ad47SMaud Spierings 	int res, i;
240*3014ad47SMaud Spierings 
241*3014ad47SMaud Spierings 	res = of_property_count_u32_elems(node, "maxim,strings");
242*3014ad47SMaud Spierings 	if (res == 4) {
243*3014ad47SMaud Spierings 		of_property_read_u32_array(node, "maxim,strings", strings, 4);
244*3014ad47SMaud Spierings 		for (i = 0; i < 4; i++) {
245*3014ad47SMaud Spierings 			if (strings[i] == 0)
246*3014ad47SMaud Spierings 				maxim->strings_mask |= 1 << i;
247*3014ad47SMaud Spierings 	}
248*3014ad47SMaud Spierings 	} else {
249*3014ad47SMaud Spierings 		maxim->strings_mask = 0;
250*3014ad47SMaud Spierings 	}
251*3014ad47SMaud Spierings 
252*3014ad47SMaud Spierings 	*initial_brightness = 50U;
253*3014ad47SMaud Spierings 	of_property_read_u32(node, "default-brightness", initial_brightness);
254*3014ad47SMaud Spierings 
255*3014ad47SMaud Spierings 	maxim->iset = MAX25014_ISET_DEFAULT_100;
256*3014ad47SMaud Spierings 	of_property_read_u32(node, "maxim,iset", &maxim->iset);
257*3014ad47SMaud Spierings 
258*3014ad47SMaud Spierings 	if (maxim->iset > 15)
259*3014ad47SMaud Spierings 		return dev_err_probe(dev, -EINVAL,
260*3014ad47SMaud Spierings 				     "Invalid iset, should be a value from 0-15, entered was %d\n",
261*3014ad47SMaud Spierings 				     maxim->iset);
262*3014ad47SMaud Spierings 
263*3014ad47SMaud Spierings 	if (*initial_brightness > 100)
264*3014ad47SMaud Spierings 		return dev_err_probe(dev, -EINVAL,
265*3014ad47SMaud Spierings 				     "Invalid initial brightness, should be a value from 0-100, entered was %d\n",
266*3014ad47SMaud Spierings 				     *initial_brightness);
267*3014ad47SMaud Spierings 
268*3014ad47SMaud Spierings 	return 0;
269*3014ad47SMaud Spierings }
270*3014ad47SMaud Spierings 
271*3014ad47SMaud Spierings static int max25014_probe(struct i2c_client *cl)
272*3014ad47SMaud Spierings {
273*3014ad47SMaud Spierings 	const struct i2c_device_id *id = i2c_client_get_device_id(cl);
274*3014ad47SMaud Spierings 	struct backlight_properties props;
275*3014ad47SMaud Spierings 	uint32_t initial_brightness = 50;
276*3014ad47SMaud Spierings 	struct backlight_device *bl;
277*3014ad47SMaud Spierings 	struct max25014 *maxim;
278*3014ad47SMaud Spierings 	int ret;
279*3014ad47SMaud Spierings 
280*3014ad47SMaud Spierings 	maxim = devm_kzalloc(&cl->dev, sizeof(struct max25014), GFP_KERNEL);
281*3014ad47SMaud Spierings 	if (!maxim)
282*3014ad47SMaud Spierings 		return -ENOMEM;
283*3014ad47SMaud Spierings 
284*3014ad47SMaud Spierings 	maxim->client = cl;
285*3014ad47SMaud Spierings 
286*3014ad47SMaud Spierings 	ret = max25014_parse_dt(maxim, &initial_brightness);
287*3014ad47SMaud Spierings 	if (ret)
288*3014ad47SMaud Spierings 		return ret;
289*3014ad47SMaud Spierings 
290*3014ad47SMaud Spierings 	ret = devm_regulator_get_enable(&maxim->client->dev, "power");
291*3014ad47SMaud Spierings 	if (ret)
292*3014ad47SMaud Spierings 		return dev_err_probe(&maxim->client->dev, ret,
293*3014ad47SMaud Spierings 				     "failed to get power-supply");
294*3014ad47SMaud Spierings 
295*3014ad47SMaud Spierings 	maxim->enable = devm_gpiod_get_optional(&maxim->client->dev, "enable",
296*3014ad47SMaud Spierings 						GPIOD_OUT_HIGH);
297*3014ad47SMaud Spierings 	if (IS_ERR(maxim->enable))
298*3014ad47SMaud Spierings 		return dev_err_probe(&maxim->client->dev, PTR_ERR(maxim->enable),
299*3014ad47SMaud Spierings 				    "failed to get enable gpio\n");
300*3014ad47SMaud Spierings 
301*3014ad47SMaud Spierings 	/* Datasheet Electrical Characteristics tSTARTUP 2ms */
302*3014ad47SMaud Spierings 	fsleep(2000);
303*3014ad47SMaud Spierings 
304*3014ad47SMaud Spierings 	maxim->regmap = devm_regmap_init_i2c(cl, &max25014_regmap_config);
305*3014ad47SMaud Spierings 	if (IS_ERR(maxim->regmap))
306*3014ad47SMaud Spierings 		return dev_err_probe(&maxim->client->dev, PTR_ERR(maxim->regmap),
307*3014ad47SMaud Spierings 			"failed to initialize the i2c regmap\n");
308*3014ad47SMaud Spierings 
309*3014ad47SMaud Spierings 	i2c_set_clientdata(cl, maxim);
310*3014ad47SMaud Spierings 
311*3014ad47SMaud Spierings 	ret = max25014_check_errors(maxim);
312*3014ad47SMaud Spierings 	if (ret) /* error is already reported in the above function */
313*3014ad47SMaud Spierings 		return ret;
314*3014ad47SMaud Spierings 
315*3014ad47SMaud Spierings 	ret = max25014_initial_power_state(maxim);
316*3014ad47SMaud Spierings 	if (ret < 0)
317*3014ad47SMaud Spierings 		return dev_err_probe(&maxim->client->dev, ret, "Could not get enabled state\n");
318*3014ad47SMaud Spierings 
319*3014ad47SMaud Spierings 	memset(&props, 0, sizeof(struct backlight_properties));
320*3014ad47SMaud Spierings 	props.type = BACKLIGHT_PLATFORM;
321*3014ad47SMaud Spierings 	props.max_brightness = MAX_BRIGHTNESS;
322*3014ad47SMaud Spierings 	props.brightness = initial_brightness;
323*3014ad47SMaud Spierings 	props.scale = BACKLIGHT_SCALE_LINEAR;
324*3014ad47SMaud Spierings 	props.power = ret;
325*3014ad47SMaud Spierings 
326*3014ad47SMaud Spierings 	ret = max25014_configure(maxim, ret);
327*3014ad47SMaud Spierings 	if (ret)
328*3014ad47SMaud Spierings 		return dev_err_probe(&maxim->client->dev, ret, "device config error");
329*3014ad47SMaud Spierings 
330*3014ad47SMaud Spierings 	bl = devm_backlight_device_register(&maxim->client->dev, id->name,
331*3014ad47SMaud Spierings 					    &maxim->client->dev, maxim,
332*3014ad47SMaud Spierings 					    &max25014_bl_ops, &props);
333*3014ad47SMaud Spierings 	if (IS_ERR(bl))
334*3014ad47SMaud Spierings 		return dev_err_probe(&maxim->client->dev, PTR_ERR(bl),
335*3014ad47SMaud Spierings 				    "failed to register backlight\n");
336*3014ad47SMaud Spierings 
337*3014ad47SMaud Spierings 	maxim->bl = bl;
338*3014ad47SMaud Spierings 
339*3014ad47SMaud Spierings 	backlight_update_status(maxim->bl);
340*3014ad47SMaud Spierings 
341*3014ad47SMaud Spierings 	return 0;
342*3014ad47SMaud Spierings }
343*3014ad47SMaud Spierings 
344*3014ad47SMaud Spierings static void max25014_remove(struct i2c_client *cl)
345*3014ad47SMaud Spierings {
346*3014ad47SMaud Spierings 	struct max25014 *maxim = i2c_get_clientdata(cl);
347*3014ad47SMaud Spierings 
348*3014ad47SMaud Spierings 	backlight_device_set_brightness(maxim->bl, 0);
349*3014ad47SMaud Spierings 	gpiod_set_value_cansleep(maxim->enable, 0);
350*3014ad47SMaud Spierings }
351*3014ad47SMaud Spierings 
352*3014ad47SMaud Spierings static const struct of_device_id max25014_dt_ids[] = {
353*3014ad47SMaud Spierings 	{ .compatible = "maxim,max25014", },
354*3014ad47SMaud Spierings 	{ }
355*3014ad47SMaud Spierings };
356*3014ad47SMaud Spierings MODULE_DEVICE_TABLE(of, max25014_dt_ids);
357*3014ad47SMaud Spierings 
358*3014ad47SMaud Spierings static const struct i2c_device_id max25014_ids[] = {
359*3014ad47SMaud Spierings 	{ "max25014" },
360*3014ad47SMaud Spierings 	{ }
361*3014ad47SMaud Spierings };
362*3014ad47SMaud Spierings MODULE_DEVICE_TABLE(i2c, max25014_ids);
363*3014ad47SMaud Spierings 
364*3014ad47SMaud Spierings static struct i2c_driver max25014_driver = {
365*3014ad47SMaud Spierings 	.driver = {
366*3014ad47SMaud Spierings 		.name = KBUILD_MODNAME,
367*3014ad47SMaud Spierings 		.of_match_table = of_match_ptr(max25014_dt_ids),
368*3014ad47SMaud Spierings 	},
369*3014ad47SMaud Spierings 	.probe = max25014_probe,
370*3014ad47SMaud Spierings 	.remove = max25014_remove,
371*3014ad47SMaud Spierings 	.id_table = max25014_ids,
372*3014ad47SMaud Spierings };
373*3014ad47SMaud Spierings module_i2c_driver(max25014_driver);
374*3014ad47SMaud Spierings 
375*3014ad47SMaud Spierings MODULE_DESCRIPTION("Maxim MAX25014 backlight driver");
376*3014ad47SMaud Spierings MODULE_AUTHOR("Maud Spierings <maudspierings@gocontroll.com>");
377*3014ad47SMaud Spierings MODULE_LICENSE("GPL");
378