File Index
Files and directories
Sign in
FILE

leds-st1202.c

File preview with syntax highlighting.

linux-6.19.14/drivers/leds/leds-st1202.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * LED driver for STMicroelectronics LED1202 chip
  4 *
  5 * Copyright (C) 2024 Remote-Tech Ltd. UK
  6 */
  7
  8#include <linux/cleanup.h>
  9#include <linux/ctype.h>
 10#include <linux/delay.h>
 11#include <linux/err.h>
 12#include <linux/gpio.h>
 13#include <linux/i2c.h>
 14#include <linux/leds.h>
 15#include <linux/module.h>
 16#include <linux/slab.h>
 17#include <linux/string.h>
 18
 19#define ST1202_CHAN_DISABLE_ALL            0x00
 20#define ST1202_CHAN_ENABLE_HIGH            0x03
 21#define ST1202_CHAN_ENABLE_LOW             0x02
 22#define ST1202_CONFIG_REG                  0x04
 23/* PATS: Pattern sequence feature enable */
 24#define ST1202_CONFIG_REG_PATS             BIT(7)
 25/* PATSR: Pattern sequence runs (self-clear when sequence is finished) */
 26#define ST1202_CONFIG_REG_PATSR            BIT(6)
 27#define ST1202_CONFIG_REG_SHFT             BIT(3)
 28#define ST1202_DEV_ENABLE                  0x01
 29#define ST1202_DEV_ENABLE_ON               BIT(0)
 30#define ST1202_DEV_ENABLE_RESET            BIT(7)
 31#define ST1202_DEVICE_ID                   0x00
 32#define ST1202_ILED_REG0                   0x09
 33#define ST1202_MAX_LEDS                    12
 34#define ST1202_MAX_PATTERNS                8
 35#define ST1202_MILLIS_PATTERN_DUR_MAX      5660
 36#define ST1202_MILLIS_PATTERN_DUR_MIN      22
 37#define ST1202_PATTERN_DUR                 0x16
 38#define ST1202_PATTERN_PWM                 0x1E
 39#define ST1202_PATTERN_REP                 0x15
 40
 41struct st1202_led {
 42	struct fwnode_handle *fwnode;
 43	struct led_classdev led_cdev;
 44	struct st1202_chip *chip;
 45	bool is_active;
 46	int led_num;
 47};
 48
 49struct st1202_chip {
 50	struct i2c_client *client;
 51	struct mutex lock;
 52	struct st1202_led leds[ST1202_MAX_LEDS];
 53};
 54
 55static struct st1202_led *cdev_to_st1202_led(struct led_classdev *cdev)
 56{
 57	return container_of(cdev, struct st1202_led, led_cdev);
 58}
 59
 60static int st1202_read_reg(struct st1202_chip *chip, int reg, uint8_t *val)
 61{
 62	struct device *dev = &chip->client->dev;
 63	int ret;
 64
 65	ret = i2c_smbus_read_byte_data(chip->client, reg);
 66	if (ret < 0) {
 67		dev_err(dev, "Failed to read register [0x%x]: %d\n", reg, ret);
 68		return ret;
 69	}
 70
 71	*val = (uint8_t)ret;
 72	return 0;
 73}
 74
 75static int st1202_write_reg(struct st1202_chip *chip, int reg, uint8_t val)
 76{
 77	struct device *dev = &chip->client->dev;
 78	int ret;
 79
 80	ret = i2c_smbus_write_byte_data(chip->client, reg, val);
 81	if (ret != 0)
 82		dev_err(dev, "Failed to write %d to register [0x%x]: %d\n", val, reg, ret);
 83
 84	return ret;
 85}
 86
 87static uint8_t st1202_prescalar_to_miliseconds(unsigned int value)
 88{
 89	return value / ST1202_MILLIS_PATTERN_DUR_MIN - 1;
 90}
 91
 92static int st1202_pwm_pattern_write(struct st1202_chip *chip, int led_num,
 93				int pattern, unsigned int value)
 94{
 95	u8 value_l, value_h;
 96	int ret;
 97
 98	value_l = (u8)value;
 99	value_h = (u8)(value >> 8);
100
101	/*
102	 * Datasheet: Register address low = 1Eh + 2*(xh) + 18h*(yh),
103	 * where x is the channel number (led number) in hexadecimal (x = 00h .. 0Bh)
104	 * and y is the pattern number in hexadecimal (y = 00h .. 07h)
105	 */
106	ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + (led_num * 2) + 0x18 * pattern),
107				value_l);
108	if (ret != 0)
109		return ret;
110
111	/*
112	 * Datasheet: Register address high = 1Eh + 01h + 2(xh) +18h*(yh),
113	 * where x is the channel number in hexadecimal (x = 00h .. 0Bh)
114	 * and y is the pattern number in hexadecimal (y = 00h .. 07h)
115	 */
116	ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + 0x1 + (led_num * 2) + 0x18 * pattern),
117				value_h);
118	if (ret != 0)
119		return ret;
120
121	return 0;
122}
123
124static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern,
125					unsigned int value)
126{
127	return st1202_write_reg(chip, (ST1202_PATTERN_DUR + pattern),
128				st1202_prescalar_to_miliseconds(value));
129}
130
131static void st1202_brightness_set(struct led_classdev *led_cdev,
132				enum led_brightness value)
133{
134	struct st1202_led *led = cdev_to_st1202_led(led_cdev);
135	struct st1202_chip *chip = led->chip;
136
137	guard(mutex)(&chip->lock);
138
139	st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
140}
141
142static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
143{
144	struct st1202_led *led = cdev_to_st1202_led(led_cdev);
145	struct st1202_chip *chip = led->chip;
146	u8 value = 0;
147
148	guard(mutex)(&chip->lock);
149
150	st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
151
152	return value;
153}
154
155static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
156{
157	u8 chan_low, chan_high;
158	int ret;
159
160	guard(mutex)(&chip->lock);
161
162	if (led_num <= 7) {
163		ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low);
164		if (ret < 0)
165			return ret;
166
167		chan_low = active ? chan_low | BIT(led_num) : chan_low & ~BIT(led_num);
168
169		ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, chan_low);
170		if (ret < 0)
171			return ret;
172
173	} else {
174		ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_HIGH, &chan_high);
175		if (ret < 0)
176			return ret;
177
178		chan_high = active ? chan_high | (BIT(led_num) >> 8) :
179					chan_high & ~(BIT(led_num) >> 8);
180
181		ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, chan_high);
182		if (ret < 0)
183			return ret;
184	}
185
186	return 0;
187}
188
189static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value)
190{
191	struct st1202_led *led = cdev_to_st1202_led(ldev);
192
193	return st1202_channel_set(led->chip, led->led_num, !!value);
194}
195
196static int st1202_led_pattern_clear(struct led_classdev *ldev)
197{
198	struct st1202_led *led = cdev_to_st1202_led(ldev);
199	struct st1202_chip *chip = led->chip;
200	int ret;
201
202	guard(mutex)(&chip->lock);
203
204	for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) {
205		ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF);
206		if (ret != 0)
207			return ret;
208
209		ret = st1202_duration_pattern_write(chip, patt, ST1202_MILLIS_PATTERN_DUR_MIN);
210		if (ret != 0)
211			return ret;
212	}
213
214	return 0;
215}
216
217static int st1202_led_pattern_set(struct led_classdev *ldev,
218				struct led_pattern *pattern,
219				u32 len, int repeat)
220{
221	struct st1202_led *led = cdev_to_st1202_led(ldev);
222	struct st1202_chip *chip = led->chip;
223	int ret;
224
225	if (len > ST1202_MAX_PATTERNS)
226		return -EINVAL;
227
228	guard(mutex)(&chip->lock);
229
230	for (int patt = 0; patt < len; patt++) {
231		if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN ||
232				pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)
233			return -EINVAL;
234
235		ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness);
236		if (ret != 0)
237			return ret;
238
239		ret = st1202_duration_pattern_write(chip, patt, pattern[patt].delta_t);
240		if (ret != 0)
241			return ret;
242	}
243
244	ret = st1202_write_reg(chip, ST1202_PATTERN_REP, repeat);
245	if (ret != 0)
246		return ret;
247
248	ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR |
249							ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT));
250	if (ret != 0)
251		return ret;
252
253	return 0;
254}
255
256static int st1202_dt_init(struct st1202_chip *chip)
257{
258	struct device *dev = &chip->client->dev;
259	struct st1202_led *led;
260	int err, reg;
261
262	for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
263		err = of_property_read_u32(child, "reg", &reg);
264		if (err)
265			return dev_err_probe(dev, err, "Invalid register\n");
266
267		led = &chip->leds[reg];
268		led->is_active = true;
269		led->fwnode = of_fwnode_handle(child);
270
271		led->led_cdev.max_brightness = U8_MAX;
272		led->led_cdev.brightness_set_blocking = st1202_led_set;
273		led->led_cdev.pattern_set = st1202_led_pattern_set;
274		led->led_cdev.pattern_clear = st1202_led_pattern_clear;
275		led->led_cdev.default_trigger = "pattern";
276		led->led_cdev.brightness_set = st1202_brightness_set;
277		led->led_cdev.brightness_get = st1202_brightness_get;
278	}
279
280	return 0;
281}
282
283static int st1202_setup(struct st1202_chip *chip)
284{
285	int ret;
286
287	guard(mutex)(&chip->lock);
288
289	/*
290	 * Once the supply voltage is applied, the LED1202 executes some internal checks.
291	 * Afterwards, it stops the oscillator and puts the internal LDO in quiescent mode.
292	 * To start the device, EN bit must be set inside the “Device Enable” register at
293	 * address 01h. As soon as EN is set, the LED1202 loads the adjustment parameters
294	 * from the internal non-volatile memory and performs an auto-calibration procedure
295	 * in order to increase the output current precision.
296	 * Such initialization lasts about 6.5 ms.
297	 */
298
299	/* Reset the chip during setup */
300	ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_RESET);
301	if (ret < 0)
302		return ret;
303
304	/* Enable phase-shift delay feature */
305	ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
306	if (ret < 0)
307		return ret;
308
309	/* Enable the device */
310	ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_ON);
311	if (ret < 0)
312		return ret;
313
314	/* Duration of initialization */
315	usleep_range(6500, 10000);
316
317	/* Deactivate all LEDS (channels) and activate only the ones found in Device Tree */
318	ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, ST1202_CHAN_DISABLE_ALL);
319	if (ret < 0)
320		return ret;
321
322	ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, ST1202_CHAN_DISABLE_ALL);
323	if (ret < 0)
324		return ret;
325
326	ret = st1202_write_reg(chip, ST1202_CONFIG_REG,
327				ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_PATSR);
328	if (ret < 0)
329		return ret;
330
331	return 0;
332}
333
334static int st1202_probe(struct i2c_client *client)
335{
336	struct st1202_chip *chip;
337	struct st1202_led *led;
338	int ret;
339
340	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
341		return dev_err_probe(&client->dev, -EIO, "SMBUS Byte Data not Supported\n");
342
343	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
344	if (!chip)
345		return -ENOMEM;
346
347	ret = devm_mutex_init(&client->dev, &chip->lock);
348	if (ret < 0)
349		return ret;
350	chip->client = client;
351
352	ret = st1202_setup(chip);
353	if (ret < 0)
354		return ret;
355
356	ret = st1202_dt_init(chip);
357	if (ret < 0)
358		return ret;
359
360	for (int i = 0; i < ST1202_MAX_LEDS; i++) {
361		struct led_init_data init_data = {};
362		led = &chip->leds[i];
363		led->chip = chip;
364		led->led_num = i;
365
366		if (!led->is_active)
367			continue;
368
369		ret = st1202_channel_set(led->chip, led->led_num, true);
370		if (ret < 0)
371			return dev_err_probe(&client->dev, ret,
372					"Failed to activate LED channel\n");
373
374		ret = st1202_led_pattern_clear(&led->led_cdev);
375		if (ret < 0)
376			return dev_err_probe(&client->dev, ret,
377					"Failed to clear LED pattern\n");
378
379		init_data.fwnode = led->fwnode;
380		init_data.devicename = "st1202";
381		init_data.default_label = ":";
382
383		ret = devm_led_classdev_register_ext(&client->dev, &led->led_cdev, &init_data);
384		if (ret < 0)
385			return dev_err_probe(&client->dev, ret,
386					"Failed to register LED class device\n");
387	}
388
389	return 0;
390}
391
392static const struct i2c_device_id st1202_id[] = {
393	{ "st1202-i2c" },
394	{ /* sentinel */ }
395};
396MODULE_DEVICE_TABLE(i2c, st1202_id);
397
398static const struct of_device_id st1202_dt_ids[] = {
399	{ .compatible = "st,led1202" },
400	{ /* sentinel */ }
401};
402MODULE_DEVICE_TABLE(of, st1202_dt_ids);
403
404static struct i2c_driver st1202_driver = {
405	.driver = {
406		.name = "leds-st1202",
407		.of_match_table = of_match_ptr(st1202_dt_ids),
408	},
409	.probe = st1202_probe,
410	.id_table = st1202_id,
411};
412module_i2c_driver(st1202_driver);
413
414MODULE_AUTHOR("Remote Tech LTD");
415MODULE_DESCRIPTION("STMicroelectronics LED1202 : 12-channel constant current LED driver");
416MODULE_LICENSE("GPL");
~/ Read-only file preview.