xref: /linux/drivers/video/backlight/lp855x_bl.c (revision a544684b790f3e9f75173b3b42d7dad1c89dd237)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * TI LP855x Backlight Driver
4  *
5  *			Copyright (C) 2011 Texas Instruments
6  */
7 
8 #include <linux/acpi.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/i2c.h>
12 #include <linux/backlight.h>
13 #include <linux/delay.h>
14 #include <linux/err.h>
15 #include <linux/of.h>
16 #include <linux/platform_data/lp855x.h>
17 #include <linux/pwm.h>
18 #include <linux/regulator/consumer.h>
19 
20 /* LP8550/1/2/3/6 Registers */
21 #define LP855X_BRIGHTNESS_CTRL		0x00
22 #define LP855X_DEVICE_CTRL		0x01
23 #define LP855X_EEPROM_START		0xA0
24 #define LP855X_EEPROM_END		0xA7
25 #define LP8556_EPROM_START		0xA0
26 #define LP8556_EPROM_END		0xAF
27 
28 /* LP8555/7 Registers */
29 #define LP8557_BL_CMD			0x00
30 #define LP8557_BL_MASK			0x01
31 #define LP8557_BL_ON			0x01
32 #define LP8557_BL_OFF			0x00
33 #define LP8557_BRIGHTNESS_CTRL		0x04
34 #define LP8557_CONFIG			0x10
35 #define LP8555_EPROM_START		0x10
36 #define LP8555_EPROM_END		0x7A
37 #define LP8557_EPROM_START		0x10
38 #define LP8557_EPROM_END		0x1E
39 
40 #define DEFAULT_BL_NAME		"lcd-backlight"
41 #define MAX_BRIGHTNESS		255
42 
43 enum lp855x_brightness_ctrl_mode {
44 	PWM_BASED = 1,
45 	REGISTER_BASED,
46 };
47 
48 struct lp855x;
49 
50 /*
51  * struct lp855x_device_config
52  * @pre_init_device: init device function call before updating the brightness
53  * @reg_brightness: register address for brigthenss control
54  * @reg_devicectrl: register address for device control
55  * @post_init_device: late init device function call
56  */
57 struct lp855x_device_config {
58 	int (*pre_init_device)(struct lp855x *);
59 	u8 reg_brightness;
60 	u8 reg_devicectrl;
61 	int (*post_init_device)(struct lp855x *);
62 };
63 
64 struct lp855x {
65 	const char *chipname;
66 	enum lp855x_chip_id chip_id;
67 	enum lp855x_brightness_ctrl_mode mode;
68 	struct lp855x_device_config *cfg;
69 	struct i2c_client *client;
70 	struct backlight_device *bl;
71 	struct device *dev;
72 	struct lp855x_platform_data *pdata;
73 	struct pwm_device *pwm;
74 	struct regulator *supply;	/* regulator for VDD input */
75 	struct regulator *enable;	/* regulator for EN/VDDIO input */
76 };
77 
78 static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
79 {
80 	return i2c_smbus_write_byte_data(lp->client, reg, data);
81 }
82 
83 static int lp855x_update_bit(struct lp855x *lp, u8 reg, u8 mask, u8 data)
84 {
85 	int ret;
86 	u8 tmp;
87 
88 	ret = i2c_smbus_read_byte_data(lp->client, reg);
89 	if (ret < 0) {
90 		dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
91 		return ret;
92 	}
93 
94 	tmp = (u8)ret;
95 	tmp &= ~mask;
96 	tmp |= data & mask;
97 
98 	return lp855x_write_byte(lp, reg, tmp);
99 }
100 
101 static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
102 {
103 	u8 start, end;
104 
105 	switch (lp->chip_id) {
106 	case LP8550:
107 	case LP8551:
108 	case LP8552:
109 	case LP8553:
110 		start = LP855X_EEPROM_START;
111 		end = LP855X_EEPROM_END;
112 		break;
113 	case LP8556:
114 		start = LP8556_EPROM_START;
115 		end = LP8556_EPROM_END;
116 		break;
117 	case LP8555:
118 		start = LP8555_EPROM_START;
119 		end = LP8555_EPROM_END;
120 		break;
121 	case LP8557:
122 		start = LP8557_EPROM_START;
123 		end = LP8557_EPROM_END;
124 		break;
125 	default:
126 		return false;
127 	}
128 
129 	return addr >= start && addr <= end;
130 }
131 
132 static int lp8557_bl_off(struct lp855x *lp)
133 {
134 	/* BL_ON = 0 before updating EPROM settings */
135 	return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
136 				LP8557_BL_OFF);
137 }
138 
139 static int lp8557_bl_on(struct lp855x *lp)
140 {
141 	/* BL_ON = 1 after updating EPROM settings */
142 	return lp855x_update_bit(lp, LP8557_BL_CMD, LP8557_BL_MASK,
143 				LP8557_BL_ON);
144 }
145 
146 static struct lp855x_device_config lp855x_dev_cfg = {
147 	.reg_brightness = LP855X_BRIGHTNESS_CTRL,
148 	.reg_devicectrl = LP855X_DEVICE_CTRL,
149 };
150 
151 static struct lp855x_device_config lp8557_dev_cfg = {
152 	.reg_brightness = LP8557_BRIGHTNESS_CTRL,
153 	.reg_devicectrl = LP8557_CONFIG,
154 	.pre_init_device = lp8557_bl_off,
155 	.post_init_device = lp8557_bl_on,
156 };
157 
158 /*
159  * Device specific configuration flow
160  *
161  *    a) pre_init_device(optional)
162  *    b) update the brightness register
163  *    c) update device control register
164  *    d) update ROM area(optional)
165  *    e) post_init_device(optional)
166  *
167  */
168 static int lp855x_configure(struct lp855x *lp)
169 {
170 	u8 val, addr;
171 	int i, ret;
172 	struct lp855x_platform_data *pd = lp->pdata;
173 
174 	if (lp->cfg->pre_init_device) {
175 		ret = lp->cfg->pre_init_device(lp);
176 		if (ret) {
177 			dev_err(lp->dev, "pre init device err: %d\n", ret);
178 			goto err;
179 		}
180 	}
181 
182 	val = pd->initial_brightness;
183 	ret = lp855x_write_byte(lp, lp->cfg->reg_brightness, val);
184 	if (ret)
185 		goto err;
186 
187 	val = pd->device_control;
188 	ret = lp855x_write_byte(lp, lp->cfg->reg_devicectrl, val);
189 	if (ret)
190 		goto err;
191 
192 	if (pd->size_program > 0) {
193 		for (i = 0; i < pd->size_program; i++) {
194 			addr = pd->rom_data[i].addr;
195 			val = pd->rom_data[i].val;
196 			if (!lp855x_is_valid_rom_area(lp, addr))
197 				continue;
198 
199 			ret = lp855x_write_byte(lp, addr, val);
200 			if (ret)
201 				goto err;
202 		}
203 	}
204 
205 	if (lp->cfg->post_init_device) {
206 		ret = lp->cfg->post_init_device(lp);
207 		if (ret) {
208 			dev_err(lp->dev, "post init device err: %d\n", ret);
209 			goto err;
210 		}
211 	}
212 
213 	return 0;
214 
215 err:
216 	return ret;
217 }
218 
219 static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br)
220 {
221 	unsigned int period = lp->pdata->period_ns;
222 	unsigned int duty = br * period / max_br;
223 	struct pwm_device *pwm;
224 
225 	/* request pwm device with the consumer name */
226 	if (!lp->pwm) {
227 		pwm = devm_pwm_get(lp->dev, lp->chipname);
228 		if (IS_ERR(pwm))
229 			return;
230 
231 		lp->pwm = pwm;
232 
233 		/*
234 		 * FIXME: pwm_apply_args() should be removed when switching to
235 		 * the atomic PWM API.
236 		 */
237 		pwm_apply_args(pwm);
238 	}
239 
240 	pwm_config(lp->pwm, duty, period);
241 	if (duty)
242 		pwm_enable(lp->pwm);
243 	else
244 		pwm_disable(lp->pwm);
245 }
246 
247 static int lp855x_bl_update_status(struct backlight_device *bl)
248 {
249 	struct lp855x *lp = bl_get_data(bl);
250 	int brightness = bl->props.brightness;
251 
252 	if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
253 		brightness = 0;
254 
255 	if (lp->mode == PWM_BASED)
256 		lp855x_pwm_ctrl(lp, brightness, bl->props.max_brightness);
257 	else if (lp->mode == REGISTER_BASED)
258 		lp855x_write_byte(lp, lp->cfg->reg_brightness, (u8)brightness);
259 
260 	return 0;
261 }
262 
263 static const struct backlight_ops lp855x_bl_ops = {
264 	.options = BL_CORE_SUSPENDRESUME,
265 	.update_status = lp855x_bl_update_status,
266 };
267 
268 static int lp855x_backlight_register(struct lp855x *lp)
269 {
270 	struct backlight_device *bl;
271 	struct backlight_properties props;
272 	struct lp855x_platform_data *pdata = lp->pdata;
273 	const char *name = pdata->name ? : DEFAULT_BL_NAME;
274 
275 	memset(&props, 0, sizeof(props));
276 	props.type = BACKLIGHT_PLATFORM;
277 	props.max_brightness = MAX_BRIGHTNESS;
278 
279 	if (pdata->initial_brightness > props.max_brightness)
280 		pdata->initial_brightness = props.max_brightness;
281 
282 	props.brightness = pdata->initial_brightness;
283 
284 	bl = devm_backlight_device_register(lp->dev, name, lp->dev, lp,
285 				       &lp855x_bl_ops, &props);
286 	if (IS_ERR(bl))
287 		return PTR_ERR(bl);
288 
289 	lp->bl = bl;
290 
291 	return 0;
292 }
293 
294 static ssize_t lp855x_get_chip_id(struct device *dev,
295 				struct device_attribute *attr, char *buf)
296 {
297 	struct lp855x *lp = dev_get_drvdata(dev);
298 
299 	return scnprintf(buf, PAGE_SIZE, "%s\n", lp->chipname);
300 }
301 
302 static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
303 				     struct device_attribute *attr, char *buf)
304 {
305 	struct lp855x *lp = dev_get_drvdata(dev);
306 	char *strmode = NULL;
307 
308 	if (lp->mode == PWM_BASED)
309 		strmode = "pwm based";
310 	else if (lp->mode == REGISTER_BASED)
311 		strmode = "register based";
312 
313 	return scnprintf(buf, PAGE_SIZE, "%s\n", strmode);
314 }
315 
316 static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
317 static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
318 
319 static struct attribute *lp855x_attributes[] = {
320 	&dev_attr_chip_id.attr,
321 	&dev_attr_bl_ctl_mode.attr,
322 	NULL,
323 };
324 
325 static const struct attribute_group lp855x_attr_group = {
326 	.attrs = lp855x_attributes,
327 };
328 
329 #ifdef CONFIG_OF
330 static int lp855x_parse_dt(struct lp855x *lp)
331 {
332 	struct device *dev = lp->dev;
333 	struct device_node *node = dev->of_node;
334 	struct lp855x_platform_data *pdata = lp->pdata;
335 	int rom_length;
336 
337 	if (!node) {
338 		dev_err(dev, "no platform data\n");
339 		return -EINVAL;
340 	}
341 
342 	of_property_read_string(node, "bl-name", &pdata->name);
343 	of_property_read_u8(node, "dev-ctrl", &pdata->device_control);
344 	of_property_read_u8(node, "init-brt", &pdata->initial_brightness);
345 	of_property_read_u32(node, "pwm-period", &pdata->period_ns);
346 
347 	/* Fill ROM platform data if defined */
348 	rom_length = of_get_child_count(node);
349 	if (rom_length > 0) {
350 		struct lp855x_rom_data *rom;
351 		struct device_node *child;
352 		int i = 0;
353 
354 		rom = devm_kcalloc(dev, rom_length, sizeof(*rom), GFP_KERNEL);
355 		if (!rom)
356 			return -ENOMEM;
357 
358 		for_each_child_of_node(node, child) {
359 			of_property_read_u8(child, "rom-addr", &rom[i].addr);
360 			of_property_read_u8(child, "rom-val", &rom[i].val);
361 			i++;
362 		}
363 
364 		pdata->size_program = rom_length;
365 		pdata->rom_data = &rom[0];
366 	}
367 
368 	return 0;
369 }
370 #else
371 static int lp855x_parse_dt(struct lp855x *lp)
372 {
373 	return -EINVAL;
374 }
375 #endif
376 
377 static int lp855x_parse_acpi(struct lp855x *lp)
378 {
379 	int ret;
380 
381 	/*
382 	 * On ACPI the device has already been initialized by the firmware
383 	 * and is in register mode, so we can read back the settings from
384 	 * the registers.
385 	 */
386 	ret = i2c_smbus_read_byte_data(lp->client, lp->cfg->reg_brightness);
387 	if (ret < 0)
388 		return ret;
389 
390 	lp->pdata->initial_brightness = ret;
391 
392 	ret = i2c_smbus_read_byte_data(lp->client, lp->cfg->reg_devicectrl);
393 	if (ret < 0)
394 		return ret;
395 
396 	lp->pdata->device_control = ret;
397 	return 0;
398 }
399 
400 static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
401 {
402 	const struct acpi_device_id *acpi_id = NULL;
403 	struct device *dev = &cl->dev;
404 	struct lp855x *lp;
405 	int ret;
406 
407 	if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
408 		return -EIO;
409 
410 	lp = devm_kzalloc(dev, sizeof(struct lp855x), GFP_KERNEL);
411 	if (!lp)
412 		return -ENOMEM;
413 
414 	lp->client = cl;
415 	lp->dev = dev;
416 	lp->pdata = dev_get_platdata(dev);
417 
418 	if (id) {
419 		lp->chipname = id->name;
420 		lp->chip_id = id->driver_data;
421 	} else {
422 		acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
423 		if (!acpi_id)
424 			return -ENODEV;
425 
426 		lp->chipname = acpi_id->id;
427 		lp->chip_id = acpi_id->driver_data;
428 	}
429 
430 	switch (lp->chip_id) {
431 	case LP8550:
432 	case LP8551:
433 	case LP8552:
434 	case LP8553:
435 	case LP8556:
436 		lp->cfg = &lp855x_dev_cfg;
437 		break;
438 	case LP8555:
439 	case LP8557:
440 		lp->cfg = &lp8557_dev_cfg;
441 		break;
442 	default:
443 		return -EINVAL;
444 	}
445 
446 	if (!lp->pdata) {
447 		lp->pdata = devm_kzalloc(dev, sizeof(*lp->pdata), GFP_KERNEL);
448 		if (!lp->pdata)
449 			return -ENOMEM;
450 
451 		if (id) {
452 			ret = lp855x_parse_dt(lp);
453 			if (ret < 0)
454 				return ret;
455 		} else {
456 			ret = lp855x_parse_acpi(lp);
457 			if (ret < 0)
458 				return ret;
459 		}
460 	}
461 
462 	if (lp->pdata->period_ns > 0)
463 		lp->mode = PWM_BASED;
464 	else
465 		lp->mode = REGISTER_BASED;
466 
467 	lp->supply = devm_regulator_get(dev, "power");
468 	if (IS_ERR(lp->supply)) {
469 		if (PTR_ERR(lp->supply) == -EPROBE_DEFER)
470 			return -EPROBE_DEFER;
471 		lp->supply = NULL;
472 	}
473 
474 	lp->enable = devm_regulator_get_optional(dev, "enable");
475 	if (IS_ERR(lp->enable)) {
476 		ret = PTR_ERR(lp->enable);
477 		if (ret == -ENODEV) {
478 			lp->enable = NULL;
479 		} else {
480 			return dev_err_probe(dev, ret, "getting enable regulator\n");
481 		}
482 	}
483 
484 	if (lp->supply) {
485 		ret = regulator_enable(lp->supply);
486 		if (ret < 0) {
487 			dev_err(dev, "failed to enable supply: %d\n", ret);
488 			return ret;
489 		}
490 	}
491 
492 	if (lp->enable) {
493 		ret = regulator_enable(lp->enable);
494 		if (ret < 0) {
495 			dev_err(dev, "failed to enable vddio: %d\n", ret);
496 			goto disable_supply;
497 		}
498 
499 		/*
500 		 * LP8555 datasheet says t_RESPONSE (time between VDDIO and
501 		 * I2C) is 1ms.
502 		 */
503 		usleep_range(1000, 2000);
504 	}
505 
506 	i2c_set_clientdata(cl, lp);
507 
508 	ret = lp855x_configure(lp);
509 	if (ret) {
510 		dev_err(dev, "device config err: %d", ret);
511 		goto disable_vddio;
512 	}
513 
514 	ret = lp855x_backlight_register(lp);
515 	if (ret) {
516 		dev_err(dev, "failed to register backlight. err: %d\n", ret);
517 		goto disable_vddio;
518 	}
519 
520 	ret = sysfs_create_group(&dev->kobj, &lp855x_attr_group);
521 	if (ret) {
522 		dev_err(dev, "failed to register sysfs. err: %d\n", ret);
523 		goto disable_vddio;
524 	}
525 
526 	backlight_update_status(lp->bl);
527 
528 	return 0;
529 
530 disable_vddio:
531 	if (lp->enable)
532 		regulator_disable(lp->enable);
533 disable_supply:
534 	if (lp->supply)
535 		regulator_disable(lp->supply);
536 
537 	return ret;
538 }
539 
540 static int lp855x_remove(struct i2c_client *cl)
541 {
542 	struct lp855x *lp = i2c_get_clientdata(cl);
543 
544 	lp->bl->props.brightness = 0;
545 	backlight_update_status(lp->bl);
546 	if (lp->enable)
547 		regulator_disable(lp->enable);
548 	if (lp->supply)
549 		regulator_disable(lp->supply);
550 	sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
551 
552 	return 0;
553 }
554 
555 static const struct of_device_id lp855x_dt_ids[] = {
556 	{ .compatible = "ti,lp8550", },
557 	{ .compatible = "ti,lp8551", },
558 	{ .compatible = "ti,lp8552", },
559 	{ .compatible = "ti,lp8553", },
560 	{ .compatible = "ti,lp8555", },
561 	{ .compatible = "ti,lp8556", },
562 	{ .compatible = "ti,lp8557", },
563 	{ }
564 };
565 MODULE_DEVICE_TABLE(of, lp855x_dt_ids);
566 
567 static const struct i2c_device_id lp855x_ids[] = {
568 	{"lp8550", LP8550},
569 	{"lp8551", LP8551},
570 	{"lp8552", LP8552},
571 	{"lp8553", LP8553},
572 	{"lp8555", LP8555},
573 	{"lp8556", LP8556},
574 	{"lp8557", LP8557},
575 	{ }
576 };
577 MODULE_DEVICE_TABLE(i2c, lp855x_ids);
578 
579 #ifdef CONFIG_ACPI
580 static const struct acpi_device_id lp855x_acpi_match[] = {
581 	/* Xiaomi specific HID used for the LP8556 on the Mi Pad 2 */
582 	{ "XMCC0001", LP8556 },
583 	{ }
584 };
585 MODULE_DEVICE_TABLE(acpi, lp855x_acpi_match);
586 #endif
587 
588 static struct i2c_driver lp855x_driver = {
589 	.driver = {
590 		   .name = "lp855x",
591 		   .of_match_table = of_match_ptr(lp855x_dt_ids),
592 		   .acpi_match_table = ACPI_PTR(lp855x_acpi_match),
593 		   },
594 	.probe = lp855x_probe,
595 	.remove = lp855x_remove,
596 	.id_table = lp855x_ids,
597 };
598 
599 module_i2c_driver(lp855x_driver);
600 
601 MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
602 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
603 MODULE_LICENSE("GPL");
604