17fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz/*
27fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * LEDs driver for Freescale MC13783
37fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz *
47fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * Copyright (C) 2010 Philippe Rétornaz
57fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz *
67fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * Based on leds-da903x:
77fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * Copyright (C) 2008 Compulab, Ltd.
87fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz *      Mike Rapoport <mike@compulab.co.il>
97fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz *
107fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * Copyright (C) 2006-2008 Marvell International Ltd.
117fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz *      Eric Miao <eric.miao@marvell.com>
127fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz *
137fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * This program is free software; you can redistribute it and/or modify
147fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * it under the terms of the GNU General Public License version 2 as
157fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz * published by the Free Software Foundation.
167fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz */
177fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
187fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#include <linux/module.h>
197fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#include <linux/kernel.h>
207fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#include <linux/init.h>
217fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#include <linux/platform_device.h>
227fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#include <linux/leds.h>
237fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#include <linux/workqueue.h>
24f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander#include <linux/mfd/mc13xxx.h>
257fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#include <linux/slab.h>
267fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
277fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstruct mc13783_led {
287fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	struct led_classdev	cdev;
297fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	struct work_struct	work;
30f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	struct mc13xxx		*master;
317fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	enum led_brightness	new_brightness;
327fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int			id;
337fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz};
347fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
357fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_REG_LED_CONTROL_0	51
367fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_ENABLE_BIT	(1 << 0)
377fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_TRIODE_MD_BIT	(1 << 7)
387fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_TRIODE_AD_BIT	(1 << 8)
397fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_TRIODE_KP_BIT	(1 << 9)
407fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_BOOST_BIT	(1 << 10)
417fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_ABMODE_MASK	0x7
427fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_ABMODE		11
437fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_ABREF_MASK	0x3
447fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C0_ABREF		14
457fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
467fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_REG_LED_CONTROL_1	52
477fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C1_TC1HALF_BIT	(1 << 18)
487fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
497fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_REG_LED_CONTROL_2	53
507fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_BL_P_MASK	0xf
517fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_MD_P		9
527fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_AD_P		13
537fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_KP_P		17
547fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_BL_C_MASK	0x7
557fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_MD_C		0
567fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_AD_C		3
577fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C2_KP_C		6
587fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
597fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_REG_LED_CONTROL_3	54
607fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C3_TC_P		6
617fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_C3_TC_P_MASK	0x1f
627fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
637fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_REG_LED_CONTROL_4	55
647fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_REG_LED_CONTROL_5	56
657fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
667fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_Cx_PERIOD		21
677fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_Cx_PERIOD_MASK	0x3
687fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_Cx_SLEWLIM_BIT      (1 << 23)
697fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_Cx_TRIODE_TC_BIT	(1 << 23)
707fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz#define MC13783_LED_Cx_TC_C_MASK	0x3
717fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
727fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstatic void mc13783_led_work(struct work_struct *work)
737fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz{
747fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	struct mc13783_led *led = container_of(work, struct mc13783_led, work);
757fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int reg = 0;
767fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int mask = 0;
777fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int value = 0;
787fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int bank, off, shift;
797fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
807fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	switch (led->id) {
817fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_MD:
827fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_2;
837fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_MD_P;
847fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = (led->new_brightness >> 4) << MC13783_LED_C2_MD_P;
857fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
867fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_AD:
877fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_2;
887fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_AD_P;
897fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = (led->new_brightness >> 4) << MC13783_LED_C2_AD_P;
907fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
917fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_KP:
927fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_2;
937fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_KP_P;
947fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = (led->new_brightness >> 4) << MC13783_LED_C2_KP_P;
957fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
967fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_R1:
977fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_G1:
987fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_B1:
997fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_R2:
1007fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_G2:
1017fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_B2:
1027fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_R3:
1037fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_G3:
1047fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_B3:
1057fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		off = led->id - MC13783_LED_R1;
1067fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		bank = off/3;
1077fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_3 + off/3;
1087fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		shift = (off - bank * 3) * 5 + MC13783_LED_C3_TC_P;
1097fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = (led->new_brightness >> 3) << shift;
1107fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_C3_TC_P_MASK << shift;
1117fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
1127fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
1137fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
114f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_lock(led->master);
1157fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
116f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_reg_rmw(led->master, reg, mask, value);
1177fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
118f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_unlock(led->master);
1197fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz}
1207fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
1217fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstatic void mc13783_led_set(struct led_classdev *led_cdev,
1227fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			   enum led_brightness value)
1237fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz{
1247fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	struct mc13783_led *led;
1257fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
1267fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	led = container_of(led_cdev, struct mc13783_led, cdev);
1277fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	led->new_brightness = value;
1287fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	schedule_work(&led->work);
1297fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz}
1307fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
1317fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstatic int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
1327fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz{
1337fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int shift = 0;
1347fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int mask = 0;
1357fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int value = 0;
1367fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int reg = 0;
1377fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int ret, bank;
1387fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
1397fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	switch (led->id) {
1407fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_MD:
1417fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		shift = MC13783_LED_C2_MD_C;
1427fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_C2_BL_C_MASK;
1437fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = max_current & MC13783_LED_C2_BL_C_MASK;
1447fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_2;
1457fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
1467fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_AD:
1477fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		shift = MC13783_LED_C2_AD_C;
1487fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_C2_BL_C_MASK;
1497fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = max_current & MC13783_LED_C2_BL_C_MASK;
1507fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_2;
1517fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
1527fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_KP:
1537fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		shift = MC13783_LED_C2_KP_C;
1547fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_C2_BL_C_MASK;
1557fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = max_current & MC13783_LED_C2_BL_C_MASK;
1567fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_2;
1577fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
1587fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_R1:
1597fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_G1:
1607fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_B1:
1617fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_R2:
1627fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_G2:
1637fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_B2:
1647fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_R3:
1657fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_G3:
1667fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	case MC13783_LED_B3:
1677fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		bank = (led->id - MC13783_LED_R1)/3;
1687fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg = MC13783_REG_LED_CONTROL_3 + bank;
1697fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		shift = ((led->id - MC13783_LED_R1) - bank * 3) * 2;
1707fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		mask = MC13783_LED_Cx_TC_C_MASK;
1717fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		value = max_current & MC13783_LED_Cx_TC_C_MASK;
1727fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		break;
1737fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
1747fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
175f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_lock(led->master);
1767fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
177f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	ret = mc13xxx_reg_rmw(led->master, reg, mask << shift,
1787fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz						value << shift);
1797fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
180f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_unlock(led->master);
1817fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	return ret;
1827fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz}
1837fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
1847fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstatic int __devinit mc13783_leds_prepare(struct platform_device *pdev)
1857fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz{
18652b7ad3a63a42b76f4f07cba876479a3c416f1e8Samuel Ortiz	struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
187f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent);
1887fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int ret = 0;
1897fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int reg = 0;
1907fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
191f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_lock(dev);
1927fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
1937fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_TC1HALF)
1947fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_C1_TC1HALF_BIT;
1957fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
1967fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_SLEWLIMTC)
1977fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_Cx_SLEWLIM_BIT;
1987fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
199f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg);
2007fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (ret)
2017fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		goto out;
2027fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2037fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	reg = (pdata->bl_period & MC13783_LED_Cx_PERIOD_MASK) <<
2047fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz							MC13783_LED_Cx_PERIOD;
2057fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2067fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_SLEWLIMBL)
2077fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_Cx_SLEWLIM_BIT;
2087fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
209f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg);
2107fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (ret)
2117fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		goto out;
2127fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2137fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	reg = (pdata->tc1_period & MC13783_LED_Cx_PERIOD_MASK) <<
2147fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz							MC13783_LED_Cx_PERIOD;
2157fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2167fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_TRIODE_TC1)
2177fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
2187fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
219f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg);
2207fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (ret)
2217fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		goto out;
2227fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2237fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	reg = (pdata->tc2_period & MC13783_LED_Cx_PERIOD_MASK) <<
2247fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz							MC13783_LED_Cx_PERIOD;
2257fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2267fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_TRIODE_TC2)
2277fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
2287fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
229f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg);
2307fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (ret)
2317fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		goto out;
2327fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2337fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	reg = (pdata->tc3_period & MC13783_LED_Cx_PERIOD_MASK) <<
2347fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz							MC13783_LED_Cx_PERIOD;
2357fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2367fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_TRIODE_TC3)
2376eab04a87677a37cf15b52e2b4b4fd57917102adJustin P. Mattock		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
2387fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
239f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg);
2407fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (ret)
2417fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		goto out;
2427fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2437fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	reg = MC13783_LED_C0_ENABLE_BIT;
2447fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_TRIODE_MD)
2457fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_C0_TRIODE_MD_BIT;
2467fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_TRIODE_AD)
2477fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_C0_TRIODE_AD_BIT;
2487fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_TRIODE_KP)
2497fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_C0_TRIODE_KP_BIT;
2507fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata->flags & MC13783_LED_BOOST_EN)
2517fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		reg |= MC13783_LED_C0_BOOST_BIT;
2527fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2537fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	reg |= (pdata->abmode & MC13783_LED_C0_ABMODE_MASK) <<
2547fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz							MC13783_LED_C0_ABMODE;
2557fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) <<
2567fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz							MC13783_LED_C0_ABREF;
2577fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
258f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg);
2597fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2607fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazout:
261f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_unlock(dev);
2627fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	return ret;
2637fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz}
2647fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2657fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstatic int __devinit mc13783_led_probe(struct platform_device *pdev)
2667fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz{
26752b7ad3a63a42b76f4f07cba876479a3c416f1e8Samuel Ortiz	struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
26852b7ad3a63a42b76f4f07cba876479a3c416f1e8Samuel Ortiz	struct mc13xxx_led_platform_data *led_cur;
2697fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	struct mc13783_led *led, *led_dat;
2707fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int ret, i;
2717fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int init_led = 0;
2727fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2737fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (pdata == NULL) {
2747fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		dev_err(&pdev->dev, "missing platform data\n");
2757fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		return -ENODEV;
2767fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
2777fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2783b080945aa7670354364c8f9e1a3a07cbb97beb3Axel Lin	if (pdata->num_leds < 1 || pdata->num_leds > (MC13783_LED_MAX + 1)) {
2797fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds);
2807fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		return -EINVAL;
2817fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
2827fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2837fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
2847fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (led == NULL) {
2857fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		dev_err(&pdev->dev, "failed to alloc memory\n");
2867fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		return -ENOMEM;
2877fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
2887fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2897fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	ret = mc13783_leds_prepare(pdev);
2907fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	if (ret) {
2917fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		dev_err(&pdev->dev, "unable to init led driver\n");
2927fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		goto err_free;
2937fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
2947fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2957fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	for (i = 0; i < pdata->num_leds; i++) {
2967fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_dat = &led[i];
2977fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_cur = &pdata->led[i];
2987fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
2997fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		if (led_cur->id > MC13783_LED_MAX || led_cur->id < 0) {
3007fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			dev_err(&pdev->dev, "invalid id %d\n", led_cur->id);
3017fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			ret = -EINVAL;
3027fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			goto err_register;
3037fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		}
3047fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3057fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		if (init_led & (1 << led_cur->id)) {
3067fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			dev_err(&pdev->dev, "led %d already initialized\n",
3077fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz					led_cur->id);
3087fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			ret = -EINVAL;
3097fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			goto err_register;
3107fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		}
3117fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3127fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		init_led |= 1 << led_cur->id;
3137fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_dat->cdev.name = led_cur->name;
3147fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_dat->cdev.default_trigger = led_cur->default_trigger;
3157fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_dat->cdev.brightness_set = mc13783_led_set;
3167fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_dat->cdev.brightness = LED_OFF;
3177fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_dat->id = led_cur->id;
3187fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_dat->master = dev_get_drvdata(pdev->dev.parent);
3197fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3207fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		INIT_WORK(&led_dat->work, mc13783_led_work);
3217fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3227fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		ret = led_classdev_register(pdev->dev.parent, &led_dat->cdev);
3237fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		if (ret) {
3247fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			dev_err(&pdev->dev, "failed to register led %d\n",
3257fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz					led_dat->id);
3267fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			goto err_register;
3277fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		}
3287fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3297fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		ret = mc13783_led_setup(led_dat, led_cur->max_current);
3307fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		if (ret) {
3317fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			dev_err(&pdev->dev, "unable to init led %d\n",
3327fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz					led_dat->id);
3337fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			i++;
3347fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz			goto err_register;
3357fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		}
3367fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
3377fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3387fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	platform_set_drvdata(pdev, led);
3397fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	return 0;
3407fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3417fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazerr_register:
3427fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	for (i = i - 1; i >= 0; i--) {
3437fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_classdev_unregister(&led[i].cdev);
3447fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		cancel_work_sync(&led[i].work);
3457fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
3467fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3477fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazerr_free:
3487fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	kfree(led);
3497fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	return ret;
3507fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz}
3517fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3527fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstatic int __devexit mc13783_led_remove(struct platform_device *pdev)
3537fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz{
35452b7ad3a63a42b76f4f07cba876479a3c416f1e8Samuel Ortiz	struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
3557fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	struct mc13783_led *led = platform_get_drvdata(pdev);
356f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent);
3577fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	int i;
3587fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3597fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	for (i = 0; i < pdata->num_leds; i++) {
3607fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		led_classdev_unregister(&led[i].cdev);
3617fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		cancel_work_sync(&led[i].work);
3627fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	}
3637fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
364f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_lock(dev);
3657fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
366f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0);
367f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0);
368f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0);
369f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0);
370f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0);
371f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0);
3727fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
373f3ca07824f309474b308d859c9a2cc871c6c5ab8David Jander	mc13xxx_unlock(dev);
3747fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3757fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	kfree(led);
3767fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	return 0;
3777fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz}
3787fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3797fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornazstatic struct platform_driver mc13783_led_driver = {
3807fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	.driver	= {
3817fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		.name	= "mc13783-led",
3827fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz		.owner	= THIS_MODULE,
3837fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	},
3847fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	.probe		= mc13783_led_probe,
3857fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz	.remove		= __devexit_p(mc13783_led_remove),
3867fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz};
3877fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
388892a8843fbef07a7f2ab62d5f7ff5c16ea0903b0Axel Linmodule_platform_driver(mc13783_led_driver);
3897fdcef8a414eaeb367b3696005b25283d62d195dPhilippe Rétornaz
3907fdcef8a414eaeb367b3696005b25283d62d195dPhilippe RétornazMODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC");
3917fdcef8a414eaeb367b3696005b25283d62d195dPhilippe RétornazMODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>");
3927fdcef8a414eaeb367b3696005b25283d62d195dPhilippe RétornazMODULE_LICENSE("GPL");
3937fdcef8a414eaeb367b3696005b25283d62d195dPhilippe RétornazMODULE_ALIAS("platform:mc13783-led");
394