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