1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * TI LP8501 9 channel LED Driver
4 *
5 * Copyright (C) 2013 Texas Instruments
6 *
7 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
8 */
9
10#include <linux/delay.h>
11#include <linux/firmware.h>
12#include <linux/i2c.h>
13#include <linux/init.h>
14#include <linux/leds.h>
15#include <linux/module.h>
16#include <linux/mutex.h>
17#include <linux/of.h>
18#include <linux/platform_data/leds-lp55xx.h>
19#include <linux/slab.h>
20
21#include "leds-lp55xx-common.h"
22
23#define LP8501_PROGRAM_LENGTH		32
24#define LP8501_MAX_LEDS			9
25
26/* Registers */
27#define LP8501_REG_ENABLE		0x00
28#define LP8501_ENABLE			BIT(6)
29#define LP8501_EXEC_M			0x3F
30#define LP8501_EXEC_ENG1_M		0x30
31#define LP8501_EXEC_ENG2_M		0x0C
32#define LP8501_EXEC_ENG3_M		0x03
33#define LP8501_RUN_ENG1			0x20
34#define LP8501_RUN_ENG2			0x08
35#define LP8501_RUN_ENG3			0x02
36
37#define LP8501_REG_OP_MODE		0x01
38#define LP8501_MODE_ENG1_M		0x30
39#define LP8501_MODE_ENG2_M		0x0C
40#define LP8501_MODE_ENG3_M		0x03
41#define LP8501_LOAD_ENG1		0x10
42#define LP8501_LOAD_ENG2		0x04
43#define LP8501_LOAD_ENG3		0x01
44
45#define LP8501_REG_PWR_CONFIG		0x05
46#define LP8501_PWR_CONFIG_M		0x03
47
48#define LP8501_REG_LED_PWM_BASE		0x16
49
50#define LP8501_REG_LED_CURRENT_BASE	0x26
51
52#define LP8501_REG_CONFIG		0x36
53#define LP8501_PWM_PSAVE		BIT(7)
54#define LP8501_AUTO_INC			BIT(6)
55#define LP8501_PWR_SAVE			BIT(5)
56#define LP8501_CP_MODE_MASK		0x18
57#define LP8501_CP_MODE_SHIFT		3
58#define LP8501_INT_CLK			BIT(0)
59#define LP8501_DEFAULT_CFG (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE)
60
61#define LP8501_REG_RESET		0x3D
62#define LP8501_RESET			0xFF
63
64#define LP8501_REG_PROG_PAGE_SEL	0x4F
65#define LP8501_PAGE_ENG1		0
66#define LP8501_PAGE_ENG2		1
67#define LP8501_PAGE_ENG3		2
68
69#define LP8501_REG_PROG_MEM		0x50
70
71#define LP8501_ENG1_IS_LOADING(mode)	\
72	((mode & LP8501_MODE_ENG1_M) == LP8501_LOAD_ENG1)
73#define LP8501_ENG2_IS_LOADING(mode)	\
74	((mode & LP8501_MODE_ENG2_M) == LP8501_LOAD_ENG2)
75#define LP8501_ENG3_IS_LOADING(mode)	\
76	((mode & LP8501_MODE_ENG3_M) == LP8501_LOAD_ENG3)
77
78static inline void lp8501_wait_opmode_done(void)
79{
80	usleep_range(1000, 2000);
81}
82
83static void lp8501_set_led_current(struct lp55xx_led *led, u8 led_current)
84{
85	led->led_current = led_current;
86	lp55xx_write(led->chip, LP8501_REG_LED_CURRENT_BASE + led->chan_nr,
87		led_current);
88}
89
90static int lp8501_post_init_device(struct lp55xx_chip *chip)
91{
92	int ret;
93	u8 val = LP8501_DEFAULT_CFG;
94
95	ret = lp55xx_write(chip, LP8501_REG_ENABLE, LP8501_ENABLE);
96	if (ret)
97		return ret;
98
99	/* Chip startup time is 500 us, 1 - 2 ms gives some margin */
100	usleep_range(1000, 2000);
101
102	if (chip->pdata->clock_mode != LP55XX_CLOCK_EXT)
103		val |= LP8501_INT_CLK;
104
105	val |= (chip->pdata->charge_pump_mode << LP8501_CP_MODE_SHIFT) & LP8501_CP_MODE_MASK;
106
107	ret = lp55xx_write(chip, LP8501_REG_CONFIG, val);
108	if (ret)
109		return ret;
110
111	/* Power selection for each output */
112	return lp55xx_update_bits(chip, LP8501_REG_PWR_CONFIG,
113				LP8501_PWR_CONFIG_M, chip->pdata->pwr_sel);
114}
115
116static void lp8501_load_engine(struct lp55xx_chip *chip)
117{
118	enum lp55xx_engine_index idx = chip->engine_idx;
119	static const u8 mask[] = {
120		[LP55XX_ENGINE_1] = LP8501_MODE_ENG1_M,
121		[LP55XX_ENGINE_2] = LP8501_MODE_ENG2_M,
122		[LP55XX_ENGINE_3] = LP8501_MODE_ENG3_M,
123	};
124
125	static const u8 val[] = {
126		[LP55XX_ENGINE_1] = LP8501_LOAD_ENG1,
127		[LP55XX_ENGINE_2] = LP8501_LOAD_ENG2,
128		[LP55XX_ENGINE_3] = LP8501_LOAD_ENG3,
129	};
130
131	static const u8 page_sel[] = {
132		[LP55XX_ENGINE_1] = LP8501_PAGE_ENG1,
133		[LP55XX_ENGINE_2] = LP8501_PAGE_ENG2,
134		[LP55XX_ENGINE_3] = LP8501_PAGE_ENG3,
135	};
136
137	lp55xx_update_bits(chip, LP8501_REG_OP_MODE, mask[idx], val[idx]);
138
139	lp8501_wait_opmode_done();
140
141	lp55xx_write(chip, LP8501_REG_PROG_PAGE_SEL, page_sel[idx]);
142}
143
144static void lp8501_stop_engine(struct lp55xx_chip *chip)
145{
146	lp55xx_write(chip, LP8501_REG_OP_MODE, 0);
147	lp8501_wait_opmode_done();
148}
149
150static void lp8501_turn_off_channels(struct lp55xx_chip *chip)
151{
152	int i;
153
154	for (i = 0; i < LP8501_MAX_LEDS; i++)
155		lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + i, 0);
156}
157
158static void lp8501_run_engine(struct lp55xx_chip *chip, bool start)
159{
160	int ret;
161	u8 mode;
162	u8 exec;
163
164	/* stop engine */
165	if (!start) {
166		lp8501_stop_engine(chip);
167		lp8501_turn_off_channels(chip);
168		return;
169	}
170
171	/*
172	 * To run the engine,
173	 * operation mode and enable register should updated at the same time
174	 */
175
176	ret = lp55xx_read(chip, LP8501_REG_OP_MODE, &mode);
177	if (ret)
178		return;
179
180	ret = lp55xx_read(chip, LP8501_REG_ENABLE, &exec);
181	if (ret)
182		return;
183
184	/* change operation mode to RUN only when each engine is loading */
185	if (LP8501_ENG1_IS_LOADING(mode)) {
186		mode = (mode & ~LP8501_MODE_ENG1_M) | LP8501_RUN_ENG1;
187		exec = (exec & ~LP8501_EXEC_ENG1_M) | LP8501_RUN_ENG1;
188	}
189
190	if (LP8501_ENG2_IS_LOADING(mode)) {
191		mode = (mode & ~LP8501_MODE_ENG2_M) | LP8501_RUN_ENG2;
192		exec = (exec & ~LP8501_EXEC_ENG2_M) | LP8501_RUN_ENG2;
193	}
194
195	if (LP8501_ENG3_IS_LOADING(mode)) {
196		mode = (mode & ~LP8501_MODE_ENG3_M) | LP8501_RUN_ENG3;
197		exec = (exec & ~LP8501_EXEC_ENG3_M) | LP8501_RUN_ENG3;
198	}
199
200	lp55xx_write(chip, LP8501_REG_OP_MODE, mode);
201	lp8501_wait_opmode_done();
202
203	lp55xx_update_bits(chip, LP8501_REG_ENABLE, LP8501_EXEC_M, exec);
204}
205
206static int lp8501_update_program_memory(struct lp55xx_chip *chip,
207					const u8 *data, size_t size)
208{
209	u8 pattern[LP8501_PROGRAM_LENGTH] = {0};
210	unsigned cmd;
211	char c[3];
212	int update_size;
213	int nrchars;
214	int offset = 0;
215	int ret;
216	int i;
217
218	/* clear program memory before updating */
219	for (i = 0; i < LP8501_PROGRAM_LENGTH; i++)
220		lp55xx_write(chip, LP8501_REG_PROG_MEM + i, 0);
221
222	i = 0;
223	while ((offset < size - 1) && (i < LP8501_PROGRAM_LENGTH)) {
224		/* separate sscanfs because length is working only for %s */
225		ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
226		if (ret != 1)
227			goto err;
228
229		ret = sscanf(c, "%2x", &cmd);
230		if (ret != 1)
231			goto err;
232
233		pattern[i] = (u8)cmd;
234		offset += nrchars;
235		i++;
236	}
237
238	/* Each instruction is 16bit long. Check that length is even */
239	if (i % 2)
240		goto err;
241
242	update_size = i;
243	for (i = 0; i < update_size; i++)
244		lp55xx_write(chip, LP8501_REG_PROG_MEM + i, pattern[i]);
245
246	return 0;
247
248err:
249	dev_err(&chip->cl->dev, "wrong pattern format\n");
250	return -EINVAL;
251}
252
253static void lp8501_firmware_loaded(struct lp55xx_chip *chip)
254{
255	const struct firmware *fw = chip->fw;
256
257	if (fw->size > LP8501_PROGRAM_LENGTH) {
258		dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
259			fw->size);
260		return;
261	}
262
263	/*
264	 * Program memory sequence
265	 *  1) set engine mode to "LOAD"
266	 *  2) write firmware data into program memory
267	 */
268
269	lp8501_load_engine(chip);
270	lp8501_update_program_memory(chip, fw->data, fw->size);
271}
272
273static int lp8501_led_brightness(struct lp55xx_led *led)
274{
275	struct lp55xx_chip *chip = led->chip;
276	int ret;
277
278	mutex_lock(&chip->lock);
279	ret = lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + led->chan_nr,
280		     led->brightness);
281	mutex_unlock(&chip->lock);
282
283	return ret;
284}
285
286/* Chip specific configurations */
287static struct lp55xx_device_config lp8501_cfg = {
288	.reset = {
289		.addr = LP8501_REG_RESET,
290		.val  = LP8501_RESET,
291	},
292	.enable = {
293		.addr = LP8501_REG_ENABLE,
294		.val  = LP8501_ENABLE,
295	},
296	.max_channel  = LP8501_MAX_LEDS,
297	.post_init_device   = lp8501_post_init_device,
298	.brightness_fn      = lp8501_led_brightness,
299	.set_led_current    = lp8501_set_led_current,
300	.firmware_cb        = lp8501_firmware_loaded,
301	.run_engine         = lp8501_run_engine,
302};
303
304static int lp8501_probe(struct i2c_client *client)
305{
306	const struct i2c_device_id *id = i2c_client_get_device_id(client);
307	int ret;
308	struct lp55xx_chip *chip;
309	struct lp55xx_led *led;
310	struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
311	struct device_node *np = dev_of_node(&client->dev);
312
313	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
314	if (!chip)
315		return -ENOMEM;
316
317	chip->cfg = &lp8501_cfg;
318
319	if (!pdata) {
320		if (np) {
321			pdata = lp55xx_of_populate_pdata(&client->dev, np,
322							 chip);
323			if (IS_ERR(pdata))
324				return PTR_ERR(pdata);
325		} else {
326			dev_err(&client->dev, "no platform data\n");
327			return -EINVAL;
328		}
329	}
330
331	led = devm_kcalloc(&client->dev,
332			pdata->num_channels, sizeof(*led), GFP_KERNEL);
333	if (!led)
334		return -ENOMEM;
335
336	chip->cl = client;
337	chip->pdata = pdata;
338
339	mutex_init(&chip->lock);
340
341	i2c_set_clientdata(client, led);
342
343	ret = lp55xx_init_device(chip);
344	if (ret)
345		goto err_init;
346
347	dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
348
349	ret = lp55xx_register_leds(led, chip);
350	if (ret)
351		goto err_out;
352
353	ret = lp55xx_register_sysfs(chip);
354	if (ret) {
355		dev_err(&client->dev, "registering sysfs failed\n");
356		goto err_out;
357	}
358
359	return 0;
360
361err_out:
362	lp55xx_deinit_device(chip);
363err_init:
364	return ret;
365}
366
367static void lp8501_remove(struct i2c_client *client)
368{
369	struct lp55xx_led *led = i2c_get_clientdata(client);
370	struct lp55xx_chip *chip = led->chip;
371
372	lp8501_stop_engine(chip);
373	lp55xx_unregister_sysfs(chip);
374	lp55xx_deinit_device(chip);
375}
376
377static const struct i2c_device_id lp8501_id[] = {
378	{ "lp8501",  0 },
379	{ }
380};
381MODULE_DEVICE_TABLE(i2c, lp8501_id);
382
383static const struct of_device_id of_lp8501_leds_match[] = {
384	{ .compatible = "ti,lp8501", },
385	{},
386};
387
388MODULE_DEVICE_TABLE(of, of_lp8501_leds_match);
389
390static struct i2c_driver lp8501_driver = {
391	.driver = {
392		.name	= "lp8501",
393		.of_match_table = of_lp8501_leds_match,
394	},
395	.probe		= lp8501_probe,
396	.remove		= lp8501_remove,
397	.id_table	= lp8501_id,
398};
399
400module_i2c_driver(lp8501_driver);
401
402MODULE_DESCRIPTION("Texas Instruments LP8501 LED driver");
403MODULE_AUTHOR("Milo Kim");
404MODULE_LICENSE("GPL");
405