xref: /openbmc/linux/drivers/leds/leds-aw2013.c (revision 5ee9cd065836e5934710ca35653bce7905add20b)
159ea3c9fSNikita Travkin // SPDX-License-Identifier: GPL-2.0+
259ea3c9fSNikita Travkin // Driver for Awinic AW2013 3-channel LED driver
359ea3c9fSNikita Travkin 
459ea3c9fSNikita Travkin #include <linux/i2c.h>
559ea3c9fSNikita Travkin #include <linux/leds.h>
659ea3c9fSNikita Travkin #include <linux/module.h>
759ea3c9fSNikita Travkin #include <linux/regulator/consumer.h>
859ea3c9fSNikita Travkin #include <linux/mutex.h>
959ea3c9fSNikita Travkin #include <linux/of.h>
1059ea3c9fSNikita Travkin #include <linux/regmap.h>
1159ea3c9fSNikita Travkin 
1259ea3c9fSNikita Travkin #define AW2013_MAX_LEDS 3
1359ea3c9fSNikita Travkin 
1459ea3c9fSNikita Travkin /* Reset and ID register */
1559ea3c9fSNikita Travkin #define AW2013_RSTR 0x00
1659ea3c9fSNikita Travkin #define AW2013_RSTR_RESET 0x55
1759ea3c9fSNikita Travkin #define AW2013_RSTR_CHIP_ID 0x33
1859ea3c9fSNikita Travkin 
1959ea3c9fSNikita Travkin /* Global control register */
2059ea3c9fSNikita Travkin #define AW2013_GCR 0x01
2159ea3c9fSNikita Travkin #define AW2013_GCR_ENABLE BIT(0)
2259ea3c9fSNikita Travkin 
2359ea3c9fSNikita Travkin /* LED channel enable register */
2459ea3c9fSNikita Travkin #define AW2013_LCTR 0x30
2559ea3c9fSNikita Travkin #define AW2013_LCTR_LE(x) BIT((x))
2659ea3c9fSNikita Travkin 
2759ea3c9fSNikita Travkin /* LED channel control registers */
2859ea3c9fSNikita Travkin #define AW2013_LCFG(x) (0x31 + (x))
2959ea3c9fSNikita Travkin #define AW2013_LCFG_IMAX_MASK (BIT(0) | BIT(1)) // Should be 0-3
3059ea3c9fSNikita Travkin #define AW2013_LCFG_MD BIT(4)
3159ea3c9fSNikita Travkin #define AW2013_LCFG_FI BIT(5)
3259ea3c9fSNikita Travkin #define AW2013_LCFG_FO BIT(6)
3359ea3c9fSNikita Travkin 
3459ea3c9fSNikita Travkin /* LED channel PWM registers */
3559ea3c9fSNikita Travkin #define AW2013_REG_PWM(x) (0x34 + (x))
3659ea3c9fSNikita Travkin 
3759ea3c9fSNikita Travkin /* LED channel timing registers */
3859ea3c9fSNikita Travkin #define AW2013_LEDT0(x) (0x37 + (x) * 3)
3959ea3c9fSNikita Travkin #define AW2013_LEDT0_T1(x) ((x) << 4) // Should be 0-7
4059ea3c9fSNikita Travkin #define AW2013_LEDT0_T2(x) (x) // Should be 0-5
4159ea3c9fSNikita Travkin 
4259ea3c9fSNikita Travkin #define AW2013_LEDT1(x) (0x38 + (x) * 3)
4359ea3c9fSNikita Travkin #define AW2013_LEDT1_T3(x) ((x) << 4) // Should be 0-7
4459ea3c9fSNikita Travkin #define AW2013_LEDT1_T4(x) (x) // Should be 0-7
4559ea3c9fSNikita Travkin 
4659ea3c9fSNikita Travkin #define AW2013_LEDT2(x) (0x39 + (x) * 3)
4759ea3c9fSNikita Travkin #define AW2013_LEDT2_T0(x) ((x) << 4) // Should be 0-8
4859ea3c9fSNikita Travkin #define AW2013_LEDT2_REPEAT(x) (x) // Should be 0-15
4959ea3c9fSNikita Travkin 
5059ea3c9fSNikita Travkin #define AW2013_REG_MAX 0x77
5159ea3c9fSNikita Travkin 
5259ea3c9fSNikita Travkin #define AW2013_TIME_STEP 130 /* ms */
5359ea3c9fSNikita Travkin 
5459ea3c9fSNikita Travkin struct aw2013;
5559ea3c9fSNikita Travkin 
5659ea3c9fSNikita Travkin struct aw2013_led {
5759ea3c9fSNikita Travkin 	struct aw2013 *chip;
5859ea3c9fSNikita Travkin 	struct led_classdev cdev;
5959ea3c9fSNikita Travkin 	u32 num;
6059ea3c9fSNikita Travkin 	unsigned int imax;
6159ea3c9fSNikita Travkin };
6259ea3c9fSNikita Travkin 
6359ea3c9fSNikita Travkin struct aw2013 {
6459ea3c9fSNikita Travkin 	struct mutex mutex; /* held when writing to registers */
65baca986eSLin, Meng-Bo 	struct regulator_bulk_data regulators[2];
6659ea3c9fSNikita Travkin 	struct i2c_client *client;
6759ea3c9fSNikita Travkin 	struct aw2013_led leds[AW2013_MAX_LEDS];
6859ea3c9fSNikita Travkin 	struct regmap *regmap;
6959ea3c9fSNikita Travkin 	int num_leds;
7059ea3c9fSNikita Travkin 	bool enabled;
7159ea3c9fSNikita Travkin };
7259ea3c9fSNikita Travkin 
aw2013_chip_init(struct aw2013 * chip)7359ea3c9fSNikita Travkin static int aw2013_chip_init(struct aw2013 *chip)
7459ea3c9fSNikita Travkin {
7559ea3c9fSNikita Travkin 	int i, ret;
7659ea3c9fSNikita Travkin 
7759ea3c9fSNikita Travkin 	ret = regmap_write(chip->regmap, AW2013_GCR, AW2013_GCR_ENABLE);
7859ea3c9fSNikita Travkin 	if (ret) {
7959ea3c9fSNikita Travkin 		dev_err(&chip->client->dev, "Failed to enable the chip: %d\n",
8059ea3c9fSNikita Travkin 			ret);
8159ea3c9fSNikita Travkin 		return ret;
8259ea3c9fSNikita Travkin 	}
8359ea3c9fSNikita Travkin 
8459ea3c9fSNikita Travkin 	for (i = 0; i < chip->num_leds; i++) {
8559ea3c9fSNikita Travkin 		ret = regmap_update_bits(chip->regmap,
8659ea3c9fSNikita Travkin 					 AW2013_LCFG(chip->leds[i].num),
8759ea3c9fSNikita Travkin 					 AW2013_LCFG_IMAX_MASK,
8859ea3c9fSNikita Travkin 					 chip->leds[i].imax);
8959ea3c9fSNikita Travkin 		if (ret) {
9059ea3c9fSNikita Travkin 			dev_err(&chip->client->dev,
9159ea3c9fSNikita Travkin 				"Failed to set maximum current for led %d: %d\n",
9259ea3c9fSNikita Travkin 				chip->leds[i].num, ret);
9359ea3c9fSNikita Travkin 			return ret;
9459ea3c9fSNikita Travkin 		}
9559ea3c9fSNikita Travkin 	}
9659ea3c9fSNikita Travkin 
9759ea3c9fSNikita Travkin 	return ret;
9859ea3c9fSNikita Travkin }
9959ea3c9fSNikita Travkin 
aw2013_chip_disable(struct aw2013 * chip)10059ea3c9fSNikita Travkin static void aw2013_chip_disable(struct aw2013 *chip)
10159ea3c9fSNikita Travkin {
10259ea3c9fSNikita Travkin 	int ret;
10359ea3c9fSNikita Travkin 
10459ea3c9fSNikita Travkin 	if (!chip->enabled)
10559ea3c9fSNikita Travkin 		return;
10659ea3c9fSNikita Travkin 
10759ea3c9fSNikita Travkin 	regmap_write(chip->regmap, AW2013_GCR, 0);
10859ea3c9fSNikita Travkin 
109baca986eSLin, Meng-Bo 	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
110baca986eSLin, Meng-Bo 				     chip->regulators);
11159ea3c9fSNikita Travkin 	if (ret) {
11259ea3c9fSNikita Travkin 		dev_err(&chip->client->dev,
113baca986eSLin, Meng-Bo 			"Failed to disable regulators: %d\n", ret);
11459ea3c9fSNikita Travkin 		return;
11559ea3c9fSNikita Travkin 	}
11659ea3c9fSNikita Travkin 
11759ea3c9fSNikita Travkin 	chip->enabled = false;
11859ea3c9fSNikita Travkin }
11959ea3c9fSNikita Travkin 
aw2013_chip_enable(struct aw2013 * chip)12059ea3c9fSNikita Travkin static int aw2013_chip_enable(struct aw2013 *chip)
12159ea3c9fSNikita Travkin {
12259ea3c9fSNikita Travkin 	int ret;
12359ea3c9fSNikita Travkin 
12459ea3c9fSNikita Travkin 	if (chip->enabled)
12559ea3c9fSNikita Travkin 		return 0;
12659ea3c9fSNikita Travkin 
127baca986eSLin, Meng-Bo 	ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators),
128baca986eSLin, Meng-Bo 				    chip->regulators);
12959ea3c9fSNikita Travkin 	if (ret) {
13059ea3c9fSNikita Travkin 		dev_err(&chip->client->dev,
131baca986eSLin, Meng-Bo 			"Failed to enable regulators: %d\n", ret);
13259ea3c9fSNikita Travkin 		return ret;
13359ea3c9fSNikita Travkin 	}
13459ea3c9fSNikita Travkin 	chip->enabled = true;
13559ea3c9fSNikita Travkin 
13659ea3c9fSNikita Travkin 	ret = aw2013_chip_init(chip);
13759ea3c9fSNikita Travkin 	if (ret)
13859ea3c9fSNikita Travkin 		aw2013_chip_disable(chip);
13959ea3c9fSNikita Travkin 
14059ea3c9fSNikita Travkin 	return ret;
14159ea3c9fSNikita Travkin }
14259ea3c9fSNikita Travkin 
aw2013_chip_in_use(struct aw2013 * chip)14359ea3c9fSNikita Travkin static bool aw2013_chip_in_use(struct aw2013 *chip)
14459ea3c9fSNikita Travkin {
14559ea3c9fSNikita Travkin 	int i;
14659ea3c9fSNikita Travkin 
14759ea3c9fSNikita Travkin 	for (i = 0; i < chip->num_leds; i++)
14859ea3c9fSNikita Travkin 		if (chip->leds[i].cdev.brightness)
14959ea3c9fSNikita Travkin 			return true;
15059ea3c9fSNikita Travkin 
15159ea3c9fSNikita Travkin 	return false;
15259ea3c9fSNikita Travkin }
15359ea3c9fSNikita Travkin 
aw2013_brightness_set(struct led_classdev * cdev,enum led_brightness brightness)15459ea3c9fSNikita Travkin static int aw2013_brightness_set(struct led_classdev *cdev,
15559ea3c9fSNikita Travkin 				 enum led_brightness brightness)
15659ea3c9fSNikita Travkin {
15759ea3c9fSNikita Travkin 	struct aw2013_led *led = container_of(cdev, struct aw2013_led, cdev);
15859ea3c9fSNikita Travkin 	int ret, num;
15959ea3c9fSNikita Travkin 
16059ea3c9fSNikita Travkin 	mutex_lock(&led->chip->mutex);
16159ea3c9fSNikita Travkin 
16259ea3c9fSNikita Travkin 	if (aw2013_chip_in_use(led->chip)) {
16359ea3c9fSNikita Travkin 		ret = aw2013_chip_enable(led->chip);
16459ea3c9fSNikita Travkin 		if (ret)
16559ea3c9fSNikita Travkin 			goto error;
16659ea3c9fSNikita Travkin 	}
16759ea3c9fSNikita Travkin 
16859ea3c9fSNikita Travkin 	num = led->num;
16959ea3c9fSNikita Travkin 
17059ea3c9fSNikita Travkin 	ret = regmap_write(led->chip->regmap, AW2013_REG_PWM(num), brightness);
17159ea3c9fSNikita Travkin 	if (ret)
17259ea3c9fSNikita Travkin 		goto error;
17359ea3c9fSNikita Travkin 
17459ea3c9fSNikita Travkin 	if (brightness) {
17559ea3c9fSNikita Travkin 		ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR,
17659ea3c9fSNikita Travkin 					 AW2013_LCTR_LE(num), 0xFF);
17759ea3c9fSNikita Travkin 	} else {
17859ea3c9fSNikita Travkin 		ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR,
17959ea3c9fSNikita Travkin 					 AW2013_LCTR_LE(num), 0);
18059ea3c9fSNikita Travkin 		if (ret)
18159ea3c9fSNikita Travkin 			goto error;
18259ea3c9fSNikita Travkin 		ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num),
18359ea3c9fSNikita Travkin 					 AW2013_LCFG_MD, 0);
18459ea3c9fSNikita Travkin 	}
18559ea3c9fSNikita Travkin 	if (ret)
18659ea3c9fSNikita Travkin 		goto error;
18759ea3c9fSNikita Travkin 
18859ea3c9fSNikita Travkin 	if (!aw2013_chip_in_use(led->chip))
18959ea3c9fSNikita Travkin 		aw2013_chip_disable(led->chip);
19059ea3c9fSNikita Travkin 
19159ea3c9fSNikita Travkin error:
19259ea3c9fSNikita Travkin 	mutex_unlock(&led->chip->mutex);
19359ea3c9fSNikita Travkin 
19459ea3c9fSNikita Travkin 	return ret;
19559ea3c9fSNikita Travkin }
19659ea3c9fSNikita Travkin 
aw2013_blink_set(struct led_classdev * cdev,unsigned long * delay_on,unsigned long * delay_off)19759ea3c9fSNikita Travkin static int aw2013_blink_set(struct led_classdev *cdev,
19859ea3c9fSNikita Travkin 			    unsigned long *delay_on, unsigned long *delay_off)
19959ea3c9fSNikita Travkin {
20059ea3c9fSNikita Travkin 	struct aw2013_led *led = container_of(cdev, struct aw2013_led, cdev);
20159ea3c9fSNikita Travkin 	int ret, num = led->num;
20259ea3c9fSNikita Travkin 	unsigned long off = 0, on = 0;
20359ea3c9fSNikita Travkin 
20459ea3c9fSNikita Travkin 	/* If no blink specified, default to 1 Hz. */
20559ea3c9fSNikita Travkin 	if (!*delay_off && !*delay_on) {
20659ea3c9fSNikita Travkin 		*delay_off = 500;
20759ea3c9fSNikita Travkin 		*delay_on = 500;
20859ea3c9fSNikita Travkin 	}
20959ea3c9fSNikita Travkin 
21059ea3c9fSNikita Travkin 	if (!led->cdev.brightness) {
21159ea3c9fSNikita Travkin 		led->cdev.brightness = LED_FULL;
21259ea3c9fSNikita Travkin 		ret = aw2013_brightness_set(&led->cdev, led->cdev.brightness);
21359ea3c9fSNikita Travkin 		if (ret)
21459ea3c9fSNikita Travkin 			return ret;
21559ea3c9fSNikita Travkin 	}
21659ea3c9fSNikita Travkin 
21759ea3c9fSNikita Travkin 	/* Never on - just set to off */
21859ea3c9fSNikita Travkin 	if (!*delay_on) {
21959ea3c9fSNikita Travkin 		led->cdev.brightness = LED_OFF;
22059ea3c9fSNikita Travkin 		return aw2013_brightness_set(&led->cdev, LED_OFF);
22159ea3c9fSNikita Travkin 	}
22259ea3c9fSNikita Travkin 
22359ea3c9fSNikita Travkin 	mutex_lock(&led->chip->mutex);
22459ea3c9fSNikita Travkin 
22559ea3c9fSNikita Travkin 	/* Never off - brightness is already set, disable blinking */
22659ea3c9fSNikita Travkin 	if (!*delay_off) {
22759ea3c9fSNikita Travkin 		ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num),
22859ea3c9fSNikita Travkin 					 AW2013_LCFG_MD, 0);
22959ea3c9fSNikita Travkin 		goto out;
23059ea3c9fSNikita Travkin 	}
23159ea3c9fSNikita Travkin 
23259ea3c9fSNikita Travkin 	/* Convert into values the HW will understand. */
23359ea3c9fSNikita Travkin 	off = min(5, ilog2((*delay_off - 1) / AW2013_TIME_STEP) + 1);
23459ea3c9fSNikita Travkin 	on = min(7, ilog2((*delay_on - 1) / AW2013_TIME_STEP) + 1);
23559ea3c9fSNikita Travkin 
23659ea3c9fSNikita Travkin 	*delay_off = BIT(off) * AW2013_TIME_STEP;
23759ea3c9fSNikita Travkin 	*delay_on = BIT(on) * AW2013_TIME_STEP;
23859ea3c9fSNikita Travkin 
23959ea3c9fSNikita Travkin 	/* Set timings */
24059ea3c9fSNikita Travkin 	ret = regmap_write(led->chip->regmap,
24159ea3c9fSNikita Travkin 			   AW2013_LEDT0(num), AW2013_LEDT0_T2(on));
24259ea3c9fSNikita Travkin 	if (ret)
24359ea3c9fSNikita Travkin 		goto out;
24459ea3c9fSNikita Travkin 	ret = regmap_write(led->chip->regmap,
24559ea3c9fSNikita Travkin 			   AW2013_LEDT1(num), AW2013_LEDT1_T4(off));
24659ea3c9fSNikita Travkin 	if (ret)
24759ea3c9fSNikita Travkin 		goto out;
24859ea3c9fSNikita Travkin 
24959ea3c9fSNikita Travkin 	/* Finally, enable the LED */
25059ea3c9fSNikita Travkin 	ret = regmap_update_bits(led->chip->regmap, AW2013_LCFG(num),
25159ea3c9fSNikita Travkin 				 AW2013_LCFG_MD, 0xFF);
25259ea3c9fSNikita Travkin 	if (ret)
25359ea3c9fSNikita Travkin 		goto out;
25459ea3c9fSNikita Travkin 
25559ea3c9fSNikita Travkin 	ret = regmap_update_bits(led->chip->regmap, AW2013_LCTR,
25659ea3c9fSNikita Travkin 				 AW2013_LCTR_LE(num), 0xFF);
25759ea3c9fSNikita Travkin 
25859ea3c9fSNikita Travkin out:
25959ea3c9fSNikita Travkin 	mutex_unlock(&led->chip->mutex);
26059ea3c9fSNikita Travkin 
26159ea3c9fSNikita Travkin 	return ret;
26259ea3c9fSNikita Travkin }
26359ea3c9fSNikita Travkin 
aw2013_probe_dt(struct aw2013 * chip)26459ea3c9fSNikita Travkin static int aw2013_probe_dt(struct aw2013 *chip)
26559ea3c9fSNikita Travkin {
2668853c95eSMarek Behún 	struct device_node *np = dev_of_node(&chip->client->dev), *child;
26759ea3c9fSNikita Travkin 	int count, ret = 0, i = 0;
26859ea3c9fSNikita Travkin 	struct aw2013_led *led;
26959ea3c9fSNikita Travkin 
27099a013c8SMarek Behún 	count = of_get_available_child_count(np);
27159ea3c9fSNikita Travkin 	if (!count || count > AW2013_MAX_LEDS)
27259ea3c9fSNikita Travkin 		return -EINVAL;
27359ea3c9fSNikita Travkin 
27459ea3c9fSNikita Travkin 	regmap_write(chip->regmap, AW2013_RSTR, AW2013_RSTR_RESET);
27559ea3c9fSNikita Travkin 
27659ea3c9fSNikita Travkin 	for_each_available_child_of_node(np, child) {
27759ea3c9fSNikita Travkin 		struct led_init_data init_data = {};
27859ea3c9fSNikita Travkin 		u32 source;
27959ea3c9fSNikita Travkin 		u32 imax;
28059ea3c9fSNikita Travkin 
28159ea3c9fSNikita Travkin 		ret = of_property_read_u32(child, "reg", &source);
28259ea3c9fSNikita Travkin 		if (ret != 0 || source >= AW2013_MAX_LEDS) {
28359ea3c9fSNikita Travkin 			dev_err(&chip->client->dev,
28459ea3c9fSNikita Travkin 				"Couldn't read LED address: %d\n", ret);
28559ea3c9fSNikita Travkin 			count--;
28659ea3c9fSNikita Travkin 			continue;
28759ea3c9fSNikita Travkin 		}
28859ea3c9fSNikita Travkin 
28959ea3c9fSNikita Travkin 		led = &chip->leds[i];
29059ea3c9fSNikita Travkin 		led->num = source;
29159ea3c9fSNikita Travkin 		led->chip = chip;
29259ea3c9fSNikita Travkin 		init_data.fwnode = of_fwnode_handle(child);
29359ea3c9fSNikita Travkin 
29459ea3c9fSNikita Travkin 		if (!of_property_read_u32(child, "led-max-microamp", &imax)) {
29559ea3c9fSNikita Travkin 			led->imax = min_t(u32, imax / 5000, 3);
29659ea3c9fSNikita Travkin 		} else {
29759ea3c9fSNikita Travkin 			led->imax = 1; // 5mA
29859ea3c9fSNikita Travkin 			dev_info(&chip->client->dev,
29959ea3c9fSNikita Travkin 				 "DT property led-max-microamp is missing\n");
30059ea3c9fSNikita Travkin 		}
30159ea3c9fSNikita Travkin 
30259ea3c9fSNikita Travkin 		led->cdev.brightness_set_blocking = aw2013_brightness_set;
30359ea3c9fSNikita Travkin 		led->cdev.blink_set = aw2013_blink_set;
30459ea3c9fSNikita Travkin 
30559ea3c9fSNikita Travkin 		ret = devm_led_classdev_register_ext(&chip->client->dev,
30659ea3c9fSNikita Travkin 						     &led->cdev, &init_data);
3072c677562SMarek Behún 		if (ret < 0) {
3082c677562SMarek Behún 			of_node_put(child);
30959ea3c9fSNikita Travkin 			return ret;
3102c677562SMarek Behún 		}
31159ea3c9fSNikita Travkin 
31259ea3c9fSNikita Travkin 		i++;
31359ea3c9fSNikita Travkin 	}
31459ea3c9fSNikita Travkin 
31559ea3c9fSNikita Travkin 	if (!count)
31659ea3c9fSNikita Travkin 		return -EINVAL;
31759ea3c9fSNikita Travkin 
31859ea3c9fSNikita Travkin 	chip->num_leds = i;
31959ea3c9fSNikita Travkin 
32059ea3c9fSNikita Travkin 	return 0;
32159ea3c9fSNikita Travkin }
32259ea3c9fSNikita Travkin 
32359ea3c9fSNikita Travkin static const struct regmap_config aw2013_regmap_config = {
32459ea3c9fSNikita Travkin 	.reg_bits = 8,
32559ea3c9fSNikita Travkin 	.val_bits = 8,
32659ea3c9fSNikita Travkin 	.max_register = AW2013_REG_MAX,
32759ea3c9fSNikita Travkin };
32859ea3c9fSNikita Travkin 
aw2013_probe(struct i2c_client * client)32959ea3c9fSNikita Travkin static int aw2013_probe(struct i2c_client *client)
33059ea3c9fSNikita Travkin {
33159ea3c9fSNikita Travkin 	struct aw2013 *chip;
33259ea3c9fSNikita Travkin 	int ret;
33359ea3c9fSNikita Travkin 	unsigned int chipid;
33459ea3c9fSNikita Travkin 
33559ea3c9fSNikita Travkin 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
33659ea3c9fSNikita Travkin 	if (!chip)
33759ea3c9fSNikita Travkin 		return -ENOMEM;
33859ea3c9fSNikita Travkin 
33959ea3c9fSNikita Travkin 	mutex_init(&chip->mutex);
34059ea3c9fSNikita Travkin 	mutex_lock(&chip->mutex);
34159ea3c9fSNikita Travkin 
34259ea3c9fSNikita Travkin 	chip->client = client;
34359ea3c9fSNikita Travkin 	i2c_set_clientdata(client, chip);
34459ea3c9fSNikita Travkin 
34559ea3c9fSNikita Travkin 	chip->regmap = devm_regmap_init_i2c(client, &aw2013_regmap_config);
34659ea3c9fSNikita Travkin 	if (IS_ERR(chip->regmap)) {
34759ea3c9fSNikita Travkin 		ret = PTR_ERR(chip->regmap);
34859ea3c9fSNikita Travkin 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
34959ea3c9fSNikita Travkin 			ret);
35059ea3c9fSNikita Travkin 		goto error;
35159ea3c9fSNikita Travkin 	}
35259ea3c9fSNikita Travkin 
353baca986eSLin, Meng-Bo 	chip->regulators[0].supply = "vcc";
354baca986eSLin, Meng-Bo 	chip->regulators[1].supply = "vio";
355baca986eSLin, Meng-Bo 	ret = devm_regulator_bulk_get(&client->dev,
356baca986eSLin, Meng-Bo 				      ARRAY_SIZE(chip->regulators),
357baca986eSLin, Meng-Bo 				      chip->regulators);
358baca986eSLin, Meng-Bo 	if (ret < 0) {
35959ea3c9fSNikita Travkin 		if (ret != -EPROBE_DEFER)
36059ea3c9fSNikita Travkin 			dev_err(&client->dev,
361baca986eSLin, Meng-Bo 				"Failed to request regulators: %d\n", ret);
36259ea3c9fSNikita Travkin 		goto error;
36359ea3c9fSNikita Travkin 	}
36459ea3c9fSNikita Travkin 
365baca986eSLin, Meng-Bo 	ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators),
366baca986eSLin, Meng-Bo 				    chip->regulators);
36759ea3c9fSNikita Travkin 	if (ret) {
36859ea3c9fSNikita Travkin 		dev_err(&client->dev,
369baca986eSLin, Meng-Bo 			"Failed to enable regulators: %d\n", ret);
37059ea3c9fSNikita Travkin 		goto error;
37159ea3c9fSNikita Travkin 	}
37259ea3c9fSNikita Travkin 
37359ea3c9fSNikita Travkin 	ret = regmap_read(chip->regmap, AW2013_RSTR, &chipid);
37459ea3c9fSNikita Travkin 	if (ret) {
37559ea3c9fSNikita Travkin 		dev_err(&client->dev, "Failed to read chip ID: %d\n",
37659ea3c9fSNikita Travkin 			ret);
37759ea3c9fSNikita Travkin 		goto error_reg;
37859ea3c9fSNikita Travkin 	}
37959ea3c9fSNikita Travkin 
38059ea3c9fSNikita Travkin 	if (chipid != AW2013_RSTR_CHIP_ID) {
38159ea3c9fSNikita Travkin 		dev_err(&client->dev, "Chip reported wrong ID: %x\n",
38259ea3c9fSNikita Travkin 			chipid);
38359ea3c9fSNikita Travkin 		ret = -ENODEV;
38459ea3c9fSNikita Travkin 		goto error_reg;
38559ea3c9fSNikita Travkin 	}
38659ea3c9fSNikita Travkin 
38759ea3c9fSNikita Travkin 	ret = aw2013_probe_dt(chip);
38859ea3c9fSNikita Travkin 	if (ret < 0)
38959ea3c9fSNikita Travkin 		goto error_reg;
39059ea3c9fSNikita Travkin 
391baca986eSLin, Meng-Bo 	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
392baca986eSLin, Meng-Bo 				     chip->regulators);
39359ea3c9fSNikita Travkin 	if (ret) {
39459ea3c9fSNikita Travkin 		dev_err(&client->dev,
395baca986eSLin, Meng-Bo 			"Failed to disable regulators: %d\n", ret);
39659ea3c9fSNikita Travkin 		goto error;
39759ea3c9fSNikita Travkin 	}
39859ea3c9fSNikita Travkin 
39959ea3c9fSNikita Travkin 	mutex_unlock(&chip->mutex);
40059ea3c9fSNikita Travkin 
40159ea3c9fSNikita Travkin 	return 0;
40259ea3c9fSNikita Travkin 
40359ea3c9fSNikita Travkin error_reg:
404baca986eSLin, Meng-Bo 	regulator_bulk_disable(ARRAY_SIZE(chip->regulators),
405baca986eSLin, Meng-Bo 			       chip->regulators);
40659ea3c9fSNikita Travkin 
40759ea3c9fSNikita Travkin error:
408*e3f63060SGeorge Stark 	mutex_unlock(&chip->mutex);
40959ea3c9fSNikita Travkin 	mutex_destroy(&chip->mutex);
41059ea3c9fSNikita Travkin 	return ret;
41159ea3c9fSNikita Travkin }
41259ea3c9fSNikita Travkin 
aw2013_remove(struct i2c_client * client)413ed5c2f5fSUwe Kleine-König static void aw2013_remove(struct i2c_client *client)
41459ea3c9fSNikita Travkin {
41559ea3c9fSNikita Travkin 	struct aw2013 *chip = i2c_get_clientdata(client);
41659ea3c9fSNikita Travkin 
41759ea3c9fSNikita Travkin 	aw2013_chip_disable(chip);
41859ea3c9fSNikita Travkin 
41959ea3c9fSNikita Travkin 	mutex_destroy(&chip->mutex);
42059ea3c9fSNikita Travkin }
42159ea3c9fSNikita Travkin 
42259ea3c9fSNikita Travkin static const struct of_device_id aw2013_match_table[] = {
42359ea3c9fSNikita Travkin 	{ .compatible = "awinic,aw2013", },
42459ea3c9fSNikita Travkin 	{ /* sentinel */ },
42559ea3c9fSNikita Travkin };
42659ea3c9fSNikita Travkin 
42759ea3c9fSNikita Travkin MODULE_DEVICE_TABLE(of, aw2013_match_table);
42859ea3c9fSNikita Travkin 
42959ea3c9fSNikita Travkin static struct i2c_driver aw2013_driver = {
43059ea3c9fSNikita Travkin 	.driver = {
43159ea3c9fSNikita Travkin 		.name = "leds-aw2013",
4323d590af8SZhu Wang 		.of_match_table = aw2013_match_table,
43359ea3c9fSNikita Travkin 	},
434d9ff8a8eSUwe Kleine-König 	.probe = aw2013_probe,
43559ea3c9fSNikita Travkin 	.remove = aw2013_remove,
43659ea3c9fSNikita Travkin };
43759ea3c9fSNikita Travkin 
43859ea3c9fSNikita Travkin module_i2c_driver(aw2013_driver);
43959ea3c9fSNikita Travkin 
44059ea3c9fSNikita Travkin MODULE_AUTHOR("Nikita Travkin <nikitos.tr@gmail.com>");
44159ea3c9fSNikita Travkin MODULE_DESCRIPTION("AW2013 LED driver");
44259ea3c9fSNikita Travkin MODULE_LICENSE("GPL v2");
443