brintos

brintos / linux-shallow public Read only

0
0
Text · 33.2 KiB · 5a2e259 Raw
1355 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * LP5521/LP5523/LP55231/LP5562 Common Driver4 *5 * Copyright 2012 Texas Instruments6 *7 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>8 *9 * Derived from leds-lp5521.c, leds-lp5523.c10 */11 12#include <linux/bitfield.h>13#include <linux/cleanup.h>14#include <linux/clk.h>15#include <linux/delay.h>16#include <linux/firmware.h>17#include <linux/i2c.h>18#include <linux/iopoll.h>19#include <linux/leds.h>20#include <linux/module.h>21#include <linux/platform_data/leds-lp55xx.h>22#include <linux/slab.h>23#include <linux/gpio/consumer.h>24#include <dt-bindings/leds/leds-lp55xx.h>25 26#include "leds-lp55xx-common.h"27 28/* OP MODE require at least 153 us to clear regs */29#define LP55XX_CMD_SLEEP		20030 31#define LP55xx_PROGRAM_PAGES		1632#define LP55xx_MAX_PROGRAM_LENGTH	(LP55xx_BYTES_PER_PAGE * 4) /* 128 bytes (4 pages) */33 34/*35 * Program Memory Operations36 * Same Mask for each engine for both mode and exec37 * ENG1        GENMASK(3, 2)38 * ENG2        GENMASK(5, 4)39 * ENG3        GENMASK(7, 6)40 */41#define LP55xx_MODE_DISABLE_ALL_ENG	0x042#define LP55xx_MODE_ENG_MASK           GENMASK(1, 0)43#define   LP55xx_MODE_DISABLE_ENG      FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x0)44#define   LP55xx_MODE_LOAD_ENG         FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x1)45#define   LP55xx_MODE_RUN_ENG          FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x2)46#define   LP55xx_MODE_HALT_ENG         FIELD_PREP_CONST(LP55xx_MODE_ENG_MASK, 0x3)47 48#define   LP55xx_MODE_ENGn_SHIFT(n, shift)	((shift) + (2 * (3 - (n))))49#define   LP55xx_MODE_ENGn_MASK(n, shift)     (LP55xx_MODE_ENG_MASK << LP55xx_MODE_ENGn_SHIFT(n, shift))50#define   LP55xx_MODE_ENGn_GET(n, mode, shift)        \51	(((mode) >> LP55xx_MODE_ENGn_SHIFT(n, shift)) & LP55xx_MODE_ENG_MASK)52 53#define   LP55xx_EXEC_ENG_MASK         GENMASK(1, 0)54#define   LP55xx_EXEC_HOLD_ENG         FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x0)55#define   LP55xx_EXEC_STEP_ENG         FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x1)56#define   LP55xx_EXEC_RUN_ENG          FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x2)57#define   LP55xx_EXEC_ONCE_ENG         FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x3)58 59#define   LP55xx_EXEC_ENGn_SHIFT(n, shift)    ((shift) + (2 * (3 - (n))))60#define   LP55xx_EXEC_ENGn_MASK(n, shift)     (LP55xx_EXEC_ENG_MASK << LP55xx_EXEC_ENGn_SHIFT(n, shift))61 62/* Memory Page Selection */63#define LP55xx_REG_PROG_PAGE_SEL	0x4f64/* If supported, each ENGINE have an equal amount of pages offset from page 0 */65#define LP55xx_PAGE_OFFSET(n, pages)	(((n) - 1) * (pages))66 67#define LED_ACTIVE(mux, led)		(!!((mux) & (0x0001 << (led))))68 69/* MASTER FADER common property */70#define LP55xx_FADER_MAPPING_MASK	GENMASK(7, 6)71 72/* External clock rate */73#define LP55XX_CLK_32K			3276874 75static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)76{77	return container_of(cdev, struct lp55xx_led, cdev);78}79 80static struct lp55xx_led *dev_to_lp55xx_led(struct device *dev)81{82	return cdev_to_lp55xx_led(dev_get_drvdata(dev));83}84 85static struct lp55xx_led *mcled_cdev_to_led(struct led_classdev_mc *mc_cdev)86{87	return container_of(mc_cdev, struct lp55xx_led, mc_cdev);88}89 90static void lp55xx_wait_opmode_done(struct lp55xx_chip *chip)91{92	const struct lp55xx_device_config *cfg = chip->cfg;93	int __always_unused ret;94	u8 val;95 96	/*97	 * Recent chip supports BUSY bit for engine.98	 * Check support by checking if val is not 0.99	 * For legacy device, sleep at least 153 us.100	 */101	if (cfg->engine_busy.val) {102		read_poll_timeout(lp55xx_read, ret, !(val & cfg->engine_busy.mask),103				  LP55XX_CMD_SLEEP, LP55XX_CMD_SLEEP * 10, false,104				  chip, cfg->engine_busy.addr, &val);105	} else {106		usleep_range(LP55XX_CMD_SLEEP, LP55XX_CMD_SLEEP * 2);107	}108}109 110void lp55xx_stop_all_engine(struct lp55xx_chip *chip)111{112	const struct lp55xx_device_config *cfg = chip->cfg;113 114	lp55xx_write(chip, cfg->reg_op_mode.addr, LP55xx_MODE_DISABLE_ALL_ENG);115	lp55xx_wait_opmode_done(chip);116}117EXPORT_SYMBOL_GPL(lp55xx_stop_all_engine);118 119void lp55xx_load_engine(struct lp55xx_chip *chip)120{121	enum lp55xx_engine_index idx = chip->engine_idx;122	const struct lp55xx_device_config *cfg = chip->cfg;123	u8 mask, val;124 125	mask = LP55xx_MODE_ENGn_MASK(idx, cfg->reg_op_mode.shift);126	val = LP55xx_MODE_LOAD_ENG << LP55xx_MODE_ENGn_SHIFT(idx, cfg->reg_op_mode.shift);127 128	lp55xx_update_bits(chip, cfg->reg_op_mode.addr, mask, val);129	lp55xx_wait_opmode_done(chip);130 131	/* Setup PAGE if supported (pages_per_engine not 0)*/132	if (cfg->pages_per_engine)133		lp55xx_write(chip, LP55xx_REG_PROG_PAGE_SEL,134			     LP55xx_PAGE_OFFSET(idx, cfg->pages_per_engine));135}136EXPORT_SYMBOL_GPL(lp55xx_load_engine);137 138int lp55xx_run_engine_common(struct lp55xx_chip *chip)139{140	const struct lp55xx_device_config *cfg = chip->cfg;141	u8 mode, exec;142	int i, ret;143 144	/* To run the engine, both OP MODE and EXEC needs to be put in RUN mode */145	ret = lp55xx_read(chip, cfg->reg_op_mode.addr, &mode);146	if (ret)147		return ret;148 149	ret = lp55xx_read(chip, cfg->reg_exec.addr, &exec);150	if (ret)151		return ret;152 153	/* Switch to RUN only for engine that were put in LOAD previously */154	for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {155		if (LP55xx_MODE_ENGn_GET(i, mode, cfg->reg_op_mode.shift) != LP55xx_MODE_LOAD_ENG)156			continue;157 158		mode &= ~LP55xx_MODE_ENGn_MASK(i, cfg->reg_op_mode.shift);159		mode |= LP55xx_MODE_RUN_ENG << LP55xx_MODE_ENGn_SHIFT(i, cfg->reg_op_mode.shift);160		exec &= ~LP55xx_EXEC_ENGn_MASK(i, cfg->reg_exec.shift);161		exec |= LP55xx_EXEC_RUN_ENG << LP55xx_EXEC_ENGn_SHIFT(i, cfg->reg_exec.shift);162	}163 164	lp55xx_write(chip, cfg->reg_op_mode.addr, mode);165	lp55xx_wait_opmode_done(chip);166	lp55xx_write(chip, cfg->reg_exec.addr, exec);167 168	return 0;169}170EXPORT_SYMBOL_GPL(lp55xx_run_engine_common);171 172int lp55xx_update_program_memory(struct lp55xx_chip *chip,173				 const u8 *data, size_t size)174{175	enum lp55xx_engine_index idx = chip->engine_idx;176	const struct lp55xx_device_config *cfg = chip->cfg;177	u8 pattern[LP55xx_MAX_PROGRAM_LENGTH] = { };178	u8 start_addr = cfg->prog_mem_base.addr;179	int page, i = 0, offset = 0;180	int program_length, ret;181 182	program_length = LP55xx_BYTES_PER_PAGE;183	if (cfg->pages_per_engine)184		program_length *= cfg->pages_per_engine;185 186	while ((offset < size - 1) && (i < program_length)) {187		unsigned int cmd;188		int nrchars;189		char c[3];190 191		/* separate sscanfs because length is working only for %s */192		ret = sscanf(data + offset, "%2s%n ", c, &nrchars);193		if (ret != 1)194			goto err;195 196		ret = sscanf(c, "%2x", &cmd);197		if (ret != 1)198			goto err;199 200		pattern[i] = (u8)cmd;201		offset += nrchars;202		i++;203	}204 205	/* Each instruction is 16bit long. Check that length is even */206	if (i % 2)207		goto err;208 209	/*210	 * For legacy LED chip with no page support, engine base address are211	 * one after another at offset of 32.212	 * For LED chip that support page, PAGE is already set in load_engine.213	 */214	if (!cfg->pages_per_engine)215		start_addr += LP55xx_BYTES_PER_PAGE * idx;216 217	for (page = 0; page < program_length / LP55xx_BYTES_PER_PAGE; page++) {218		/* Write to the next page each 32 bytes (if supported) */219		if (cfg->pages_per_engine)220			lp55xx_write(chip, LP55xx_REG_PROG_PAGE_SEL,221				     LP55xx_PAGE_OFFSET(idx, cfg->pages_per_engine) + page);222 223		for (i = 0; i < LP55xx_BYTES_PER_PAGE; i++) {224			ret = lp55xx_write(chip, start_addr + i,225					   pattern[i + (page * LP55xx_BYTES_PER_PAGE)]);226			if (ret)227				return -EINVAL;228		}229	}230 231	return size;232 233err:234	dev_err(&chip->cl->dev, "wrong pattern format\n");235	return -EINVAL;236}237EXPORT_SYMBOL_GPL(lp55xx_update_program_memory);238 239void lp55xx_firmware_loaded_cb(struct lp55xx_chip *chip)240{241	const struct lp55xx_device_config *cfg = chip->cfg;242	const struct firmware *fw = chip->fw;243	int program_length;244 245	program_length = LP55xx_BYTES_PER_PAGE;246	if (cfg->pages_per_engine)247		program_length *= cfg->pages_per_engine;248 249	/*250	 * the firmware is encoded in ascii hex character, with 2 chars251	 * per byte252	 */253	if (fw->size > program_length * 2) {254		dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",255			fw->size);256		return;257	}258 259	/*260	 * Program memory sequence261	 *  1) set engine mode to "LOAD"262	 *  2) write firmware data into program memory263	 */264 265	lp55xx_load_engine(chip);266	lp55xx_update_program_memory(chip, fw->data, fw->size);267}268EXPORT_SYMBOL_GPL(lp55xx_firmware_loaded_cb);269 270int lp55xx_led_brightness(struct lp55xx_led *led)271{272	struct lp55xx_chip *chip = led->chip;273	const struct lp55xx_device_config *cfg = chip->cfg;274	int ret;275 276	guard(mutex)(&chip->lock);277 278	ret = lp55xx_write(chip, cfg->reg_led_pwm_base.addr + led->chan_nr,279			   led->brightness);280	return ret;281}282EXPORT_SYMBOL_GPL(lp55xx_led_brightness);283 284int lp55xx_multicolor_brightness(struct lp55xx_led *led)285{286	struct lp55xx_chip *chip = led->chip;287	const struct lp55xx_device_config *cfg = chip->cfg;288	int ret;289	int i;290 291	guard(mutex)(&chip->lock);292 293	for (i = 0; i < led->mc_cdev.num_colors; i++) {294		ret = lp55xx_write(chip,295				   cfg->reg_led_pwm_base.addr +296				   led->mc_cdev.subled_info[i].channel,297				   led->mc_cdev.subled_info[i].brightness);298		if (ret)299			break;300	}301 302	return ret;303}304EXPORT_SYMBOL_GPL(lp55xx_multicolor_brightness);305 306void lp55xx_set_led_current(struct lp55xx_led *led, u8 led_current)307{308	struct lp55xx_chip *chip = led->chip;309	const struct lp55xx_device_config *cfg = chip->cfg;310 311	led->led_current = led_current;312	lp55xx_write(led->chip, cfg->reg_led_current_base.addr + led->chan_nr,313		     led_current);314}315EXPORT_SYMBOL_GPL(lp55xx_set_led_current);316 317void lp55xx_turn_off_channels(struct lp55xx_chip *chip)318{319	const struct lp55xx_device_config *cfg = chip->cfg;320	int i;321 322	for (i = 0; i < cfg->max_channel; i++)323		lp55xx_write(chip, cfg->reg_led_pwm_base.addr + i, 0);324}325EXPORT_SYMBOL_GPL(lp55xx_turn_off_channels);326 327void lp55xx_stop_engine(struct lp55xx_chip *chip)328{329	enum lp55xx_engine_index idx = chip->engine_idx;330	const struct lp55xx_device_config *cfg = chip->cfg;331	u8 mask;332 333	mask = LP55xx_MODE_ENGn_MASK(idx, cfg->reg_op_mode.shift);334	lp55xx_update_bits(chip, cfg->reg_op_mode.addr, mask, 0);335 336	lp55xx_wait_opmode_done(chip);337}338EXPORT_SYMBOL_GPL(lp55xx_stop_engine);339 340static void lp55xx_reset_device(struct lp55xx_chip *chip)341{342	const struct lp55xx_device_config *cfg = chip->cfg;343	u8 addr = cfg->reset.addr;344	u8 val  = cfg->reset.val;345 346	/* no error checking here because no ACK from the device after reset */347	lp55xx_write(chip, addr, val);348}349 350static int lp55xx_detect_device(struct lp55xx_chip *chip)351{352	const struct lp55xx_device_config *cfg = chip->cfg;353	u8 addr = cfg->enable.addr;354	u8 val  = cfg->enable.val;355	int ret;356 357	ret = lp55xx_write(chip, addr, val);358	if (ret)359		return ret;360 361	usleep_range(1000, 2000);362 363	ret = lp55xx_read(chip, addr, &val);364	if (ret)365		return ret;366 367	if (val != cfg->enable.val)368		return -ENODEV;369 370	return 0;371}372 373static int lp55xx_post_init_device(struct lp55xx_chip *chip)374{375	const struct lp55xx_device_config *cfg = chip->cfg;376 377	if (!cfg->post_init_device)378		return 0;379 380	return cfg->post_init_device(chip);381}382 383static ssize_t led_current_show(struct device *dev,384			    struct device_attribute *attr,385			    char *buf)386{387	struct lp55xx_led *led = dev_to_lp55xx_led(dev);388 389	return sysfs_emit(buf, "%d\n", led->led_current);390}391 392static ssize_t led_current_store(struct device *dev,393			     struct device_attribute *attr,394			     const char *buf, size_t len)395{396	struct lp55xx_led *led = dev_to_lp55xx_led(dev);397	struct lp55xx_chip *chip = led->chip;398	unsigned long curr;399 400	if (kstrtoul(buf, 0, &curr))401		return -EINVAL;402 403	if (curr > led->max_current)404		return -EINVAL;405 406	if (!chip->cfg->set_led_current)407		return len;408 409	guard(mutex)(&chip->lock);410 411	chip->cfg->set_led_current(led, (u8)curr);412 413	return len;414}415 416static ssize_t max_current_show(struct device *dev,417			    struct device_attribute *attr,418			    char *buf)419{420	struct lp55xx_led *led = dev_to_lp55xx_led(dev);421 422	return sysfs_emit(buf, "%d\n", led->max_current);423}424 425static DEVICE_ATTR_RW(led_current);426static DEVICE_ATTR_RO(max_current);427 428static struct attribute *lp55xx_led_attrs[] = {429	&dev_attr_led_current.attr,430	&dev_attr_max_current.attr,431	NULL,432};433ATTRIBUTE_GROUPS(lp55xx_led);434 435static int lp55xx_set_mc_brightness(struct led_classdev *cdev,436				    enum led_brightness brightness)437{438	struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev);439	struct lp55xx_led *led = mcled_cdev_to_led(mc_dev);440	const struct lp55xx_device_config *cfg = led->chip->cfg;441 442	led_mc_calc_color_components(&led->mc_cdev, brightness);443	return cfg->multicolor_brightness_fn(led);444 445}446 447static int lp55xx_set_brightness(struct led_classdev *cdev,448			     enum led_brightness brightness)449{450	struct lp55xx_led *led = cdev_to_lp55xx_led(cdev);451	const struct lp55xx_device_config *cfg = led->chip->cfg;452 453	led->brightness = (u8)brightness;454	return cfg->brightness_fn(led);455}456 457static int lp55xx_init_led(struct lp55xx_led *led,458			struct lp55xx_chip *chip, int chan)459{460	struct lp55xx_platform_data *pdata = chip->pdata;461	const struct lp55xx_device_config *cfg = chip->cfg;462	struct device *dev = &chip->cl->dev;463	int max_channel = cfg->max_channel;464	struct mc_subled *mc_led_info;465	struct led_classdev *led_cdev;466	char name[32];467	int i;468	int ret;469 470	if (chan >= max_channel) {471		dev_err(dev, "invalid channel: %d / %d\n", chan, max_channel);472		return -EINVAL;473	}474 475	if (pdata->led_config[chan].led_current == 0)476		return 0;477 478	if (pdata->led_config[chan].name) {479		led->cdev.name = pdata->led_config[chan].name;480	} else {481		snprintf(name, sizeof(name), "%s:channel%d",482			pdata->label ? : chip->cl->name, chan);483		led->cdev.name = name;484	}485 486	if (pdata->led_config[chan].num_colors > 1) {487		mc_led_info = devm_kcalloc(dev,488					   pdata->led_config[chan].num_colors,489					   sizeof(*mc_led_info), GFP_KERNEL);490		if (!mc_led_info)491			return -ENOMEM;492 493		led_cdev = &led->mc_cdev.led_cdev;494		led_cdev->name = led->cdev.name;495		led_cdev->brightness_set_blocking = lp55xx_set_mc_brightness;496		led->mc_cdev.num_colors = pdata->led_config[chan].num_colors;497		for (i = 0; i < led->mc_cdev.num_colors; i++) {498			mc_led_info[i].color_index =499				pdata->led_config[chan].color_id[i];500			mc_led_info[i].channel =501					pdata->led_config[chan].output_num[i];502		}503 504		led->mc_cdev.subled_info = mc_led_info;505	} else {506		led->cdev.brightness_set_blocking = lp55xx_set_brightness;507	}508 509	led->cdev.groups = lp55xx_led_groups;510	led->cdev.default_trigger = pdata->led_config[chan].default_trigger;511	led->led_current = pdata->led_config[chan].led_current;512	led->max_current = pdata->led_config[chan].max_current;513	led->chan_nr = pdata->led_config[chan].chan_nr;514 515	if (led->chan_nr >= max_channel) {516		dev_err(dev, "Use channel numbers between 0 and %d\n",517			max_channel - 1);518		return -EINVAL;519	}520 521	if (pdata->led_config[chan].num_colors > 1)522		ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev);523	else524		ret = devm_led_classdev_register(dev, &led->cdev);525 526	if (ret) {527		dev_err(dev, "led register err: %d\n", ret);528		return ret;529	}530 531	return 0;532}533 534static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)535{536	struct lp55xx_chip *chip = context;537	struct device *dev = &chip->cl->dev;538	enum lp55xx_engine_index idx = chip->engine_idx;539 540	if (!fw) {541		dev_err(dev, "firmware request failed\n");542		return;543	}544 545	/* handling firmware data is chip dependent */546	scoped_guard(mutex, &chip->lock) {547		chip->engines[idx - 1].mode = LP55XX_ENGINE_LOAD;548		chip->fw = fw;549		if (chip->cfg->firmware_cb)550			chip->cfg->firmware_cb(chip);551	}552 553	/* firmware should be released for other channel use */554	release_firmware(chip->fw);555	chip->fw = NULL;556}557 558static int lp55xx_request_firmware(struct lp55xx_chip *chip)559{560	const char *name = chip->cl->name;561	struct device *dev = &chip->cl->dev;562 563	return request_firmware_nowait(THIS_MODULE, false, name, dev,564				GFP_KERNEL, chip, lp55xx_firmware_loaded);565}566 567static ssize_t select_engine_show(struct device *dev,568				  struct device_attribute *attr,569				  char *buf)570{571	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));572	struct lp55xx_chip *chip = led->chip;573 574	return sprintf(buf, "%d\n", chip->engine_idx);575}576 577static ssize_t select_engine_store(struct device *dev,578				   struct device_attribute *attr,579				   const char *buf, size_t len)580{581	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));582	struct lp55xx_chip *chip = led->chip;583	unsigned long val;584	int ret;585 586	if (kstrtoul(buf, 0, &val))587		return -EINVAL;588 589	/* select the engine to be run */590 591	switch (val) {592	case LP55XX_ENGINE_1:593	case LP55XX_ENGINE_2:594	case LP55XX_ENGINE_3:595		scoped_guard(mutex, &chip->lock) {596			chip->engine_idx = val;597			ret = lp55xx_request_firmware(chip);598		}599		break;600	default:601		dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val);602		return -EINVAL;603	}604 605	if (ret) {606		dev_err(dev, "request firmware err: %d\n", ret);607		return ret;608	}609 610	return len;611}612 613static inline void lp55xx_run_engine(struct lp55xx_chip *chip, bool start)614{615	if (chip->cfg->run_engine)616		chip->cfg->run_engine(chip, start);617}618 619static ssize_t run_engine_store(struct device *dev,620				struct device_attribute *attr,621				const char *buf, size_t len)622{623	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));624	struct lp55xx_chip *chip = led->chip;625	unsigned long val;626 627	if (kstrtoul(buf, 0, &val))628		return -EINVAL;629 630	/* run or stop the selected engine */631 632	if (val <= 0) {633		lp55xx_run_engine(chip, false);634		return len;635	}636 637	guard(mutex)(&chip->lock);638 639	lp55xx_run_engine(chip, true);640 641	return len;642}643 644static DEVICE_ATTR_RW(select_engine);645static DEVICE_ATTR_WO(run_engine);646 647ssize_t lp55xx_show_engine_mode(struct device *dev,648				struct device_attribute *attr,649				char *buf, int nr)650{651	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));652	struct lp55xx_chip *chip = led->chip;653	enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode;654 655	switch (mode) {656	case LP55XX_ENGINE_RUN:657		return sysfs_emit(buf, "run\n");658	case LP55XX_ENGINE_LOAD:659		return sysfs_emit(buf, "load\n");660	case LP55XX_ENGINE_DISABLED:661	default:662		return sysfs_emit(buf, "disabled\n");663	}664}665EXPORT_SYMBOL_GPL(lp55xx_show_engine_mode);666 667ssize_t lp55xx_store_engine_mode(struct device *dev,668				 struct device_attribute *attr,669				 const char *buf, size_t len, int nr)670{671	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));672	struct lp55xx_chip *chip = led->chip;673	const struct lp55xx_device_config *cfg = chip->cfg;674	struct lp55xx_engine *engine = &chip->engines[nr - 1];675 676	guard(mutex)(&chip->lock);677 678	chip->engine_idx = nr;679 680	if (!strncmp(buf, "run", 3)) {681		cfg->run_engine(chip, true);682		engine->mode = LP55XX_ENGINE_RUN;683	} else if (!strncmp(buf, "load", 4)) {684		lp55xx_stop_engine(chip);685		lp55xx_load_engine(chip);686		engine->mode = LP55XX_ENGINE_LOAD;687	} else if (!strncmp(buf, "disabled", 8)) {688		lp55xx_stop_engine(chip);689		engine->mode = LP55XX_ENGINE_DISABLED;690	}691 692	return len;693}694EXPORT_SYMBOL_GPL(lp55xx_store_engine_mode);695 696ssize_t lp55xx_store_engine_load(struct device *dev,697				 struct device_attribute *attr,698				 const char *buf, size_t len, int nr)699{700	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));701	struct lp55xx_chip *chip = led->chip;702	int ret;703 704	guard(mutex)(&chip->lock);705 706	chip->engine_idx = nr;707	lp55xx_load_engine(chip);708	ret = lp55xx_update_program_memory(chip, buf, len);709 710	return ret;711}712EXPORT_SYMBOL_GPL(lp55xx_store_engine_load);713 714static int lp55xx_mux_parse(struct lp55xx_chip *chip, const char *buf,715			    u16 *mux, size_t len)716{717	const struct lp55xx_device_config *cfg = chip->cfg;718	u16 tmp_mux = 0;719	int i;720 721	len = min_t(int, len, cfg->max_channel);722 723	for (i = 0; i < len; i++) {724		switch (buf[i]) {725		case '1':726			tmp_mux |= (1 << i);727			break;728		case '0':729			break;730		case '\n':731			i = len;732			break;733		default:734			return -1;735		}736	}737	*mux = tmp_mux;738 739	return 0;740}741 742ssize_t lp55xx_show_engine_leds(struct device *dev,743				struct device_attribute *attr,744				char *buf, int nr)745{746	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));747	struct lp55xx_chip *chip = led->chip;748	const struct lp55xx_device_config *cfg = chip->cfg;749	unsigned int led_active;750	int i, pos = 0;751 752	for (i = 0; i < cfg->max_channel; i++) {753		led_active = LED_ACTIVE(chip->engines[nr - 1].led_mux, i);754		pos += sysfs_emit_at(buf, pos, "%x", led_active);755	}756 757	pos += sysfs_emit_at(buf, pos, "\n");758 759	return pos;760}761EXPORT_SYMBOL_GPL(lp55xx_show_engine_leds);762 763static int lp55xx_load_mux(struct lp55xx_chip *chip, u16 mux, int nr)764{765	struct lp55xx_engine *engine = &chip->engines[nr - 1];766	const struct lp55xx_device_config *cfg = chip->cfg;767	u8 mux_page;768	int ret;769 770	lp55xx_load_engine(chip);771 772	/* Derive the MUX page offset by starting at the end of the ENGINE pages */773	mux_page = cfg->pages_per_engine * LP55XX_ENGINE_MAX + (nr - 1);774	ret = lp55xx_write(chip, LP55xx_REG_PROG_PAGE_SEL, mux_page);775	if (ret)776		return ret;777 778	ret = lp55xx_write(chip, cfg->prog_mem_base.addr, (u8)(mux >> 8));779	if (ret)780		return ret;781 782	ret = lp55xx_write(chip, cfg->prog_mem_base.addr + 1, (u8)(mux));783	if (ret)784		return ret;785 786	engine->led_mux = mux;787	return 0;788}789 790ssize_t lp55xx_store_engine_leds(struct device *dev,791				 struct device_attribute *attr,792				 const char *buf, size_t len, int nr)793{794	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));795	struct lp55xx_chip *chip = led->chip;796	struct lp55xx_engine *engine = &chip->engines[nr - 1];797	u16 mux = 0;798 799	if (lp55xx_mux_parse(chip, buf, &mux, len))800		return -EINVAL;801 802	guard(mutex)(&chip->lock);803 804	chip->engine_idx = nr;805 806	if (engine->mode != LP55XX_ENGINE_LOAD)807		return -EINVAL;808 809	if (lp55xx_load_mux(chip, mux, nr))810		return -EINVAL;811 812	return len;813}814EXPORT_SYMBOL_GPL(lp55xx_store_engine_leds);815 816ssize_t lp55xx_show_master_fader(struct device *dev,817				 struct device_attribute *attr,818				 char *buf, int nr)819{820	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));821	struct lp55xx_chip *chip = led->chip;822	const struct lp55xx_device_config *cfg = chip->cfg;823	int ret;824	u8 val;825 826	guard(mutex)(&chip->lock);827 828	ret = lp55xx_read(chip, cfg->reg_master_fader_base.addr + nr - 1, &val);829 830	return ret ? ret : sysfs_emit(buf, "%u\n", val);831}832EXPORT_SYMBOL_GPL(lp55xx_show_master_fader);833 834ssize_t lp55xx_store_master_fader(struct device *dev,835				  struct device_attribute *attr,836				  const char *buf, size_t len, int nr)837{838	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));839	struct lp55xx_chip *chip = led->chip;840	const struct lp55xx_device_config *cfg = chip->cfg;841	int ret;842	unsigned long val;843 844	if (kstrtoul(buf, 0, &val))845		return -EINVAL;846 847	if (val > 0xff)848		return -EINVAL;849 850	guard(mutex)(&chip->lock);851 852	ret = lp55xx_write(chip, cfg->reg_master_fader_base.addr + nr - 1,853			   (u8)val);854 855	return ret ? ret : len;856}857EXPORT_SYMBOL_GPL(lp55xx_store_master_fader);858 859ssize_t lp55xx_show_master_fader_leds(struct device *dev,860				      struct device_attribute *attr,861				      char *buf)862{863	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));864	struct lp55xx_chip *chip = led->chip;865	const struct lp55xx_device_config *cfg = chip->cfg;866	int i, ret, pos = 0;867	u8 val;868 869	guard(mutex)(&chip->lock);870 871	for (i = 0; i < cfg->max_channel; i++) {872		ret = lp55xx_read(chip, cfg->reg_led_ctrl_base.addr + i, &val);873		if (ret)874			return ret;875 876		val = FIELD_GET(LP55xx_FADER_MAPPING_MASK, val);877		if (val > FIELD_MAX(LP55xx_FADER_MAPPING_MASK)) {878			return -EINVAL;879		}880		buf[pos++] = val + '0';881	}882	buf[pos++] = '\n';883 884	return pos;885}886EXPORT_SYMBOL_GPL(lp55xx_show_master_fader_leds);887 888ssize_t lp55xx_store_master_fader_leds(struct device *dev,889				       struct device_attribute *attr,890				       const char *buf, size_t len)891{892	struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));893	struct lp55xx_chip *chip = led->chip;894	const struct lp55xx_device_config *cfg = chip->cfg;895	int i, n, ret;896	u8 val;897 898	n = min_t(int, len, cfg->max_channel);899 900	guard(mutex)(&chip->lock);901 902	for (i = 0; i < n; i++) {903		if (buf[i] >= '0' && buf[i] <= '3') {904			val = (buf[i] - '0') << __bf_shf(LP55xx_FADER_MAPPING_MASK);905			ret = lp55xx_update_bits(chip,906						 cfg->reg_led_ctrl_base.addr + i,907						 LP55xx_FADER_MAPPING_MASK,908						 val);909			if (ret)910				return ret;911		} else {912			return -EINVAL;913		}914	}915 916	return len;917}918EXPORT_SYMBOL_GPL(lp55xx_store_master_fader_leds);919 920static struct attribute *lp55xx_engine_attributes[] = {921	&dev_attr_select_engine.attr,922	&dev_attr_run_engine.attr,923	NULL,924};925 926static const struct attribute_group lp55xx_engine_attr_group = {927	.attrs = lp55xx_engine_attributes,928};929 930int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val)931{932	return i2c_smbus_write_byte_data(chip->cl, reg, val);933}934EXPORT_SYMBOL_GPL(lp55xx_write);935 936int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val)937{938	s32 ret;939 940	ret = i2c_smbus_read_byte_data(chip->cl, reg);941	if (ret < 0)942		return ret;943 944	*val = ret;945	return 0;946}947EXPORT_SYMBOL_GPL(lp55xx_read);948 949int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val)950{951	int ret;952	u8 tmp;953 954	ret = lp55xx_read(chip, reg, &tmp);955	if (ret)956		return ret;957 958	tmp &= ~mask;959	tmp |= val & mask;960 961	return lp55xx_write(chip, reg, tmp);962}963EXPORT_SYMBOL_GPL(lp55xx_update_bits);964 965bool lp55xx_is_extclk_used(struct lp55xx_chip *chip)966{967	struct clk *clk;968 969	clk = devm_clk_get_enabled(&chip->cl->dev, "32k_clk");970	if (IS_ERR(clk))971		goto use_internal_clk;972 973	if (clk_get_rate(clk) != LP55XX_CLK_32K)974		goto use_internal_clk;975 976	dev_info(&chip->cl->dev, "%dHz external clock used\n",	LP55XX_CLK_32K);977 978	return true;979 980use_internal_clk:981	dev_info(&chip->cl->dev, "internal clock used\n");982	return false;983}984EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);985 986static void lp55xx_deinit_device(struct lp55xx_chip *chip)987{988	struct lp55xx_platform_data *pdata = chip->pdata;989 990	if (pdata->enable_gpiod)991		gpiod_set_value(pdata->enable_gpiod, 0);992}993 994static int lp55xx_init_device(struct lp55xx_chip *chip)995{996	struct lp55xx_platform_data *pdata;997	const struct lp55xx_device_config *cfg;998	struct device *dev = &chip->cl->dev;999	int ret = 0;1000 1001	WARN_ON(!chip);1002 1003	pdata = chip->pdata;1004	cfg = chip->cfg;1005 1006	if (!pdata || !cfg)1007		return -EINVAL;1008 1009	if (pdata->enable_gpiod) {1010		gpiod_direction_output(pdata->enable_gpiod, 0);1011 1012		gpiod_set_consumer_name(pdata->enable_gpiod, "LP55xx enable");1013		gpiod_set_value_cansleep(pdata->enable_gpiod, 0);1014		usleep_range(1000, 2000); /* Keep enable down at least 1ms */1015		gpiod_set_value_cansleep(pdata->enable_gpiod, 1);1016		usleep_range(1000, 2000); /* 500us abs min. */1017	}1018 1019	lp55xx_reset_device(chip);1020 1021	/*1022	 * Exact value is not available. 10 - 20ms1023	 * appears to be enough for reset.1024	 */1025	usleep_range(10000, 20000);1026 1027	ret = lp55xx_detect_device(chip);1028	if (ret) {1029		dev_err(dev, "device detection err: %d\n", ret);1030		goto err;1031	}1032 1033	/* chip specific initialization */1034	ret = lp55xx_post_init_device(chip);1035	if (ret) {1036		dev_err(dev, "post init device err: %d\n", ret);1037		goto err_post_init;1038	}1039 1040	return 0;1041 1042err_post_init:1043	lp55xx_deinit_device(chip);1044err:1045	return ret;1046}1047 1048static int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip)1049{1050	struct lp55xx_platform_data *pdata = chip->pdata;1051	const struct lp55xx_device_config *cfg = chip->cfg;1052	int num_channels = pdata->num_channels;1053	struct lp55xx_led *each;1054	u8 led_current;1055	int ret;1056	int i;1057 1058	if (!cfg->brightness_fn) {1059		dev_err(&chip->cl->dev, "empty brightness configuration\n");1060		return -EINVAL;1061	}1062 1063	for (i = 0; i < num_channels; i++) {1064 1065		/* do not initialize channels that are not connected */1066		if (pdata->led_config[i].led_current == 0)1067			continue;1068 1069		led_current = pdata->led_config[i].led_current;1070		each = led + i;1071		ret = lp55xx_init_led(each, chip, i);1072		if (ret)1073			goto err_init_led;1074 1075		chip->num_leds++;1076		each->chip = chip;1077 1078		/* setting led current at each channel */1079		if (cfg->set_led_current)1080			cfg->set_led_current(each, led_current);1081	}1082 1083	return 0;1084 1085err_init_led:1086	return ret;1087}1088 1089static int lp55xx_register_sysfs(struct lp55xx_chip *chip)1090{1091	struct device *dev = &chip->cl->dev;1092	const struct lp55xx_device_config *cfg = chip->cfg;1093	int ret;1094 1095	if (!cfg->run_engine || !cfg->firmware_cb)1096		goto dev_specific_attrs;1097 1098	ret = sysfs_create_group(&dev->kobj, &lp55xx_engine_attr_group);1099	if (ret)1100		return ret;1101 1102dev_specific_attrs:1103	return cfg->dev_attr_group ?1104		sysfs_create_group(&dev->kobj, cfg->dev_attr_group) : 0;1105}1106 1107static void lp55xx_unregister_sysfs(struct lp55xx_chip *chip)1108{1109	struct device *dev = &chip->cl->dev;1110	const struct lp55xx_device_config *cfg = chip->cfg;1111 1112	if (cfg->dev_attr_group)1113		sysfs_remove_group(&dev->kobj, cfg->dev_attr_group);1114 1115	sysfs_remove_group(&dev->kobj, &lp55xx_engine_attr_group);1116}1117 1118static int lp55xx_parse_common_child(struct device_node *np,1119				     struct lp55xx_led_config *cfg,1120				     int led_number, int *chan_nr)1121{1122	int ret;1123 1124	of_property_read_string(np, "chan-name",1125				&cfg[led_number].name);1126	of_property_read_u8(np, "led-cur",1127			    &cfg[led_number].led_current);1128	of_property_read_u8(np, "max-cur",1129			    &cfg[led_number].max_current);1130 1131	ret = of_property_read_u32(np, "reg", chan_nr);1132	if (ret)1133		return ret;1134 1135	if (*chan_nr < 0 || *chan_nr > cfg->max_channel)1136		return -EINVAL;1137 1138	return 0;1139}1140 1141static int lp55xx_parse_multi_led_child(struct device_node *child,1142					 struct lp55xx_led_config *cfg,1143					 int child_number, int color_number)1144{1145	int chan_nr, color_id, ret;1146 1147	ret = lp55xx_parse_common_child(child, cfg, child_number, &chan_nr);1148	if (ret)1149		return ret;1150 1151	ret = of_property_read_u32(child, "color", &color_id);1152	if (ret)1153		return ret;1154 1155	cfg[child_number].color_id[color_number] = color_id;1156	cfg[child_number].output_num[color_number] = chan_nr;1157 1158	return 0;1159}1160 1161static int lp55xx_parse_multi_led(struct device_node *np,1162				  struct lp55xx_led_config *cfg,1163				  int child_number)1164{1165	int num_colors = 0, ret;1166 1167	for_each_available_child_of_node_scoped(np, child) {1168		ret = lp55xx_parse_multi_led_child(child, cfg, child_number,1169						   num_colors);1170		if (ret)1171			return ret;1172		num_colors++;1173	}1174 1175	cfg[child_number].num_colors = num_colors;1176 1177	return 0;1178}1179 1180static int lp55xx_parse_logical_led(struct device_node *np,1181				   struct lp55xx_led_config *cfg,1182				   int child_number)1183{1184	int led_color, ret;1185	int chan_nr = 0;1186 1187	cfg[child_number].default_trigger =1188		of_get_property(np, "linux,default-trigger", NULL);1189 1190	ret = of_property_read_u32(np, "color", &led_color);1191	if (ret)1192		return ret;1193 1194	if (led_color == LED_COLOR_ID_RGB)1195		return lp55xx_parse_multi_led(np, cfg, child_number);1196 1197	ret =  lp55xx_parse_common_child(np, cfg, child_number, &chan_nr);1198	if (ret < 0)1199		return ret;1200 1201	cfg[child_number].chan_nr = chan_nr;1202 1203	return ret;1204}1205 1206static struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,1207							     struct device_node *np,1208							     struct lp55xx_chip *chip)1209{1210	struct device_node *child;1211	struct lp55xx_platform_data *pdata;1212	struct lp55xx_led_config *cfg;1213	int num_channels;1214	int i = 0;1215	int ret;1216 1217	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);1218	if (!pdata)1219		return ERR_PTR(-ENOMEM);1220 1221	num_channels = of_get_available_child_count(np);1222	if (num_channels == 0) {1223		dev_err(dev, "no LED channels\n");1224		return ERR_PTR(-EINVAL);1225	}1226 1227	cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL);1228	if (!cfg)1229		return ERR_PTR(-ENOMEM);1230 1231	pdata->led_config = &cfg[0];1232	pdata->num_channels = num_channels;1233	cfg->max_channel = chip->cfg->max_channel;1234 1235	for_each_available_child_of_node(np, child) {1236		ret = lp55xx_parse_logical_led(child, cfg, i);1237		if (ret) {1238			of_node_put(child);1239			return ERR_PTR(-EINVAL);1240		}1241		i++;1242	}1243 1244	if (of_property_read_u32(np, "ti,charge-pump-mode", &pdata->charge_pump_mode))1245		pdata->charge_pump_mode = LP55XX_CP_AUTO;1246 1247	if (pdata->charge_pump_mode > LP55XX_CP_AUTO) {1248		dev_err(dev, "invalid charge pump mode %d\n", pdata->charge_pump_mode);1249		return ERR_PTR(-EINVAL);1250	}1251 1252	of_property_read_string(np, "label", &pdata->label);1253	of_property_read_u8(np, "clock-mode", &pdata->clock_mode);1254 1255	pdata->enable_gpiod = devm_gpiod_get_optional(dev, "enable",1256						      GPIOD_ASIS);1257	if (IS_ERR(pdata->enable_gpiod))1258		return ERR_CAST(pdata->enable_gpiod);1259 1260	/* LP8501 specific */1261	of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);1262 1263	return pdata;1264}1265 1266int lp55xx_probe(struct i2c_client *client)1267{1268	const struct i2c_device_id *id = i2c_client_get_device_id(client);1269	int program_length, ret;1270	struct lp55xx_chip *chip;1271	struct lp55xx_led *led;1272	struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);1273	struct device_node *np = dev_of_node(&client->dev);1274 1275	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);1276	if (!chip)1277		return -ENOMEM;1278 1279	chip->cfg = i2c_get_match_data(client);1280 1281	if (!pdata) {1282		if (np) {1283			pdata = lp55xx_of_populate_pdata(&client->dev, np,1284							 chip);1285			if (IS_ERR(pdata))1286				return PTR_ERR(pdata);1287		} else {1288			dev_err(&client->dev, "no platform data\n");1289			return -EINVAL;1290		}1291	}1292 1293	/* Validate max program page */1294	program_length = LP55xx_BYTES_PER_PAGE;1295	if (chip->cfg->pages_per_engine)1296		program_length *= chip->cfg->pages_per_engine;1297 1298	/* support a max of 128bytes */1299	if (program_length > LP55xx_MAX_PROGRAM_LENGTH) {1300		dev_err(&client->dev, "invalid pages_per_engine configured\n");1301		return -EINVAL;1302	}1303 1304	led = devm_kcalloc(&client->dev,1305			   pdata->num_channels, sizeof(*led), GFP_KERNEL);1306	if (!led)1307		return -ENOMEM;1308 1309	chip->cl = client;1310	chip->pdata = pdata;1311 1312	mutex_init(&chip->lock);1313 1314	i2c_set_clientdata(client, led);1315 1316	ret = lp55xx_init_device(chip);1317	if (ret)1318		goto err_init;1319 1320	dev_info(&client->dev, "%s Programmable led chip found\n", id->name);1321 1322	ret = lp55xx_register_leds(led, chip);1323	if (ret)1324		goto err_out;1325 1326	ret = lp55xx_register_sysfs(chip);1327	if (ret) {1328		dev_err(&client->dev, "registering sysfs failed\n");1329		goto err_out;1330	}1331 1332	return 0;1333 1334err_out:1335	lp55xx_deinit_device(chip);1336err_init:1337	return ret;1338}1339EXPORT_SYMBOL_GPL(lp55xx_probe);1340 1341void lp55xx_remove(struct i2c_client *client)1342{1343	struct lp55xx_led *led = i2c_get_clientdata(client);1344	struct lp55xx_chip *chip = led->chip;1345 1346	lp55xx_stop_all_engine(chip);1347	lp55xx_unregister_sysfs(chip);1348	lp55xx_deinit_device(chip);1349}1350EXPORT_SYMBOL_GPL(lp55xx_remove);1351 1352MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");1353MODULE_DESCRIPTION("LP55xx Common Driver");1354MODULE_LICENSE("GPL");1355