xref: /openbmc/linux/drivers/leds/leds-an30259a.c (revision 2d00f35c55e74fcb5626c9aa336c1ed697cd2ae9)
1*2d00f35cSSimon Shields // SPDX-License-Identifier: GPL-2.0+
2*2d00f35cSSimon Shields //
3*2d00f35cSSimon Shields // Driver for Panasonic AN30259A 3-channel LED driver
4*2d00f35cSSimon Shields //
5*2d00f35cSSimon Shields // Copyright (c) 2018 Simon Shields <simon@lineageos.org>
6*2d00f35cSSimon Shields //
7*2d00f35cSSimon Shields // Datasheet:
8*2d00f35cSSimon Shields // https://www.alliedelec.com/m/d/a9d2b3ee87c2d1a535a41dd747b1c247.pdf
9*2d00f35cSSimon Shields 
10*2d00f35cSSimon Shields #include <linux/i2c.h>
11*2d00f35cSSimon Shields #include <linux/leds.h>
12*2d00f35cSSimon Shields #include <linux/module.h>
13*2d00f35cSSimon Shields #include <linux/mutex.h>
14*2d00f35cSSimon Shields #include <linux/of.h>
15*2d00f35cSSimon Shields #include <linux/regmap.h>
16*2d00f35cSSimon Shields #include <uapi/linux/uleds.h>
17*2d00f35cSSimon Shields 
18*2d00f35cSSimon Shields #define AN30259A_MAX_LEDS 3
19*2d00f35cSSimon Shields 
20*2d00f35cSSimon Shields #define AN30259A_REG_SRESET 0x00
21*2d00f35cSSimon Shields #define AN30259A_LED_SRESET BIT(0)
22*2d00f35cSSimon Shields 
23*2d00f35cSSimon Shields /* LED power registers */
24*2d00f35cSSimon Shields #define AN30259A_REG_LED_ON 0x01
25*2d00f35cSSimon Shields #define AN30259A_LED_EN(x) BIT((x) - 1)
26*2d00f35cSSimon Shields #define AN30259A_LED_SLOPE(x) BIT(((x) - 1) + 4)
27*2d00f35cSSimon Shields 
28*2d00f35cSSimon Shields #define AN30259A_REG_LEDCC(x) (0x03 + ((x) - 1))
29*2d00f35cSSimon Shields 
30*2d00f35cSSimon Shields /* slope control registers */
31*2d00f35cSSimon Shields #define AN30259A_REG_SLOPE(x) (0x06 + ((x) - 1))
32*2d00f35cSSimon Shields #define AN30259A_LED_SLOPETIME1(x) (x)
33*2d00f35cSSimon Shields #define AN30259A_LED_SLOPETIME2(x) ((x) << 4)
34*2d00f35cSSimon Shields 
35*2d00f35cSSimon Shields #define AN30259A_REG_LEDCNT1(x) (0x09 + (4 * ((x) - 1)))
36*2d00f35cSSimon Shields #define AN30259A_LED_DUTYMAX(x) ((x) << 4)
37*2d00f35cSSimon Shields #define AN30259A_LED_DUTYMID(x) (x)
38*2d00f35cSSimon Shields 
39*2d00f35cSSimon Shields #define AN30259A_REG_LEDCNT2(x) (0x0A + (4 * ((x) - 1)))
40*2d00f35cSSimon Shields #define AN30259A_LED_DELAY(x) ((x) << 4)
41*2d00f35cSSimon Shields #define AN30259A_LED_DUTYMIN(x) (x)
42*2d00f35cSSimon Shields 
43*2d00f35cSSimon Shields /* detention time control (length of each slope step) */
44*2d00f35cSSimon Shields #define AN30259A_REG_LEDCNT3(x) (0x0B + (4 * ((x) - 1)))
45*2d00f35cSSimon Shields #define AN30259A_LED_DT1(x) (x)
46*2d00f35cSSimon Shields #define AN30259A_LED_DT2(x) ((x) << 4)
47*2d00f35cSSimon Shields 
48*2d00f35cSSimon Shields #define AN30259A_REG_LEDCNT4(x) (0x0C + (4 * ((x) - 1)))
49*2d00f35cSSimon Shields #define AN30259A_LED_DT3(x) (x)
50*2d00f35cSSimon Shields #define AN30259A_LED_DT4(x) ((x) << 4)
51*2d00f35cSSimon Shields 
52*2d00f35cSSimon Shields #define AN30259A_REG_MAX 0x14
53*2d00f35cSSimon Shields 
54*2d00f35cSSimon Shields #define AN30259A_BLINK_MAX_TIME 7500 /* ms */
55*2d00f35cSSimon Shields #define AN30259A_SLOPE_RESOLUTION 500 /* ms */
56*2d00f35cSSimon Shields 
57*2d00f35cSSimon Shields #define STATE_OFF 0
58*2d00f35cSSimon Shields #define STATE_KEEP 1
59*2d00f35cSSimon Shields #define STATE_ON 2
60*2d00f35cSSimon Shields 
61*2d00f35cSSimon Shields struct an30259a;
62*2d00f35cSSimon Shields 
63*2d00f35cSSimon Shields struct an30259a_led {
64*2d00f35cSSimon Shields 	struct an30259a *chip;
65*2d00f35cSSimon Shields 	struct led_classdev cdev;
66*2d00f35cSSimon Shields 	u32 num;
67*2d00f35cSSimon Shields 	u32 default_state;
68*2d00f35cSSimon Shields 	bool sloping;
69*2d00f35cSSimon Shields 	char label[LED_MAX_NAME_SIZE];
70*2d00f35cSSimon Shields };
71*2d00f35cSSimon Shields 
72*2d00f35cSSimon Shields struct an30259a {
73*2d00f35cSSimon Shields 	struct mutex mutex; /* held when writing to registers */
74*2d00f35cSSimon Shields 	struct i2c_client *client;
75*2d00f35cSSimon Shields 	struct an30259a_led leds[AN30259A_MAX_LEDS];
76*2d00f35cSSimon Shields 	struct regmap *regmap;
77*2d00f35cSSimon Shields 	int num_leds;
78*2d00f35cSSimon Shields };
79*2d00f35cSSimon Shields 
80*2d00f35cSSimon Shields static int an30259a_brightness_set(struct led_classdev *cdev,
81*2d00f35cSSimon Shields 				   enum led_brightness brightness)
82*2d00f35cSSimon Shields {
83*2d00f35cSSimon Shields 	struct an30259a_led *led;
84*2d00f35cSSimon Shields 	int ret;
85*2d00f35cSSimon Shields 	unsigned int led_on;
86*2d00f35cSSimon Shields 
87*2d00f35cSSimon Shields 	led = container_of(cdev, struct an30259a_led, cdev);
88*2d00f35cSSimon Shields 	mutex_lock(&led->chip->mutex);
89*2d00f35cSSimon Shields 
90*2d00f35cSSimon Shields 	ret = regmap_read(led->chip->regmap, AN30259A_REG_LED_ON, &led_on);
91*2d00f35cSSimon Shields 	if (ret)
92*2d00f35cSSimon Shields 		goto error;
93*2d00f35cSSimon Shields 
94*2d00f35cSSimon Shields 	switch (brightness) {
95*2d00f35cSSimon Shields 	case LED_OFF:
96*2d00f35cSSimon Shields 		led_on &= ~AN30259A_LED_EN(led->num);
97*2d00f35cSSimon Shields 		led_on &= ~AN30259A_LED_SLOPE(led->num);
98*2d00f35cSSimon Shields 		led->sloping = false;
99*2d00f35cSSimon Shields 		break;
100*2d00f35cSSimon Shields 	default:
101*2d00f35cSSimon Shields 		led_on |= AN30259A_LED_EN(led->num);
102*2d00f35cSSimon Shields 		if (led->sloping)
103*2d00f35cSSimon Shields 			led_on |= AN30259A_LED_SLOPE(led->num);
104*2d00f35cSSimon Shields 		ret = regmap_write(led->chip->regmap,
105*2d00f35cSSimon Shields 				   AN30259A_REG_LEDCNT1(led->num),
106*2d00f35cSSimon Shields 				   AN30259A_LED_DUTYMAX(0xf) |
107*2d00f35cSSimon Shields 				   AN30259A_LED_DUTYMID(0xf));
108*2d00f35cSSimon Shields 		if (ret)
109*2d00f35cSSimon Shields 			goto error;
110*2d00f35cSSimon Shields 		break;
111*2d00f35cSSimon Shields 	}
112*2d00f35cSSimon Shields 
113*2d00f35cSSimon Shields 	ret = regmap_write(led->chip->regmap, AN30259A_REG_LED_ON, led_on);
114*2d00f35cSSimon Shields 	if (ret)
115*2d00f35cSSimon Shields 		goto error;
116*2d00f35cSSimon Shields 
117*2d00f35cSSimon Shields 	ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCC(led->num),
118*2d00f35cSSimon Shields 			   brightness);
119*2d00f35cSSimon Shields 
120*2d00f35cSSimon Shields error:
121*2d00f35cSSimon Shields 	mutex_unlock(&led->chip->mutex);
122*2d00f35cSSimon Shields 
123*2d00f35cSSimon Shields 	return ret;
124*2d00f35cSSimon Shields }
125*2d00f35cSSimon Shields 
126*2d00f35cSSimon Shields static int an30259a_blink_set(struct led_classdev *cdev,
127*2d00f35cSSimon Shields 			      unsigned long *delay_off, unsigned long *delay_on)
128*2d00f35cSSimon Shields {
129*2d00f35cSSimon Shields 	struct an30259a_led *led;
130*2d00f35cSSimon Shields 	int ret, num;
131*2d00f35cSSimon Shields 	unsigned int led_on;
132*2d00f35cSSimon Shields 	unsigned long off = *delay_off, on = *delay_on;
133*2d00f35cSSimon Shields 
134*2d00f35cSSimon Shields 	led = container_of(cdev, struct an30259a_led, cdev);
135*2d00f35cSSimon Shields 
136*2d00f35cSSimon Shields 	mutex_lock(&led->chip->mutex);
137*2d00f35cSSimon Shields 	num = led->num;
138*2d00f35cSSimon Shields 
139*2d00f35cSSimon Shields 	/* slope time can only be a multiple of 500ms. */
140*2d00f35cSSimon Shields 	if (off % AN30259A_SLOPE_RESOLUTION || on % AN30259A_SLOPE_RESOLUTION) {
141*2d00f35cSSimon Shields 		ret = -EINVAL;
142*2d00f35cSSimon Shields 		goto error;
143*2d00f35cSSimon Shields 	}
144*2d00f35cSSimon Shields 
145*2d00f35cSSimon Shields 	/* up to a maximum of 7500ms. */
146*2d00f35cSSimon Shields 	if (off > AN30259A_BLINK_MAX_TIME || on > AN30259A_BLINK_MAX_TIME) {
147*2d00f35cSSimon Shields 		ret = -EINVAL;
148*2d00f35cSSimon Shields 		goto error;
149*2d00f35cSSimon Shields 	}
150*2d00f35cSSimon Shields 
151*2d00f35cSSimon Shields 	/* if no blink specified, default to 1 Hz. */
152*2d00f35cSSimon Shields 	if (!off && !on) {
153*2d00f35cSSimon Shields 		*delay_off = off = 500;
154*2d00f35cSSimon Shields 		*delay_on = on = 500;
155*2d00f35cSSimon Shields 	}
156*2d00f35cSSimon Shields 
157*2d00f35cSSimon Shields 	/* convert into values the HW will understand. */
158*2d00f35cSSimon Shields 	off /= AN30259A_SLOPE_RESOLUTION;
159*2d00f35cSSimon Shields 	on /= AN30259A_SLOPE_RESOLUTION;
160*2d00f35cSSimon Shields 
161*2d00f35cSSimon Shields 	/* duty min should be zero (=off), delay should be zero. */
162*2d00f35cSSimon Shields 	ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCNT2(num),
163*2d00f35cSSimon Shields 			   AN30259A_LED_DELAY(0) | AN30259A_LED_DUTYMIN(0));
164*2d00f35cSSimon Shields 	if (ret)
165*2d00f35cSSimon Shields 		goto error;
166*2d00f35cSSimon Shields 
167*2d00f35cSSimon Shields 	/* reset detention time (no "breathing" effect). */
168*2d00f35cSSimon Shields 	ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCNT3(num),
169*2d00f35cSSimon Shields 			   AN30259A_LED_DT1(0) | AN30259A_LED_DT2(0));
170*2d00f35cSSimon Shields 	if (ret)
171*2d00f35cSSimon Shields 		goto error;
172*2d00f35cSSimon Shields 	ret = regmap_write(led->chip->regmap, AN30259A_REG_LEDCNT4(num),
173*2d00f35cSSimon Shields 			   AN30259A_LED_DT3(0) | AN30259A_LED_DT4(0));
174*2d00f35cSSimon Shields 	if (ret)
175*2d00f35cSSimon Shields 		goto error;
176*2d00f35cSSimon Shields 
177*2d00f35cSSimon Shields 	/* slope time controls on/off cycle length. */
178*2d00f35cSSimon Shields 	ret = regmap_write(led->chip->regmap, AN30259A_REG_SLOPE(num),
179*2d00f35cSSimon Shields 			   AN30259A_LED_SLOPETIME1(off) |
180*2d00f35cSSimon Shields 			   AN30259A_LED_SLOPETIME2(on));
181*2d00f35cSSimon Shields 	if (ret)
182*2d00f35cSSimon Shields 		goto error;
183*2d00f35cSSimon Shields 
184*2d00f35cSSimon Shields 	/* Finally, enable slope mode. */
185*2d00f35cSSimon Shields 	ret = regmap_read(led->chip->regmap, AN30259A_REG_LED_ON, &led_on);
186*2d00f35cSSimon Shields 	if (ret)
187*2d00f35cSSimon Shields 		goto error;
188*2d00f35cSSimon Shields 
189*2d00f35cSSimon Shields 	led_on |= AN30259A_LED_SLOPE(num) | AN30259A_LED_EN(led->num);
190*2d00f35cSSimon Shields 
191*2d00f35cSSimon Shields 	ret = regmap_write(led->chip->regmap, AN30259A_REG_LED_ON, led_on);
192*2d00f35cSSimon Shields 
193*2d00f35cSSimon Shields 	if (!ret)
194*2d00f35cSSimon Shields 		led->sloping = true;
195*2d00f35cSSimon Shields error:
196*2d00f35cSSimon Shields 	mutex_unlock(&led->chip->mutex);
197*2d00f35cSSimon Shields 
198*2d00f35cSSimon Shields 	return ret;
199*2d00f35cSSimon Shields }
200*2d00f35cSSimon Shields 
201*2d00f35cSSimon Shields static int an30259a_dt_init(struct i2c_client *client,
202*2d00f35cSSimon Shields 			    struct an30259a *chip)
203*2d00f35cSSimon Shields {
204*2d00f35cSSimon Shields 	struct device_node *np = client->dev.of_node, *child;
205*2d00f35cSSimon Shields 	int count, ret;
206*2d00f35cSSimon Shields 	int i = 0;
207*2d00f35cSSimon Shields 	const char *str;
208*2d00f35cSSimon Shields 	struct an30259a_led *led;
209*2d00f35cSSimon Shields 
210*2d00f35cSSimon Shields 	count = of_get_child_count(np);
211*2d00f35cSSimon Shields 	if (!count || count > AN30259A_MAX_LEDS)
212*2d00f35cSSimon Shields 		return -EINVAL;
213*2d00f35cSSimon Shields 
214*2d00f35cSSimon Shields 	for_each_available_child_of_node(np, child) {
215*2d00f35cSSimon Shields 		u32 source;
216*2d00f35cSSimon Shields 
217*2d00f35cSSimon Shields 		ret = of_property_read_u32(child, "reg", &source);
218*2d00f35cSSimon Shields 		if (ret != 0 || !source || source > AN30259A_MAX_LEDS) {
219*2d00f35cSSimon Shields 			dev_err(&client->dev, "Couldn't read LED address: %d\n",
220*2d00f35cSSimon Shields 				ret);
221*2d00f35cSSimon Shields 			count--;
222*2d00f35cSSimon Shields 			continue;
223*2d00f35cSSimon Shields 		}
224*2d00f35cSSimon Shields 
225*2d00f35cSSimon Shields 		led = &chip->leds[i];
226*2d00f35cSSimon Shields 
227*2d00f35cSSimon Shields 		led->num = source;
228*2d00f35cSSimon Shields 		led->chip = chip;
229*2d00f35cSSimon Shields 
230*2d00f35cSSimon Shields 		if (of_property_read_string(child, "label", &str))
231*2d00f35cSSimon Shields 			snprintf(led->label, sizeof(led->label), "an30259a::");
232*2d00f35cSSimon Shields 		else
233*2d00f35cSSimon Shields 			snprintf(led->label, sizeof(led->label), "an30259a:%s",
234*2d00f35cSSimon Shields 				 str);
235*2d00f35cSSimon Shields 
236*2d00f35cSSimon Shields 		led->cdev.name = led->label;
237*2d00f35cSSimon Shields 
238*2d00f35cSSimon Shields 		if (!of_property_read_string(child, "default-state", &str)) {
239*2d00f35cSSimon Shields 			if (!strcmp(str, "on"))
240*2d00f35cSSimon Shields 				led->default_state = STATE_ON;
241*2d00f35cSSimon Shields 			else if (!strcmp(str, "keep"))
242*2d00f35cSSimon Shields 				led->default_state = STATE_KEEP;
243*2d00f35cSSimon Shields 			else
244*2d00f35cSSimon Shields 				led->default_state = STATE_OFF;
245*2d00f35cSSimon Shields 		}
246*2d00f35cSSimon Shields 
247*2d00f35cSSimon Shields 		of_property_read_string(child, "linux,default-trigger",
248*2d00f35cSSimon Shields 					&led->cdev.default_trigger);
249*2d00f35cSSimon Shields 
250*2d00f35cSSimon Shields 		i++;
251*2d00f35cSSimon Shields 	}
252*2d00f35cSSimon Shields 
253*2d00f35cSSimon Shields 	if (!count)
254*2d00f35cSSimon Shields 		return -EINVAL;
255*2d00f35cSSimon Shields 
256*2d00f35cSSimon Shields 	chip->num_leds = i;
257*2d00f35cSSimon Shields 
258*2d00f35cSSimon Shields 	return 0;
259*2d00f35cSSimon Shields }
260*2d00f35cSSimon Shields 
261*2d00f35cSSimon Shields static const struct regmap_config an30259a_regmap_config = {
262*2d00f35cSSimon Shields 	.reg_bits = 8,
263*2d00f35cSSimon Shields 	.val_bits = 8,
264*2d00f35cSSimon Shields 	.max_register = AN30259A_REG_MAX,
265*2d00f35cSSimon Shields };
266*2d00f35cSSimon Shields 
267*2d00f35cSSimon Shields static void an30259a_init_default_state(struct an30259a_led *led)
268*2d00f35cSSimon Shields {
269*2d00f35cSSimon Shields 	struct an30259a *chip = led->chip;
270*2d00f35cSSimon Shields 	int led_on, err;
271*2d00f35cSSimon Shields 
272*2d00f35cSSimon Shields 	switch (led->default_state) {
273*2d00f35cSSimon Shields 	case STATE_ON:
274*2d00f35cSSimon Shields 		led->cdev.brightness = LED_FULL;
275*2d00f35cSSimon Shields 		break;
276*2d00f35cSSimon Shields 	case STATE_KEEP:
277*2d00f35cSSimon Shields 		err = regmap_read(chip->regmap, AN30259A_REG_LED_ON, &led_on);
278*2d00f35cSSimon Shields 		if (err)
279*2d00f35cSSimon Shields 			break;
280*2d00f35cSSimon Shields 
281*2d00f35cSSimon Shields 		if (!(led_on & AN30259A_LED_EN(led->num))) {
282*2d00f35cSSimon Shields 			led->cdev.brightness = LED_OFF;
283*2d00f35cSSimon Shields 			break;
284*2d00f35cSSimon Shields 		}
285*2d00f35cSSimon Shields 		regmap_read(chip->regmap, AN30259A_REG_LEDCC(led->num),
286*2d00f35cSSimon Shields 			    &led->cdev.brightness);
287*2d00f35cSSimon Shields 		break;
288*2d00f35cSSimon Shields 	default:
289*2d00f35cSSimon Shields 		led->cdev.brightness = LED_OFF;
290*2d00f35cSSimon Shields 	}
291*2d00f35cSSimon Shields 
292*2d00f35cSSimon Shields 	an30259a_brightness_set(&led->cdev, led->cdev.brightness);
293*2d00f35cSSimon Shields }
294*2d00f35cSSimon Shields 
295*2d00f35cSSimon Shields static int an30259a_probe(struct i2c_client *client)
296*2d00f35cSSimon Shields {
297*2d00f35cSSimon Shields 	struct an30259a *chip;
298*2d00f35cSSimon Shields 	int i, err;
299*2d00f35cSSimon Shields 
300*2d00f35cSSimon Shields 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
301*2d00f35cSSimon Shields 	if (!chip)
302*2d00f35cSSimon Shields 		return -ENOMEM;
303*2d00f35cSSimon Shields 
304*2d00f35cSSimon Shields 	err = an30259a_dt_init(client, chip);
305*2d00f35cSSimon Shields 	if (err < 0)
306*2d00f35cSSimon Shields 		return err;
307*2d00f35cSSimon Shields 
308*2d00f35cSSimon Shields 	mutex_init(&chip->mutex);
309*2d00f35cSSimon Shields 	chip->client = client;
310*2d00f35cSSimon Shields 	i2c_set_clientdata(client, chip);
311*2d00f35cSSimon Shields 
312*2d00f35cSSimon Shields 	chip->regmap = devm_regmap_init_i2c(client, &an30259a_regmap_config);
313*2d00f35cSSimon Shields 
314*2d00f35cSSimon Shields 	for (i = 0; i < chip->num_leds; i++) {
315*2d00f35cSSimon Shields 		an30259a_init_default_state(&chip->leds[i]);
316*2d00f35cSSimon Shields 		chip->leds[i].cdev.brightness_set_blocking =
317*2d00f35cSSimon Shields 			an30259a_brightness_set;
318*2d00f35cSSimon Shields 		chip->leds[i].cdev.blink_set = an30259a_blink_set;
319*2d00f35cSSimon Shields 
320*2d00f35cSSimon Shields 		err = devm_led_classdev_register(&client->dev,
321*2d00f35cSSimon Shields 						 &chip->leds[i].cdev);
322*2d00f35cSSimon Shields 		if (err < 0)
323*2d00f35cSSimon Shields 			goto exit;
324*2d00f35cSSimon Shields 	}
325*2d00f35cSSimon Shields 	return 0;
326*2d00f35cSSimon Shields 
327*2d00f35cSSimon Shields exit:
328*2d00f35cSSimon Shields 	mutex_destroy(&chip->mutex);
329*2d00f35cSSimon Shields 	return err;
330*2d00f35cSSimon Shields }
331*2d00f35cSSimon Shields 
332*2d00f35cSSimon Shields static int an30259a_remove(struct i2c_client *client)
333*2d00f35cSSimon Shields {
334*2d00f35cSSimon Shields 	struct an30259a *chip = i2c_get_clientdata(client);
335*2d00f35cSSimon Shields 
336*2d00f35cSSimon Shields 	mutex_destroy(&chip->mutex);
337*2d00f35cSSimon Shields 
338*2d00f35cSSimon Shields 	return 0;
339*2d00f35cSSimon Shields }
340*2d00f35cSSimon Shields 
341*2d00f35cSSimon Shields static const struct of_device_id an30259a_match_table[] = {
342*2d00f35cSSimon Shields 	{ .compatible = "panasonic,an30259a", },
343*2d00f35cSSimon Shields 	{ /* sentinel */ },
344*2d00f35cSSimon Shields };
345*2d00f35cSSimon Shields 
346*2d00f35cSSimon Shields MODULE_DEVICE_TABLE(of, an30259a_match_table);
347*2d00f35cSSimon Shields 
348*2d00f35cSSimon Shields static const struct i2c_device_id an30259a_id[] = {
349*2d00f35cSSimon Shields 	{ "an30259a", 0 },
350*2d00f35cSSimon Shields 	{ /* sentinel */ },
351*2d00f35cSSimon Shields };
352*2d00f35cSSimon Shields MODULE_DEVICE_TABLE(i2c, an30259a_id);
353*2d00f35cSSimon Shields 
354*2d00f35cSSimon Shields static struct i2c_driver an30259a_driver = {
355*2d00f35cSSimon Shields 	.driver = {
356*2d00f35cSSimon Shields 		.name = "leds-an32059a",
357*2d00f35cSSimon Shields 		.of_match_table = of_match_ptr(an30259a_match_table),
358*2d00f35cSSimon Shields 	},
359*2d00f35cSSimon Shields 	.probe_new = an30259a_probe,
360*2d00f35cSSimon Shields 	.remove = an30259a_remove,
361*2d00f35cSSimon Shields 	.id_table = an30259a_id,
362*2d00f35cSSimon Shields };
363*2d00f35cSSimon Shields 
364*2d00f35cSSimon Shields module_i2c_driver(an30259a_driver);
365*2d00f35cSSimon Shields 
366*2d00f35cSSimon Shields MODULE_AUTHOR("Simon Shields <simon@lineageos.org>");
367*2d00f35cSSimon Shields MODULE_DESCRIPTION("AN32059A LED driver");
368*2d00f35cSSimon Shields MODULE_LICENSE("GPL v2");
369