Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2015-16 Golden Delicious Computers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Author: Nikolaus Schaller <hns@goldelico.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * LED driver for the IS31FL319{0,1,3,6,9} to drive 1, 3, 6 or 9 light
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * effect LEDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/leds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /* register numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define IS31FL319X_SHUTDOWN		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define IS31FL319X_CTRL1		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define IS31FL319X_CTRL2		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define IS31FL319X_CONFIG1		0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define IS31FL319X_CONFIG2		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define IS31FL319X_RAMP_MODE		0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define IS31FL319X_BREATH_MASK		0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define IS31FL319X_PWM(channel)		(0x07 + channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define IS31FL319X_DATA_UPDATE		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define IS31FL319X_T0(channel)		(0x11 + channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define IS31FL319X_T123_1		0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define IS31FL319X_T123_2		0x1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define IS31FL319X_T123_3		0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define IS31FL319X_T4(channel)		(0x1d + channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define IS31FL319X_TIME_UPDATE		0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define IS31FL319X_RESET		0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define IS31FL319X_REG_CNT		(IS31FL319X_RESET + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define IS31FL319X_MAX_LEDS		9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) /* CS (Current Setting) in CONFIG2 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define IS31FL319X_CONFIG2_CS_SHIFT	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define IS31FL319X_CONFIG2_CS_MASK	0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define IS31FL319X_CONFIG2_CS_STEP_REF	12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define IS31FL319X_CURRENT_MIN		((u32)5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define IS31FL319X_CURRENT_MAX		((u32)40000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define IS31FL319X_CURRENT_STEP		((u32)5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define IS31FL319X_CURRENT_DEFAULT	((u32)20000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) /* Audio gain in CONFIG2 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define IS31FL319X_AUDIO_GAIN_DB_MAX	((u32)21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define IS31FL319X_AUDIO_GAIN_DB_STEP	((u32)3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * regmap is used as a cache of chip's register space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * to avoid reading back brightness values from chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * which is known to hang.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) struct is31fl319x_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	const struct is31fl319x_chipdef *cdef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct i2c_client               *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct gpio_desc		*shutdown_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct regmap                   *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct mutex                    lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	u32                             audio_gain_db;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct is31fl319x_led {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		struct is31fl319x_chip  *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		struct led_classdev     cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		u32                     max_microamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		bool                    configured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	} leds[IS31FL319X_MAX_LEDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) struct is31fl319x_chipdef {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	int num_leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static const struct is31fl319x_chipdef is31fl3190_cdef = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	.num_leds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static const struct is31fl319x_chipdef is31fl3193_cdef = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	.num_leds = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static const struct is31fl319x_chipdef is31fl3196_cdef = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	.num_leds = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static const struct is31fl319x_chipdef is31fl3199_cdef = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	.num_leds = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static const struct of_device_id of_is31fl319x_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	{ .compatible = "issi,is31fl3190", .data = &is31fl3190_cdef, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	{ .compatible = "issi,is31fl3191", .data = &is31fl3190_cdef, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	{ .compatible = "issi,is31fl3193", .data = &is31fl3193_cdef, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	{ .compatible = "issi,is31fl3196", .data = &is31fl3196_cdef, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	{ .compatible = "issi,is31fl3199", .data = &is31fl3199_cdef, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	{ .compatible = "si-en,sn3199",    .data = &is31fl3199_cdef, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) MODULE_DEVICE_TABLE(of, of_is31fl319x_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int is31fl319x_brightness_set(struct led_classdev *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 				     enum led_brightness brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	struct is31fl319x_led *led = container_of(cdev, struct is31fl319x_led,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 						  cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	struct is31fl319x_chip *is31 = led->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	int chan = led - is31->leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	u8 ctrl1 = 0, ctrl2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	dev_dbg(&is31->client->dev, "%s %d: %d\n", __func__, chan, brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	mutex_lock(&is31->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* update PWM register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	ret = regmap_write(is31->regmap, IS31FL319X_PWM(chan), brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	/* read current brightness of all PWM channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	for (i = 0; i < is31->cdef->num_leds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		unsigned int pwm_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		bool on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		 * since neither cdev nor the chip can provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		 * the current setting, we read from the regmap cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		ret = regmap_read(is31->regmap, IS31FL319X_PWM(i), &pwm_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		dev_dbg(&is31->client->dev, "%s read %d: ret=%d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			__func__, i, ret, pwm_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		on = ret >= 0 && pwm_value > LED_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		if (i < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			ctrl1 |= on << i;       /* 0..2 => bit 0..2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		else if (i < 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			ctrl1 |= on << (i + 1); /* 3..5 => bit 4..6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			ctrl2 |= on << (i - 6); /* 6..8 => bit 0..2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (ctrl1 > 0 || ctrl2 > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		dev_dbg(&is31->client->dev, "power up %02x %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			ctrl1, ctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		regmap_write(is31->regmap, IS31FL319X_CTRL1, ctrl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		regmap_write(is31->regmap, IS31FL319X_CTRL2, ctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		/* update PWMs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		regmap_write(is31->regmap, IS31FL319X_DATA_UPDATE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		/* enable chip from shut down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		ret = regmap_write(is31->regmap, IS31FL319X_SHUTDOWN, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		dev_dbg(&is31->client->dev, "power down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		/* shut down (no need to clear CTRL1/2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		ret = regmap_write(is31->regmap, IS31FL319X_SHUTDOWN, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	mutex_unlock(&is31->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int is31fl319x_parse_child_dt(const struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				     const struct device_node *child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				     struct is31fl319x_led *led)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct led_classdev *cdev = &led->cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (of_property_read_string(child, "label", &cdev->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		cdev->name = child->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	ret = of_property_read_string(child, "linux,default-trigger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 				      &cdev->default_trigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (ret < 0 && ret != -EINVAL) /* is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	led->max_microamp = IS31FL319X_CURRENT_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	ret = of_property_read_u32(child, "led-max-microamp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 				   &led->max_microamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		if (led->max_microamp < IS31FL319X_CURRENT_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			return -EINVAL;	/* not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		led->max_microamp = min(led->max_microamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 					  IS31FL319X_CURRENT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int is31fl319x_parse_dt(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			       struct is31fl319x_chip *is31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	struct device_node *np = dev_of_node(dev), *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	is31->shutdown_gpio = devm_gpiod_get_optional(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 						"shutdown",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 						GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (IS_ERR(is31->shutdown_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		ret = PTR_ERR(is31->shutdown_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		dev_err(dev, "Failed to get shutdown gpio: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	is31->cdef = device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	count = of_get_available_child_count(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	dev_dbg(dev, "probing with %d leds defined in DT\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (!count || count > is31->cdef->num_leds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		dev_err(dev, "Number of leds defined must be between 1 and %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			is31->cdef->num_leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	for_each_available_child_of_node(np, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		struct is31fl319x_led *led;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		ret = of_property_read_u32(child, "reg", &reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			dev_err(dev, "Failed to read led 'reg' property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			goto put_child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		if (reg < 1 || reg > is31->cdef->num_leds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			dev_err(dev, "invalid led reg %u\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			goto put_child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		led = &is31->leds[reg - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		if (led->configured) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			dev_err(dev, "led %u is already configured\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			goto put_child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		ret = is31fl319x_parse_child_dt(dev, child, led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			dev_err(dev, "led %u DT parsing failed\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			goto put_child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		led->configured = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	is31->audio_gain_db = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	ret = of_property_read_u32(np, "audio-gain-db", &is31->audio_gain_db);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		is31->audio_gain_db = min(is31->audio_gain_db,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 					  IS31FL319X_AUDIO_GAIN_DB_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) put_child_node:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static bool is31fl319x_readable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { /* we have no readable registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static bool is31fl319x_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { /* volatile registers are not cached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	case IS31FL319X_DATA_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	case IS31FL319X_TIME_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	case IS31FL319X_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		return true; /* always write-through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static const struct reg_default is31fl319x_reg_defaults[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	{ IS31FL319X_CONFIG1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	{ IS31FL319X_CONFIG2, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	{ IS31FL319X_PWM(0), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	{ IS31FL319X_PWM(1), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	{ IS31FL319X_PWM(2), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	{ IS31FL319X_PWM(3), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	{ IS31FL319X_PWM(4), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	{ IS31FL319X_PWM(5), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	{ IS31FL319X_PWM(6), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	{ IS31FL319X_PWM(7), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	{ IS31FL319X_PWM(8), 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static struct regmap_config regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	.reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	.val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	.max_register = IS31FL319X_REG_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	.cache_type = REGCACHE_FLAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	.readable_reg = is31fl319x_readable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	.volatile_reg = is31fl319x_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	.reg_defaults = is31fl319x_reg_defaults,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	.num_reg_defaults = ARRAY_SIZE(is31fl319x_reg_defaults),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static inline int is31fl319x_microamp_to_cs(struct device *dev, u32 microamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) { /* round down to nearest supported value (range check done by caller) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	u32 step = microamp / IS31FL319X_CURRENT_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	return ((IS31FL319X_CONFIG2_CS_STEP_REF - step) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		IS31FL319X_CONFIG2_CS_MASK) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		IS31FL319X_CONFIG2_CS_SHIFT; /* CS encoding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static inline int is31fl319x_db_to_gain(u32 dezibel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) { /* round down to nearest supported value (range check done by caller) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	return dezibel / IS31FL319X_AUDIO_GAIN_DB_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int is31fl319x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			    const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	struct is31fl319x_chip *is31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	u32 aggregated_led_microamp = IS31FL319X_CURRENT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	is31 = devm_kzalloc(&client->dev, sizeof(*is31), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	if (!is31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	mutex_init(&is31->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	err = is31fl319x_parse_dt(&client->dev, is31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		goto free_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	if (is31->shutdown_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		gpiod_direction_output(is31->shutdown_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		gpiod_direction_output(is31->shutdown_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	is31->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	is31->regmap = devm_regmap_init_i2c(client, &regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	if (IS_ERR(is31->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		dev_err(&client->dev, "failed to allocate register map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		err = PTR_ERR(is31->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		goto free_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	i2c_set_clientdata(client, is31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	/* check for write-reply from chip (we can't read any registers) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	err = regmap_write(is31->regmap, IS31FL319X_RESET, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		dev_err(&client->dev, "no response from chip write: err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		err = -EIO; /* does not answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		goto free_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	 * Kernel conventions require per-LED led-max-microamp property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	 * But the chip does not allow to limit individual LEDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	 * So we take minimum from all subnodes for safety of hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	for (i = 0; i < is31->cdef->num_leds; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		if (is31->leds[i].configured &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		    is31->leds[i].max_microamp < aggregated_led_microamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			aggregated_led_microamp = is31->leds[i].max_microamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	regmap_write(is31->regmap, IS31FL319X_CONFIG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		     is31fl319x_microamp_to_cs(dev, aggregated_led_microamp) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		     is31fl319x_db_to_gain(is31->audio_gain_db));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	for (i = 0; i < is31->cdef->num_leds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		struct is31fl319x_led *led = &is31->leds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		if (!led->configured)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		led->chip = is31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		led->cdev.brightness_set_blocking = is31fl319x_brightness_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		err = devm_led_classdev_register(&client->dev, &led->cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			goto free_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) free_mutex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	mutex_destroy(&is31->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int is31fl319x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	struct is31fl319x_chip *is31 = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	mutex_destroy(&is31->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  * i2c-core (and modalias) requires that id_table be properly filled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  * even though it is not used for DeviceTree based instantiation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static const struct i2c_device_id is31fl319x_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	{ "is31fl3190" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	{ "is31fl3191" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	{ "is31fl3193" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	{ "is31fl3196" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	{ "is31fl3199" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	{ "sn3199" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) MODULE_DEVICE_TABLE(i2c, is31fl319x_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static struct i2c_driver is31fl319x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	.driver   = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		.name           = "leds-is31fl319x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		.of_match_table = of_match_ptr(of_is31fl319x_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	.probe    = is31fl319x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	.remove   = is31fl319x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	.id_table = is31fl319x_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) module_i2c_driver(is31fl319x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) MODULE_AUTHOR("Andrey Utkin <andrey_utkin@fastmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) MODULE_DESCRIPTION("IS31FL319X LED driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) MODULE_LICENSE("GPL v2");