blob: 096ad39cba4b676a084acd9b33171e163ca84644 [file] [log] [blame]
David Collins8885f792017-01-26 14:36:34 -08001/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "flashv2: %s: " fmt, __func__
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/errno.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/of.h>
22#include <linux/of_irq.h>
23#include <linux/of_gpio.h>
24#include <linux/gpio.h>
25#include <linux/regmap.h>
26#include <linux/power_supply.h>
27#include <linux/platform_device.h>
28#include <linux/interrupt.h>
29#include <linux/regulator/consumer.h>
30#include <linux/leds-qpnp-flash.h>
31#include <linux/leds-qpnp-flash-v2.h>
32#include <linux/qpnp/qpnp-revid.h>
33#include <linux/log2.h>
34#include "leds.h"
35
36#define FLASH_LED_REG_LED_STATUS1(base) (base + 0x08)
37#define FLASH_LED_REG_LED_STATUS2(base) (base + 0x09)
38#define FLASH_LED_REG_INT_RT_STS(base) (base + 0x10)
39#define FLASH_LED_REG_SAFETY_TMR(base) (base + 0x40)
40#define FLASH_LED_REG_TGR_CURRENT(base) (base + 0x43)
41#define FLASH_LED_REG_MOD_CTRL(base) (base + 0x46)
42#define FLASH_LED_REG_IRES(base) (base + 0x47)
43#define FLASH_LED_REG_STROBE_CFG(base) (base + 0x48)
44#define FLASH_LED_REG_STROBE_CTRL(base) (base + 0x49)
45#define FLASH_LED_EN_LED_CTRL(base) (base + 0x4C)
46#define FLASH_LED_REG_HDRM_PRGM(base) (base + 0x4D)
47#define FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(base) (base + 0x50)
48#define FLASH_LED_REG_WARMUP_DELAY(base) (base + 0x51)
49#define FLASH_LED_REG_ISC_DELAY(base) (base + 0x52)
50#define FLASH_LED_REG_THERMAL_RMP_DN_RATE(base) (base + 0x55)
51#define FLASH_LED_REG_THERMAL_THRSH1(base) (base + 0x56)
52#define FLASH_LED_REG_THERMAL_THRSH2(base) (base + 0x57)
53#define FLASH_LED_REG_THERMAL_THRSH3(base) (base + 0x58)
54#define FLASH_LED_REG_THERMAL_HYSTERESIS(base) (base + 0x59)
55#define FLASH_LED_REG_THERMAL_DEBOUNCE(base) (base + 0x5A)
56#define FLASH_LED_REG_VPH_DROOP_THRESHOLD(base) (base + 0x61)
57#define FLASH_LED_REG_VPH_DROOP_DEBOUNCE(base) (base + 0x62)
58#define FLASH_LED_REG_ILED_GRT_THRSH(base) (base + 0x67)
59#define FLASH_LED_REG_LED1N2_ICLAMP_LOW(base) (base + 0x68)
60#define FLASH_LED_REG_LED1N2_ICLAMP_MID(base) (base + 0x69)
61#define FLASH_LED_REG_LED3_ICLAMP_LOW(base) (base + 0x6A)
62#define FLASH_LED_REG_LED3_ICLAMP_MID(base) (base + 0x6B)
63#define FLASH_LED_REG_MITIGATION_SEL(base) (base + 0x6E)
64#define FLASH_LED_REG_MITIGATION_SW(base) (base + 0x6F)
65#define FLASH_LED_REG_LMH_LEVEL(base) (base + 0x70)
66#define FLASH_LED_REG_CURRENT_DERATE_EN(base) (base + 0x76)
67
68#define FLASH_LED_HDRM_VOL_MASK GENMASK(7, 4)
69#define FLASH_LED_CURRENT_MASK GENMASK(6, 0)
70#define FLASH_LED_ENABLE_MASK GENMASK(2, 0)
71#define FLASH_HW_STROBE_MASK GENMASK(2, 0)
72#define FLASH_LED_ISC_WARMUP_DELAY_MASK GENMASK(1, 0)
73#define FLASH_LED_CURRENT_DERATE_EN_MASK GENMASK(2, 0)
74#define FLASH_LED_VPH_DROOP_DEBOUNCE_MASK GENMASK(1, 0)
75#define FLASH_LED_CHGR_MITIGATION_SEL_MASK GENMASK(5, 4)
76#define FLASH_LED_LMH_MITIGATION_SEL_MASK GENMASK(1, 0)
77#define FLASH_LED_ILED_GRT_THRSH_MASK GENMASK(5, 0)
78#define FLASH_LED_LMH_LEVEL_MASK GENMASK(1, 0)
79#define FLASH_LED_VPH_DROOP_HYSTERESIS_MASK GENMASK(5, 4)
80#define FLASH_LED_VPH_DROOP_THRESHOLD_MASK GENMASK(2, 0)
81#define FLASH_LED_THERMAL_HYSTERESIS_MASK GENMASK(1, 0)
82#define FLASH_LED_THERMAL_DEBOUNCE_MASK GENMASK(1, 0)
83#define FLASH_LED_THERMAL_THRSH_MASK GENMASK(2, 0)
84#define FLASH_LED_MOD_CTRL_MASK BIT(7)
85#define FLASH_LED_HW_SW_STROBE_SEL_BIT BIT(2)
86#define FLASH_LED_VPH_DROOP_FAULT_MASK BIT(4)
87#define FLASH_LED_LMH_MITIGATION_EN_MASK BIT(0)
88#define FLASH_LED_CHGR_MITIGATION_EN_MASK BIT(4)
89#define THERMAL_OTST1_RAMP_CTRL_MASK BIT(7)
90#define THERMAL_OTST1_RAMP_CTRL_SHIFT 7
91#define THERMAL_DERATE_SLOW_SHIFT 4
92#define THERMAL_DERATE_SLOW_MASK GENMASK(6, 4)
93#define THERMAL_DERATE_FAST_MASK GENMASK(2, 0)
94
95#define VPH_DROOP_DEBOUNCE_US_TO_VAL(val_us) (val_us / 8)
96#define VPH_DROOP_HYST_MV_TO_VAL(val_mv) (val_mv / 25)
97#define VPH_DROOP_THRESH_MV_TO_VAL(val_mv) ((val_mv / 100) - 25)
98#define VPH_DROOP_THRESH_VAL_TO_UV(val) ((val + 25) * 100000)
99#define MITIGATION_THRSH_MA_TO_VAL(val_ma) (val_ma / 100)
100#define CURRENT_MA_TO_REG_VAL(curr_ma, ires_ua) ((curr_ma * 1000) / ires_ua - 1)
101#define SAFETY_TMR_TO_REG_VAL(duration_ms) ((duration_ms / 10) - 1)
102#define THERMAL_HYST_TEMP_TO_VAL(val, divisor) (val / divisor)
103
104#define FLASH_LED_ISC_WARMUP_DELAY_SHIFT 6
105#define FLASH_LED_WARMUP_DELAY_DEFAULT 2
106#define FLASH_LED_ISC_DELAY_DEFAULT 3
107#define FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT 2
108#define FLASH_LED_VPH_DROOP_HYST_SHIFT 4
109#define FLASH_LED_VPH_DROOP_HYST_DEFAULT 2
110#define FLASH_LED_VPH_DROOP_THRESH_DEFAULT 5
111#define FLASH_LED_DEBOUNCE_MAX 3
112#define FLASH_LED_HYSTERESIS_MAX 3
113#define FLASH_LED_VPH_DROOP_THRESH_MAX 7
114#define THERMAL_DERATE_SLOW_MAX 314592
115#define THERMAL_DERATE_FAST_MAX 512
116#define THERMAL_DEBOUNCE_TIME_MAX 64
117#define THERMAL_DERATE_HYSTERESIS_MAX 3
118#define FLASH_LED_THERMAL_THRSH_MIN 3
119#define FLASH_LED_THERMAL_THRSH_MAX 7
120#define FLASH_LED_THERMAL_OTST_LEVELS 3
121#define FLASH_LED_VLED_MAX_DEFAULT_UV 3500000
122#define FLASH_LED_IBATT_OCP_THRESH_DEFAULT_UA 4500000
123#define FLASH_LED_RPARA_DEFAULT_UOHM 0
124#define FLASH_LED_SAFETY_TMR_ENABLE BIT(7)
125#define FLASH_LED_LMH_LEVEL_DEFAULT 0
126#define FLASH_LED_LMH_MITIGATION_ENABLE 1
127#define FLASH_LED_LMH_MITIGATION_DISABLE 0
128#define FLASH_LED_CHGR_MITIGATION_ENABLE BIT(4)
129#define FLASH_LED_CHGR_MITIGATION_DISABLE 0
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530130#define FLASH_LED_LMH_MITIGATION_SEL_DEFAULT 2
David Collins8885f792017-01-26 14:36:34 -0800131#define FLASH_LED_MITIGATION_SEL_MAX 2
132#define FLASH_LED_CHGR_MITIGATION_SEL_SHIFT 4
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530133#define FLASH_LED_CHGR_MITIGATION_THRSH_DEFAULT 0xA
134#define FLASH_LED_CHGR_MITIGATION_THRSH_MAX 0x1F
David Collins8885f792017-01-26 14:36:34 -0800135#define FLASH_LED_LMH_OCV_THRESH_DEFAULT_UV 3700000
136#define FLASH_LED_LMH_RBATT_THRESH_DEFAULT_UOHM 400000
137#define FLASH_LED_IRES_BASE 3
138#define FLASH_LED_IRES_DIVISOR 2500
139#define FLASH_LED_IRES_MIN_UA 5000
140#define FLASH_LED_IRES_DEFAULT_UA 12500
141#define FLASH_LED_IRES_DEFAULT_VAL 0x00
142#define FLASH_LED_HDRM_VOL_SHIFT 4
143#define FLASH_LED_HDRM_VOL_DEFAULT_MV 0x80
144#define FLASH_LED_HDRM_VOL_HI_LO_WIN_DEFAULT_MV 0x04
145#define FLASH_LED_HDRM_VOL_BASE_MV 125
146#define FLASH_LED_HDRM_VOL_STEP_MV 25
147#define FLASH_LED_STROBE_CFG_DEFAULT 0x00
148#define FLASH_LED_HW_STROBE_OPTION_1 0x00
149#define FLASH_LED_HW_STROBE_OPTION_2 0x01
150#define FLASH_LED_HW_STROBE_OPTION_3 0x02
151#define FLASH_LED_ENABLE BIT(0)
152#define FLASH_LED_MOD_ENABLE BIT(7)
153#define FLASH_LED_DISABLE 0x00
154#define FLASH_LED_SAFETY_TMR_DISABLED 0x13
David Collins8885f792017-01-26 14:36:34 -0800155#define FLASH_LED_MAX_TOTAL_CURRENT_MA 3750
156
157/* notifier call chain for flash-led irqs */
158static ATOMIC_NOTIFIER_HEAD(irq_notifier_list);
159
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530160enum flash_charger_mitigation {
161 FLASH_DISABLE_CHARGER_MITIGATION,
162 FLASH_HW_CHARGER_MITIGATION_BY_ILED_THRSHLD,
163 FLASH_SW_CHARGER_MITIGATION,
164};
165
David Collins8885f792017-01-26 14:36:34 -0800166enum flash_led_type {
167 FLASH_LED_TYPE_FLASH,
168 FLASH_LED_TYPE_TORCH,
169};
170
171enum {
172 LED1 = 0,
173 LED2,
174 LED3,
175};
176
177/*
178 * Configurations for each individual LED
179 */
180struct flash_node_data {
181 struct platform_device *pdev;
182 struct led_classdev cdev;
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -0700183 struct pinctrl *strobe_pinctrl;
David Collins8885f792017-01-26 14:36:34 -0800184 struct pinctrl_state *hw_strobe_state_active;
185 struct pinctrl_state *hw_strobe_state_suspend;
186 int hw_strobe_gpio;
187 int ires_ua;
188 int max_current;
189 int current_ma;
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530190 int prev_current_ma;
David Collins8885f792017-01-26 14:36:34 -0800191 u8 duration;
192 u8 id;
193 u8 type;
194 u8 ires;
195 u8 hdrm_val;
196 u8 current_reg_val;
197 u8 trigger;
198 bool led_on;
199};
200
201
202struct flash_switch_data {
203 struct platform_device *pdev;
204 struct regulator *vreg;
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -0700205 struct pinctrl *led_en_pinctrl;
206 struct pinctrl_state *gpio_state_active;
207 struct pinctrl_state *gpio_state_suspend;
David Collins8885f792017-01-26 14:36:34 -0800208 struct led_classdev cdev;
209 int led_mask;
210 bool regulator_on;
211 bool enabled;
212};
213
214/*
215 * Flash LED configuration read from device tree
216 */
217struct flash_led_platform_data {
218 struct pmic_revid_data *pmic_rev_id;
219 int *thermal_derate_current;
220 int all_ramp_up_done_irq;
221 int all_ramp_down_done_irq;
222 int led_fault_irq;
223 int ibatt_ocp_threshold_ua;
224 int vled_max_uv;
225 int rpara_uohm;
226 int lmh_rbatt_threshold_uohm;
227 int lmh_ocv_threshold_uv;
228 int thermal_derate_slow;
229 int thermal_derate_fast;
230 int thermal_hysteresis;
231 int thermal_debounce;
232 int thermal_thrsh1;
233 int thermal_thrsh2;
234 int thermal_thrsh3;
235 u32 led1n2_iclamp_low_ma;
236 u32 led1n2_iclamp_mid_ma;
237 u32 led3_iclamp_low_ma;
238 u32 led3_iclamp_mid_ma;
239 u8 isc_delay;
240 u8 warmup_delay;
241 u8 current_derate_en_cfg;
242 u8 vph_droop_threshold;
243 u8 vph_droop_hysteresis;
244 u8 vph_droop_debounce;
245 u8 lmh_mitigation_sel;
246 u8 chgr_mitigation_sel;
247 u8 lmh_level;
248 u8 iled_thrsh_val;
249 u8 hw_strobe_option;
250 bool hdrm_auto_mode_en;
251 bool thermal_derate_en;
252 bool otst_ramp_bkup_en;
253};
254
255/*
256 * Flash LED data structure containing flash LED attributes
257 */
258struct qpnp_flash_led {
259 struct flash_led_platform_data *pdata;
260 struct platform_device *pdev;
261 struct regmap *regmap;
262 struct flash_node_data *fnode;
263 struct flash_switch_data *snode;
264 struct power_supply *bms_psy;
265 struct notifier_block nb;
266 spinlock_t lock;
267 int num_fnodes;
268 int num_snodes;
269 int enable;
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530270 int total_current_ma;
David Collins8885f792017-01-26 14:36:34 -0800271 u16 base;
272 bool trigger_lmh;
273 bool trigger_chgr;
274};
275
276static int thermal_derate_slow_table[] = {
277 128, 256, 512, 1024, 2048, 4096, 8192, 314592,
278};
279
280static int thermal_derate_fast_table[] = {
281 32, 64, 96, 128, 256, 384, 512,
282};
283
284static int otst1_threshold_table[] = {
285 85, 79, 73, 67, 109, 103, 97, 91,
286};
287
288static int otst2_threshold_table[] = {
289 110, 104, 98, 92, 134, 128, 122, 116,
290};
291
292static int otst3_threshold_table[] = {
293 125, 119, 113, 107, 149, 143, 137, 131,
294};
295
296static int qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data)
297{
298 int rc;
299 uint val;
300
301 rc = regmap_read(led->regmap, addr, &val);
302 if (rc < 0) {
303 pr_err("Unable to read from 0x%04X rc = %d\n", addr, rc);
304 return rc;
305 }
306
307 pr_debug("Read 0x%02X from addr 0x%04X\n", val, addr);
308 *data = (u8)val;
309 return 0;
310}
311
312static int qpnp_flash_led_write(struct qpnp_flash_led *led, u16 addr, u8 data)
313{
314 int rc;
315
316 rc = regmap_write(led->regmap, addr, data);
317 if (rc < 0) {
318 pr_err("Unable to write to 0x%04X rc = %d\n", addr, rc);
319 return rc;
320 }
321
322 pr_debug("Wrote 0x%02X to addr 0x%04X\n", data, addr);
323 return 0;
324}
325
326static int
327qpnp_flash_led_masked_read(struct qpnp_flash_led *led, u16 addr, u8 mask,
328 u8 *val)
329{
330 int rc;
331
332 rc = qpnp_flash_led_read(led, addr, val);
333 if (rc < 0)
334 return rc;
335
336 *val &= mask;
337 return rc;
338}
339
340static int
341qpnp_flash_led_masked_write(struct qpnp_flash_led *led, u16 addr, u8 mask,
342 u8 val)
343{
344 int rc;
345
346 rc = regmap_update_bits(led->regmap, addr, mask, val);
347 if (rc < 0)
348 pr_err("Unable to update bits from 0x%04X, rc = %d\n", addr,
349 rc);
350 else
351 pr_debug("Wrote 0x%02X to addr 0x%04X\n", val, addr);
352
353 return rc;
354}
355
356static enum
357led_brightness qpnp_flash_led_brightness_get(struct led_classdev *led_cdev)
358{
359 return led_cdev->brightness;
360}
361
362static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
363{
364 int rc, i, addr_offset;
365 u8 val = 0, mask;
366
367 for (i = 0; i < led->num_fnodes; i++) {
368 addr_offset = led->fnode[i].id;
369 rc = qpnp_flash_led_write(led,
370 FLASH_LED_REG_HDRM_PRGM(led->base + addr_offset),
371 led->fnode[i].hdrm_val);
372 if (rc < 0)
373 return rc;
374
375 val |= 0x1 << led->fnode[i].id;
376 }
377
378 rc = qpnp_flash_led_write(led,
379 FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(led->base),
380 val);
381 if (rc < 0)
382 return rc;
383
384 rc = qpnp_flash_led_masked_write(led,
385 FLASH_LED_REG_ISC_DELAY(led->base),
386 FLASH_LED_ISC_WARMUP_DELAY_MASK,
387 led->pdata->isc_delay);
388 if (rc < 0)
389 return rc;
390
391 rc = qpnp_flash_led_masked_write(led,
392 FLASH_LED_REG_WARMUP_DELAY(led->base),
393 FLASH_LED_ISC_WARMUP_DELAY_MASK,
394 led->pdata->warmup_delay);
395 if (rc < 0)
396 return rc;
397
398 rc = qpnp_flash_led_masked_write(led,
399 FLASH_LED_REG_CURRENT_DERATE_EN(led->base),
400 FLASH_LED_CURRENT_DERATE_EN_MASK,
401 led->pdata->current_derate_en_cfg);
402 if (rc < 0)
403 return rc;
404
405 val = (led->pdata->otst_ramp_bkup_en << THERMAL_OTST1_RAMP_CTRL_SHIFT);
406 mask = THERMAL_OTST1_RAMP_CTRL_MASK;
407 if (led->pdata->thermal_derate_slow >= 0) {
408 val |= (led->pdata->thermal_derate_slow <<
409 THERMAL_DERATE_SLOW_SHIFT);
410 mask |= THERMAL_DERATE_SLOW_MASK;
411 }
412
413 if (led->pdata->thermal_derate_fast >= 0) {
414 val |= led->pdata->thermal_derate_fast;
415 mask |= THERMAL_DERATE_FAST_MASK;
416 }
417
418 rc = qpnp_flash_led_masked_write(led,
419 FLASH_LED_REG_THERMAL_RMP_DN_RATE(led->base),
420 mask, val);
421 if (rc < 0)
422 return rc;
423
424 if (led->pdata->thermal_debounce >= 0) {
425 rc = qpnp_flash_led_masked_write(led,
426 FLASH_LED_REG_THERMAL_DEBOUNCE(led->base),
427 FLASH_LED_THERMAL_DEBOUNCE_MASK,
428 led->pdata->thermal_debounce);
429 if (rc < 0)
430 return rc;
431 }
432
433 if (led->pdata->thermal_hysteresis >= 0) {
434 rc = qpnp_flash_led_masked_write(led,
435 FLASH_LED_REG_THERMAL_HYSTERESIS(led->base),
436 FLASH_LED_THERMAL_HYSTERESIS_MASK,
437 led->pdata->thermal_hysteresis);
438 if (rc < 0)
439 return rc;
440 }
441
442 if (led->pdata->thermal_thrsh1 >= 0) {
443 rc = qpnp_flash_led_masked_write(led,
444 FLASH_LED_REG_THERMAL_THRSH1(led->base),
445 FLASH_LED_THERMAL_THRSH_MASK,
446 led->pdata->thermal_thrsh1);
447 if (rc < 0)
448 return rc;
449 }
450
451 if (led->pdata->thermal_thrsh2 >= 0) {
452 rc = qpnp_flash_led_masked_write(led,
453 FLASH_LED_REG_THERMAL_THRSH2(led->base),
454 FLASH_LED_THERMAL_THRSH_MASK,
455 led->pdata->thermal_thrsh2);
456 if (rc < 0)
457 return rc;
458 }
459
460 if (led->pdata->thermal_thrsh3 >= 0) {
461 rc = qpnp_flash_led_masked_write(led,
462 FLASH_LED_REG_THERMAL_THRSH3(led->base),
463 FLASH_LED_THERMAL_THRSH_MASK,
464 led->pdata->thermal_thrsh3);
465 if (rc < 0)
466 return rc;
467 }
468
469 rc = qpnp_flash_led_masked_write(led,
470 FLASH_LED_REG_VPH_DROOP_DEBOUNCE(led->base),
471 FLASH_LED_VPH_DROOP_DEBOUNCE_MASK,
472 led->pdata->vph_droop_debounce);
473 if (rc < 0)
474 return rc;
475
476 rc = qpnp_flash_led_masked_write(led,
477 FLASH_LED_REG_VPH_DROOP_THRESHOLD(led->base),
478 FLASH_LED_VPH_DROOP_THRESHOLD_MASK,
479 led->pdata->vph_droop_threshold);
480 if (rc < 0)
481 return rc;
482
483 rc = qpnp_flash_led_masked_write(led,
484 FLASH_LED_REG_VPH_DROOP_THRESHOLD(led->base),
485 FLASH_LED_VPH_DROOP_HYSTERESIS_MASK,
486 led->pdata->vph_droop_hysteresis);
487 if (rc < 0)
488 return rc;
489
490 rc = qpnp_flash_led_masked_write(led,
491 FLASH_LED_REG_MITIGATION_SEL(led->base),
492 FLASH_LED_LMH_MITIGATION_SEL_MASK,
493 led->pdata->lmh_mitigation_sel);
494 if (rc < 0)
495 return rc;
496
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530497 val = led->pdata->chgr_mitigation_sel
498 << FLASH_LED_CHGR_MITIGATION_SEL_SHIFT;
David Collins8885f792017-01-26 14:36:34 -0800499 rc = qpnp_flash_led_masked_write(led,
500 FLASH_LED_REG_MITIGATION_SEL(led->base),
501 FLASH_LED_CHGR_MITIGATION_SEL_MASK,
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530502 val);
David Collins8885f792017-01-26 14:36:34 -0800503 if (rc < 0)
504 return rc;
505
506 rc = qpnp_flash_led_masked_write(led,
507 FLASH_LED_REG_LMH_LEVEL(led->base),
508 FLASH_LED_LMH_LEVEL_MASK,
509 led->pdata->lmh_level);
510 if (rc < 0)
511 return rc;
512
513 rc = qpnp_flash_led_masked_write(led,
514 FLASH_LED_REG_ILED_GRT_THRSH(led->base),
515 FLASH_LED_ILED_GRT_THRSH_MASK,
516 led->pdata->iled_thrsh_val);
517 if (rc < 0)
518 return rc;
519
520 if (led->pdata->led1n2_iclamp_low_ma) {
521 val = CURRENT_MA_TO_REG_VAL(led->pdata->led1n2_iclamp_low_ma,
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -0700522 led->fnode[LED1].ires_ua);
David Collins8885f792017-01-26 14:36:34 -0800523 rc = qpnp_flash_led_masked_write(led,
524 FLASH_LED_REG_LED1N2_ICLAMP_LOW(led->base),
525 FLASH_LED_CURRENT_MASK, val);
526 if (rc < 0)
527 return rc;
528 }
529
530 if (led->pdata->led1n2_iclamp_mid_ma) {
531 val = CURRENT_MA_TO_REG_VAL(led->pdata->led1n2_iclamp_mid_ma,
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -0700532 led->fnode[LED1].ires_ua);
David Collins8885f792017-01-26 14:36:34 -0800533 rc = qpnp_flash_led_masked_write(led,
534 FLASH_LED_REG_LED1N2_ICLAMP_MID(led->base),
535 FLASH_LED_CURRENT_MASK, val);
536 if (rc < 0)
537 return rc;
538 }
539
540 if (led->pdata->led3_iclamp_low_ma) {
541 val = CURRENT_MA_TO_REG_VAL(led->pdata->led3_iclamp_low_ma,
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -0700542 led->fnode[LED3].ires_ua);
David Collins8885f792017-01-26 14:36:34 -0800543 rc = qpnp_flash_led_masked_write(led,
544 FLASH_LED_REG_LED3_ICLAMP_LOW(led->base),
545 FLASH_LED_CURRENT_MASK, val);
546 if (rc < 0)
547 return rc;
548 }
549
550 if (led->pdata->led3_iclamp_mid_ma) {
551 val = CURRENT_MA_TO_REG_VAL(led->pdata->led3_iclamp_mid_ma,
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -0700552 led->fnode[LED3].ires_ua);
David Collins8885f792017-01-26 14:36:34 -0800553 rc = qpnp_flash_led_masked_write(led,
554 FLASH_LED_REG_LED3_ICLAMP_MID(led->base),
555 FLASH_LED_CURRENT_MASK, val);
556 if (rc < 0)
557 return rc;
558 }
559
560 return 0;
561}
562
563static int qpnp_flash_led_hw_strobe_enable(struct flash_node_data *fnode,
564 int hw_strobe_option, bool on)
565{
566 int rc = 0;
567
568 /*
569 * If the LED controlled by this fnode is not GPIO controlled
570 * for the given strobe_option, return.
571 */
572 if (hw_strobe_option == FLASH_LED_HW_STROBE_OPTION_1)
573 return 0;
574 else if (hw_strobe_option == FLASH_LED_HW_STROBE_OPTION_2
575 && fnode->id != LED3)
576 return 0;
577 else if (hw_strobe_option == FLASH_LED_HW_STROBE_OPTION_3
578 && fnode->id == LED1)
579 return 0;
580
581 if (gpio_is_valid(fnode->hw_strobe_gpio)) {
582 gpio_set_value(fnode->hw_strobe_gpio, on ? 1 : 0);
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -0700583 } else if (fnode->strobe_pinctrl && fnode->hw_strobe_state_active &&
David Collins8885f792017-01-26 14:36:34 -0800584 fnode->hw_strobe_state_suspend) {
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -0700585 rc = pinctrl_select_state(fnode->strobe_pinctrl,
David Collins8885f792017-01-26 14:36:34 -0800586 on ? fnode->hw_strobe_state_active :
587 fnode->hw_strobe_state_suspend);
588 if (rc < 0) {
589 pr_err("failed to change hw strobe pin state\n");
590 return rc;
591 }
592 }
593
594 return rc;
595}
596
597static int qpnp_flash_led_regulator_enable(struct qpnp_flash_led *led,
598 struct flash_switch_data *snode, bool on)
599{
600 int rc = 0;
601
602 if (!snode || !snode->vreg)
603 return 0;
604
605 if (snode->regulator_on == on)
606 return 0;
607
608 if (on)
609 rc = regulator_enable(snode->vreg);
610 else
611 rc = regulator_disable(snode->vreg);
612
613 if (rc < 0) {
614 pr_err("regulator_%s failed, rc=%d\n",
615 on ? "enable" : "disable", rc);
616 return rc;
617 }
618
619 snode->regulator_on = on ? true : false;
620 return 0;
621}
622
623static int get_property_from_fg(struct qpnp_flash_led *led,
624 enum power_supply_property prop, int *val)
625{
626 int rc;
627 union power_supply_propval pval = {0, };
628
629 if (!led->bms_psy) {
630 pr_err("no bms psy found\n");
631 return -EINVAL;
632 }
633
634 rc = power_supply_get_property(led->bms_psy, prop, &pval);
635 if (rc) {
636 pr_err("bms psy doesn't support reading prop %d rc = %d\n",
637 prop, rc);
638 return rc;
639 }
640
641 *val = pval.intval;
642 return rc;
643}
644
645#define VOLTAGE_HDRM_DEFAULT_MV 350
646static int qpnp_flash_led_get_voltage_headroom(struct qpnp_flash_led *led)
647{
648 int i, voltage_hdrm_mv = 0, voltage_hdrm_max = 0;
649
650 for (i = 0; i < led->num_fnodes; i++) {
651 if (led->fnode[i].led_on) {
652 if (led->fnode[i].id < 2) {
653 if (led->fnode[i].current_ma < 750)
654 voltage_hdrm_mv = 125;
655 else if (led->fnode[i].current_ma < 1000)
656 voltage_hdrm_mv = 175;
657 else if (led->fnode[i].current_ma < 1250)
658 voltage_hdrm_mv = 250;
659 else
660 voltage_hdrm_mv = 350;
661 } else {
662 if (led->fnode[i].current_ma < 375)
663 voltage_hdrm_mv = 125;
664 else if (led->fnode[i].current_ma < 500)
665 voltage_hdrm_mv = 175;
666 else if (led->fnode[i].current_ma < 625)
667 voltage_hdrm_mv = 250;
668 else
669 voltage_hdrm_mv = 350;
670 }
671
672 voltage_hdrm_max = max(voltage_hdrm_max,
673 voltage_hdrm_mv);
674 }
675 }
676
677 if (!voltage_hdrm_max)
678 return VOLTAGE_HDRM_DEFAULT_MV;
679
680 return voltage_hdrm_max;
681}
682
683#define UCONV 1000000LL
684#define MCONV 1000LL
685#define FLASH_VDIP_MARGIN 50000
686#define BOB_EFFICIENCY 900LL
687#define VIN_FLASH_MIN_UV 3300000LL
688static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
689{
Kyle Yan74fdd732017-03-22 13:37:08 -0700690 int ocv_uv, ibat_now, voltage_hdrm_mv, rc;
691 int rbatt_uohm = 0;
David Collins8885f792017-01-26 14:36:34 -0800692 int64_t ibat_flash_ua, avail_flash_ua, avail_flash_power_fw;
693 int64_t ibat_safe_ua, vin_flash_uv, vph_flash_uv, vph_flash_vdip;
694
695 /* RESISTANCE = esr_uohm + rslow_uohm */
696 rc = get_property_from_fg(led, POWER_SUPPLY_PROP_RESISTANCE,
697 &rbatt_uohm);
698 if (rc < 0) {
699 pr_err("bms psy does not support resistance, rc=%d\n", rc);
700 return rc;
701 }
702
703 /* If no battery is connected, return max possible flash current */
704 if (!rbatt_uohm)
705 return FLASH_LED_MAX_TOTAL_CURRENT_MA;
706
707 rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv);
708 if (rc < 0) {
709 pr_err("bms psy does not support OCV, rc=%d\n", rc);
710 return rc;
711 }
712
713 rc = get_property_from_fg(led, POWER_SUPPLY_PROP_CURRENT_NOW,
714 &ibat_now);
715 if (rc < 0) {
716 pr_err("bms psy does not support current, rc=%d\n", rc);
717 return rc;
718 }
719
720 rbatt_uohm += led->pdata->rpara_uohm;
721 voltage_hdrm_mv = qpnp_flash_led_get_voltage_headroom(led);
722 vph_flash_vdip =
723 VPH_DROOP_THRESH_VAL_TO_UV(led->pdata->vph_droop_threshold)
724 + FLASH_VDIP_MARGIN;
725
726 /* Check if LMH_MITIGATION needs to be triggered */
727 if (!led->trigger_lmh && (ocv_uv < led->pdata->lmh_ocv_threshold_uv ||
728 rbatt_uohm > led->pdata->lmh_rbatt_threshold_uohm)) {
729 led->trigger_lmh = true;
730 rc = qpnp_flash_led_masked_write(led,
731 FLASH_LED_REG_MITIGATION_SW(led->base),
732 FLASH_LED_LMH_MITIGATION_EN_MASK,
733 FLASH_LED_LMH_MITIGATION_ENABLE);
734 if (rc < 0) {
735 pr_err("trigger lmh mitigation failed, rc=%d\n", rc);
736 return rc;
737 }
738
739 /* Wait for LMH mitigation to take effect */
740 udelay(100);
741
742 return qpnp_flash_led_calc_max_current(led);
743 }
744
745 /*
746 * Calculate the maximum current that can pulled out of the battery
747 * before the battery voltage dips below a safe threshold.
748 */
749 ibat_safe_ua = div_s64((ocv_uv - vph_flash_vdip) * UCONV,
750 rbatt_uohm);
751
752 if (ibat_safe_ua <= led->pdata->ibatt_ocp_threshold_ua) {
753 /*
754 * If the calculated current is below the OCP threshold, then
755 * use it as the possible flash current.
756 */
757 ibat_flash_ua = ibat_safe_ua - ibat_now;
758 vph_flash_uv = vph_flash_vdip;
759 } else {
760 /*
761 * If the calculated current is above the OCP threshold, then
762 * use the ocp threshold instead.
763 *
764 * Any higher current will be tripping the battery OCP.
765 */
766 ibat_flash_ua = led->pdata->ibatt_ocp_threshold_ua - ibat_now;
767 vph_flash_uv = ocv_uv - div64_s64((int64_t)rbatt_uohm
768 * led->pdata->ibatt_ocp_threshold_ua, UCONV);
769 }
770 /* Calculate the input voltage of the flash module. */
771 vin_flash_uv = max((led->pdata->vled_max_uv +
772 (voltage_hdrm_mv * MCONV)), VIN_FLASH_MIN_UV);
773 /* Calculate the available power for the flash module. */
774 avail_flash_power_fw = BOB_EFFICIENCY * vph_flash_uv * ibat_flash_ua;
775 /*
776 * Calculate the available amount of current the flash module can draw
777 * before collapsing the battery. (available power/ flash input voltage)
778 */
779 avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV);
780 pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
781 avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh);
782 return min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
783 (int)(div64_s64(avail_flash_ua, MCONV)));
784}
785
786static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led)
787{
788 int thermal_current_lim = 0;
789 int rc;
790 u8 thermal_thrsh1, thermal_thrsh2, thermal_thrsh3, otst_status;
791
792 /* Store THERMAL_THRSHx register values */
793 rc = qpnp_flash_led_masked_read(led,
794 FLASH_LED_REG_THERMAL_THRSH1(led->base),
795 FLASH_LED_THERMAL_THRSH_MASK,
796 &thermal_thrsh1);
797 if (rc < 0)
798 return rc;
799
800 rc = qpnp_flash_led_masked_read(led,
801 FLASH_LED_REG_THERMAL_THRSH2(led->base),
802 FLASH_LED_THERMAL_THRSH_MASK,
803 &thermal_thrsh2);
804 if (rc < 0)
805 return rc;
806
807 rc = qpnp_flash_led_masked_read(led,
808 FLASH_LED_REG_THERMAL_THRSH3(led->base),
809 FLASH_LED_THERMAL_THRSH_MASK,
810 &thermal_thrsh3);
811 if (rc < 0)
812 return rc;
813
814 /* Lower THERMAL_THRSHx thresholds to minimum */
815 rc = qpnp_flash_led_masked_write(led,
816 FLASH_LED_REG_THERMAL_THRSH1(led->base),
817 FLASH_LED_THERMAL_THRSH_MASK,
818 FLASH_LED_THERMAL_THRSH_MIN);
819 if (rc < 0)
820 return rc;
821
822 rc = qpnp_flash_led_masked_write(led,
823 FLASH_LED_REG_THERMAL_THRSH2(led->base),
824 FLASH_LED_THERMAL_THRSH_MASK,
825 FLASH_LED_THERMAL_THRSH_MIN);
826 if (rc < 0)
827 return rc;
828
829 rc = qpnp_flash_led_masked_write(led,
830 FLASH_LED_REG_THERMAL_THRSH3(led->base),
831 FLASH_LED_THERMAL_THRSH_MASK,
832 FLASH_LED_THERMAL_THRSH_MIN);
833 if (rc < 0)
834 return rc;
835
836 /* Check THERMAL_OTST status */
837 rc = qpnp_flash_led_read(led,
838 FLASH_LED_REG_LED_STATUS2(led->base),
839 &otst_status);
840 if (rc < 0)
841 return rc;
842
843 /* Look up current limit based on THERMAL_OTST status */
844 if (otst_status)
845 thermal_current_lim =
846 led->pdata->thermal_derate_current[otst_status >> 1];
847
848 /* Restore THERMAL_THRESHx registers to original values */
849 rc = qpnp_flash_led_masked_write(led,
850 FLASH_LED_REG_THERMAL_THRSH1(led->base),
851 FLASH_LED_THERMAL_THRSH_MASK,
852 thermal_thrsh1);
853 if (rc < 0)
854 return rc;
855
856 rc = qpnp_flash_led_masked_write(led,
857 FLASH_LED_REG_THERMAL_THRSH2(led->base),
858 FLASH_LED_THERMAL_THRSH_MASK,
859 thermal_thrsh2);
860 if (rc < 0)
861 return rc;
862
863 rc = qpnp_flash_led_masked_write(led,
864 FLASH_LED_REG_THERMAL_THRSH3(led->base),
865 FLASH_LED_THERMAL_THRSH_MASK,
866 thermal_thrsh3);
867 if (rc < 0)
868 return rc;
869
870 return thermal_current_lim;
871}
872
873static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led)
874{
875 int max_avail_current, thermal_current_lim = 0;
876
877 led->trigger_lmh = false;
878 max_avail_current = qpnp_flash_led_calc_max_current(led);
879 if (led->pdata->thermal_derate_en)
880 thermal_current_lim =
881 qpnp_flash_led_calc_thermal_current_lim(led);
882
883 if (thermal_current_lim)
884 max_avail_current = min(max_avail_current, thermal_current_lim);
885
886 return max_avail_current;
887}
888
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530889static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode)
890{
891 struct qpnp_flash_led *led = dev_get_drvdata(&fnode->pdev->dev);
892
893 if (fnode->current_ma)
894 led->total_current_ma += fnode->current_ma
895 - fnode->prev_current_ma;
896 else
897 led->total_current_ma -= fnode->prev_current_ma;
898
899 fnode->prev_current_ma = fnode->current_ma;
900}
901
David Collins8885f792017-01-26 14:36:34 -0800902static void qpnp_flash_led_node_set(struct flash_node_data *fnode, int value)
903{
904 int prgm_current_ma = value;
Ankit Sharma8798ab12017-04-06 15:44:09 +0530905 int min_ma = fnode->ires_ua / 1000;
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530906 struct qpnp_flash_led *led = dev_get_drvdata(&fnode->pdev->dev);
David Collins8885f792017-01-26 14:36:34 -0800907
908 if (value <= 0)
909 prgm_current_ma = 0;
Ankit Sharma8798ab12017-04-06 15:44:09 +0530910 else if (value < min_ma)
911 prgm_current_ma = min_ma;
David Collins8885f792017-01-26 14:36:34 -0800912
913 prgm_current_ma = min(prgm_current_ma, fnode->max_current);
914 fnode->current_ma = prgm_current_ma;
915 fnode->cdev.brightness = prgm_current_ma;
916 fnode->current_reg_val = CURRENT_MA_TO_REG_VAL(prgm_current_ma,
917 fnode->ires_ua);
918 fnode->led_on = prgm_current_ma != 0;
Ankit Sharmaa7153c32017-03-22 19:04:52 +0530919
920 if (led->pdata->chgr_mitigation_sel == FLASH_SW_CHARGER_MITIGATION) {
921 qpnp_flash_led_aggregate_max_current(fnode);
922 led->trigger_chgr = false;
923 if (led->total_current_ma >= 1000)
924 led->trigger_chgr = true;
925 }
David Collins8885f792017-01-26 14:36:34 -0800926}
927
928static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
929{
930 struct qpnp_flash_led *led = dev_get_drvdata(&snode->pdev->dev);
931 int i, rc, addr_offset;
932
933 rc = qpnp_flash_led_masked_write(led,
934 FLASH_LED_EN_LED_CTRL(led->base),
935 snode->led_mask, FLASH_LED_DISABLE);
936 if (rc < 0)
937 return rc;
938
939 if (led->trigger_lmh) {
940 rc = qpnp_flash_led_masked_write(led,
941 FLASH_LED_REG_MITIGATION_SW(led->base),
942 FLASH_LED_LMH_MITIGATION_EN_MASK,
943 FLASH_LED_LMH_MITIGATION_DISABLE);
944 if (rc < 0) {
945 pr_err("disable lmh mitigation failed, rc=%d\n", rc);
946 return rc;
947 }
948 }
949
950 if (!led->trigger_chgr) {
951 rc = qpnp_flash_led_masked_write(led,
952 FLASH_LED_REG_MITIGATION_SW(led->base),
953 FLASH_LED_CHGR_MITIGATION_EN_MASK,
954 FLASH_LED_CHGR_MITIGATION_DISABLE);
955 if (rc < 0) {
956 pr_err("disable chgr mitigation failed, rc=%d\n", rc);
957 return rc;
958 }
959 }
960
961 led->enable--;
962 if (led->enable == 0) {
963 rc = qpnp_flash_led_masked_write(led,
964 FLASH_LED_REG_MOD_CTRL(led->base),
965 FLASH_LED_MOD_CTRL_MASK, FLASH_LED_DISABLE);
966 if (rc < 0)
967 return rc;
968 }
969
970 for (i = 0; i < led->num_fnodes; i++) {
971 if (!led->fnode[i].led_on ||
972 !(snode->led_mask & BIT(led->fnode[i].id)))
973 continue;
974
975 addr_offset = led->fnode[i].id;
976 rc = qpnp_flash_led_masked_write(led,
977 FLASH_LED_REG_TGR_CURRENT(led->base + addr_offset),
978 FLASH_LED_CURRENT_MASK, 0);
979 if (rc < 0)
980 return rc;
981
982 led->fnode[i].led_on = false;
983
David Collins8885f792017-01-26 14:36:34 -0800984 if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
985 rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
986 led->pdata->hw_strobe_option, false);
987 if (rc < 0) {
988 pr_err("Unable to disable hw strobe, rc=%d\n",
989 rc);
990 return rc;
991 }
992 }
993 }
994
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -0700995 if (snode->led_en_pinctrl) {
996 pr_debug("Selecting suspend state for %s\n", snode->cdev.name);
997 rc = pinctrl_select_state(snode->led_en_pinctrl,
998 snode->gpio_state_suspend);
999 if (rc < 0) {
1000 pr_err("failed to select pinctrl suspend state rc=%d\n",
1001 rc);
1002 return rc;
1003 }
1004 }
1005
David Collins8885f792017-01-26 14:36:34 -08001006 snode->enabled = false;
1007 return 0;
1008}
1009
1010static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
1011{
1012 struct qpnp_flash_led *led = dev_get_drvdata(&snode->pdev->dev);
1013 int rc, i, addr_offset;
1014 u8 val, mask;
1015
1016 if (snode->enabled == on) {
1017 pr_debug("Switch node is already %s!\n",
1018 on ? "enabled" : "disabled");
1019 return 0;
1020 }
1021
1022 if (!on) {
1023 rc = qpnp_flash_led_switch_disable(snode);
1024 return rc;
1025 }
1026
1027 /* Iterate over all leds for this switch node */
1028 val = 0;
1029 for (i = 0; i < led->num_fnodes; i++)
1030 if (snode->led_mask & BIT(led->fnode[i].id))
1031 val |= led->fnode[i].ires << (led->fnode[i].id * 2);
1032
1033 rc = qpnp_flash_led_masked_write(led, FLASH_LED_REG_IRES(led->base),
1034 FLASH_LED_CURRENT_MASK, val);
1035 if (rc < 0)
1036 return rc;
1037
1038 rc = qpnp_flash_led_masked_write(led,
1039 FLASH_LED_REG_STROBE_CFG(led->base),
1040 FLASH_LED_ENABLE_MASK,
1041 led->pdata->hw_strobe_option);
1042 if (rc < 0)
1043 return rc;
1044
1045 val = 0;
1046 for (i = 0; i < led->num_fnodes; i++) {
1047 if (!led->fnode[i].led_on ||
1048 !(snode->led_mask & BIT(led->fnode[i].id)))
1049 continue;
1050
1051 addr_offset = led->fnode[i].id;
1052 if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT)
1053 mask = FLASH_HW_STROBE_MASK;
1054 else
1055 mask = FLASH_LED_HW_SW_STROBE_SEL_BIT;
1056 rc = qpnp_flash_led_masked_write(led,
1057 FLASH_LED_REG_STROBE_CTRL(led->base + addr_offset),
1058 mask, led->fnode[i].trigger);
1059 if (rc < 0)
1060 return rc;
1061
1062 rc = qpnp_flash_led_masked_write(led,
1063 FLASH_LED_REG_TGR_CURRENT(led->base + addr_offset),
1064 FLASH_LED_CURRENT_MASK, led->fnode[i].current_reg_val);
1065 if (rc < 0)
1066 return rc;
1067
1068 rc = qpnp_flash_led_write(led,
1069 FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset),
1070 led->fnode[i].duration);
1071 if (rc < 0)
1072 return rc;
1073
1074 val |= FLASH_LED_ENABLE << led->fnode[i].id;
1075
David Collins8885f792017-01-26 14:36:34 -08001076 if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
1077 rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
1078 led->pdata->hw_strobe_option, true);
1079 if (rc < 0) {
1080 pr_err("Unable to enable hw strobe rc=%d\n",
1081 rc);
1082 return rc;
1083 }
1084 }
1085 }
1086
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -07001087 if (snode->led_en_pinctrl) {
1088 pr_debug("Selecting active state for %s\n", snode->cdev.name);
1089 rc = pinctrl_select_state(snode->led_en_pinctrl,
1090 snode->gpio_state_active);
1091 if (rc < 0) {
1092 pr_err("failed to select pinctrl active state rc=%d\n",
1093 rc);
1094 return rc;
1095 }
1096 }
1097
David Collins8885f792017-01-26 14:36:34 -08001098 if (led->enable == 0) {
1099 rc = qpnp_flash_led_masked_write(led,
1100 FLASH_LED_REG_MOD_CTRL(led->base),
1101 FLASH_LED_MOD_CTRL_MASK, FLASH_LED_MOD_ENABLE);
1102 if (rc < 0)
1103 return rc;
1104 }
1105 led->enable++;
1106
1107 if (led->trigger_lmh) {
1108 rc = qpnp_flash_led_masked_write(led,
1109 FLASH_LED_REG_MITIGATION_SW(led->base),
1110 FLASH_LED_LMH_MITIGATION_EN_MASK,
1111 FLASH_LED_LMH_MITIGATION_ENABLE);
1112 if (rc < 0) {
1113 pr_err("trigger lmh mitigation failed, rc=%d\n", rc);
1114 return rc;
1115 }
Subbaraman Narayanamurthyd02fbc92017-02-02 16:39:41 -08001116 /* Wait for LMH mitigation to take effect */
1117 udelay(500);
David Collins8885f792017-01-26 14:36:34 -08001118 }
1119
1120 if (led->trigger_chgr) {
1121 rc = qpnp_flash_led_masked_write(led,
1122 FLASH_LED_REG_MITIGATION_SW(led->base),
1123 FLASH_LED_CHGR_MITIGATION_EN_MASK,
1124 FLASH_LED_CHGR_MITIGATION_ENABLE);
1125 if (rc < 0) {
1126 pr_err("trigger chgr mitigation failed, rc=%d\n", rc);
1127 return rc;
1128 }
1129 }
1130
1131 rc = qpnp_flash_led_masked_write(led,
1132 FLASH_LED_EN_LED_CTRL(led->base),
1133 snode->led_mask, val);
1134 if (rc < 0)
1135 return rc;
1136
1137 snode->enabled = true;
1138 return 0;
1139}
1140
1141int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
1142 int *max_current)
1143{
1144 struct led_classdev *led_cdev;
1145 struct flash_switch_data *snode;
1146 struct qpnp_flash_led *led;
1147 int rc;
1148
1149 if (!trig) {
1150 pr_err("Invalid led_trigger provided\n");
1151 return -EINVAL;
1152 }
1153
1154 led_cdev = trigger_to_lcdev(trig);
1155 if (!led_cdev) {
1156 pr_err("Invalid led_cdev in trigger %s\n", trig->name);
1157 return -EINVAL;
1158 }
1159
1160 snode = container_of(led_cdev, struct flash_switch_data, cdev);
1161 led = dev_get_drvdata(&snode->pdev->dev);
1162
1163 if (!(options & FLASH_LED_PREPARE_OPTIONS_MASK)) {
1164 pr_err("Invalid options %d\n", options);
1165 return -EINVAL;
1166 }
1167
1168 if (options & ENABLE_REGULATOR) {
1169 rc = qpnp_flash_led_regulator_enable(led, snode, true);
1170 if (rc < 0) {
1171 pr_err("enable regulator failed, rc=%d\n", rc);
1172 return rc;
1173 }
1174 }
1175
1176 if (options & DISABLE_REGULATOR) {
1177 rc = qpnp_flash_led_regulator_enable(led, snode, false);
1178 if (rc < 0) {
1179 pr_err("disable regulator failed, rc=%d\n", rc);
1180 return rc;
1181 }
1182 }
1183
1184 if (options & QUERY_MAX_CURRENT) {
1185 rc = qpnp_flash_led_get_max_avail_current(led);
1186 if (rc < 0) {
1187 pr_err("query max current failed, rc=%d\n", rc);
1188 return rc;
1189 }
1190 *max_current = rc;
1191 }
1192
David Collins8885f792017-01-26 14:36:34 -08001193 return 0;
1194}
1195
1196static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
1197 enum led_brightness value)
1198{
1199 struct flash_node_data *fnode = NULL;
1200 struct flash_switch_data *snode = NULL;
1201 struct qpnp_flash_led *led = NULL;
1202 int rc;
1203
1204 /*
1205 * strncmp() must be used here since a prefix comparison is required
1206 * in order to support names like led:switch_0 and led:flash_1.
1207 */
1208 if (!strncmp(led_cdev->name, "led:switch", strlen("led:switch"))) {
1209 snode = container_of(led_cdev, struct flash_switch_data, cdev);
1210 led = dev_get_drvdata(&snode->pdev->dev);
1211 } else if (!strncmp(led_cdev->name, "led:flash", strlen("led:flash")) ||
1212 !strncmp(led_cdev->name, "led:torch",
1213 strlen("led:torch"))) {
1214 fnode = container_of(led_cdev, struct flash_node_data, cdev);
1215 led = dev_get_drvdata(&fnode->pdev->dev);
1216 }
1217
1218 if (!led) {
1219 pr_err("Failed to get flash driver data\n");
1220 return;
1221 }
1222
1223 spin_lock(&led->lock);
1224 if (snode) {
1225 rc = qpnp_flash_led_switch_set(snode, value > 0);
1226 if (rc < 0)
1227 pr_err("Failed to set flash LED switch rc=%d\n", rc);
1228 } else if (fnode) {
1229 qpnp_flash_led_node_set(fnode, value);
1230 }
1231
1232 spin_unlock(&led->lock);
1233}
1234
1235/* sysfs show function for flash_max_current */
1236static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
1237 struct device_attribute *attr, char *buf)
1238{
1239 int rc;
1240 struct flash_switch_data *snode;
1241 struct qpnp_flash_led *led;
1242 struct led_classdev *led_cdev = dev_get_drvdata(dev);
1243
1244 snode = container_of(led_cdev, struct flash_switch_data, cdev);
1245 led = dev_get_drvdata(&snode->pdev->dev);
1246
1247 rc = qpnp_flash_led_get_max_avail_current(led);
1248 if (rc < 0)
1249 pr_err("query max current failed, rc=%d\n", rc);
1250
1251 return snprintf(buf, PAGE_SIZE, "%d\n", rc);
1252}
1253
1254/* sysfs attributes exported by flash_led */
1255static struct device_attribute qpnp_flash_led_attrs[] = {
1256 __ATTR(max_current, 0664, qpnp_flash_led_max_current_show, NULL),
1257};
1258
1259static int flash_led_psy_notifier_call(struct notifier_block *nb,
1260 unsigned long ev, void *v)
1261{
1262 struct power_supply *psy = v;
1263 struct qpnp_flash_led *led =
1264 container_of(nb, struct qpnp_flash_led, nb);
1265
1266 if (ev != PSY_EVENT_PROP_CHANGED)
1267 return NOTIFY_OK;
1268
1269 if (!strcmp(psy->desc->name, "bms")) {
1270 led->bms_psy = power_supply_get_by_name("bms");
1271 if (!led->bms_psy)
1272 pr_err("Failed to get bms power_supply\n");
1273 else
1274 power_supply_unreg_notifier(&led->nb);
1275 }
1276
1277 return NOTIFY_OK;
1278}
1279
1280static int flash_led_psy_register_notifier(struct qpnp_flash_led *led)
1281{
1282 int rc;
1283
1284 led->nb.notifier_call = flash_led_psy_notifier_call;
1285 rc = power_supply_reg_notifier(&led->nb);
1286 if (rc < 0) {
1287 pr_err("Couldn't register psy notifier, rc = %d\n", rc);
1288 return rc;
1289 }
1290
1291 return 0;
1292}
1293
1294/* irq handler */
1295static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led)
1296{
1297 struct qpnp_flash_led *led = _led;
1298 enum flash_led_irq_type irq_type = INVALID_IRQ;
1299 int rc;
1300 u8 irq_status, led_status1, led_status2;
1301
1302 pr_debug("irq received, irq=%d\n", irq);
1303
1304 rc = qpnp_flash_led_read(led,
1305 FLASH_LED_REG_INT_RT_STS(led->base), &irq_status);
1306 if (rc < 0) {
1307 pr_err("Failed to read interrupt status reg, rc=%d\n", rc);
1308 goto exit;
1309 }
1310
1311 if (irq == led->pdata->all_ramp_up_done_irq)
1312 irq_type = ALL_RAMP_UP_DONE_IRQ;
1313 else if (irq == led->pdata->all_ramp_down_done_irq)
1314 irq_type = ALL_RAMP_DOWN_DONE_IRQ;
1315 else if (irq == led->pdata->led_fault_irq)
1316 irq_type = LED_FAULT_IRQ;
1317
1318 if (irq_type == ALL_RAMP_UP_DONE_IRQ)
1319 atomic_notifier_call_chain(&irq_notifier_list,
1320 irq_type, NULL);
1321
1322 if (irq_type == LED_FAULT_IRQ) {
1323 rc = qpnp_flash_led_read(led,
1324 FLASH_LED_REG_LED_STATUS1(led->base), &led_status1);
1325 if (rc < 0) {
1326 pr_err("Failed to read led_status1 reg, rc=%d\n", rc);
1327 goto exit;
1328 }
1329
1330 rc = qpnp_flash_led_read(led,
1331 FLASH_LED_REG_LED_STATUS2(led->base), &led_status2);
1332 if (rc < 0) {
1333 pr_err("Failed to read led_status2 reg, rc=%d\n", rc);
1334 goto exit;
1335 }
1336
1337 if (led_status1)
1338 pr_emerg("led short/open fault detected! led_status1=%x\n",
1339 led_status1);
1340
1341 if (led_status2 & FLASH_LED_VPH_DROOP_FAULT_MASK)
1342 pr_emerg("led vph_droop fault detected!\n");
1343 }
1344
1345 pr_debug("irq handled, irq_type=%x, irq_status=%x\n", irq_type,
1346 irq_status);
1347
1348exit:
1349 return IRQ_HANDLED;
1350}
1351
1352int qpnp_flash_led_register_irq_notifier(struct notifier_block *nb)
1353{
1354 return atomic_notifier_chain_register(&irq_notifier_list, nb);
1355}
1356
1357int qpnp_flash_led_unregister_irq_notifier(struct notifier_block *nb)
1358{
1359 return atomic_notifier_chain_unregister(&irq_notifier_list, nb);
1360}
1361
1362static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
1363 struct flash_node_data *fnode, struct device_node *node)
1364{
1365 const char *temp_string;
Ankit Sharma8798ab12017-04-06 15:44:09 +05301366 int rc, min_ma;
David Collins8885f792017-01-26 14:36:34 -08001367 u32 val;
1368 bool strobe_sel = 0, edge_trigger = 0, active_high = 0;
1369
1370 fnode->pdev = led->pdev;
1371 fnode->cdev.brightness_set = qpnp_flash_led_brightness_set;
1372 fnode->cdev.brightness_get = qpnp_flash_led_brightness_get;
1373
1374 rc = of_property_read_string(node, "qcom,led-name", &fnode->cdev.name);
1375 if (rc < 0) {
1376 pr_err("Unable to read flash LED names\n");
1377 return rc;
1378 }
1379
1380 rc = of_property_read_string(node, "label", &temp_string);
1381 if (!rc) {
1382 if (!strcmp(temp_string, "flash")) {
1383 fnode->type = FLASH_LED_TYPE_FLASH;
1384 } else if (!strcmp(temp_string, "torch")) {
1385 fnode->type = FLASH_LED_TYPE_TORCH;
1386 } else {
1387 pr_err("Wrong flash LED type\n");
1388 return rc;
1389 }
1390 } else {
1391 pr_err("Unable to read flash LED label\n");
1392 return rc;
1393 }
1394
1395 rc = of_property_read_u32(node, "qcom,id", &val);
1396 if (!rc) {
1397 fnode->id = (u8)val;
1398 } else {
1399 pr_err("Unable to read flash LED ID\n");
1400 return rc;
1401 }
1402
1403 rc = of_property_read_string(node, "qcom,default-led-trigger",
1404 &fnode->cdev.default_trigger);
1405 if (rc < 0) {
1406 pr_err("Unable to read trigger name\n");
1407 return rc;
1408 }
1409
1410 fnode->ires_ua = FLASH_LED_IRES_DEFAULT_UA;
1411 fnode->ires = FLASH_LED_IRES_DEFAULT_VAL;
1412 rc = of_property_read_u32(node, "qcom,ires-ua", &val);
1413 if (!rc) {
1414 fnode->ires_ua = val;
1415 fnode->ires = FLASH_LED_IRES_BASE -
1416 (val - FLASH_LED_IRES_MIN_UA) / FLASH_LED_IRES_DIVISOR;
1417 } else if (rc != -EINVAL) {
1418 pr_err("Unable to read current resolution rc=%d\n", rc);
1419 return rc;
1420 }
1421
Ankit Sharma8798ab12017-04-06 15:44:09 +05301422 min_ma = fnode->ires_ua / 1000;
David Collins8885f792017-01-26 14:36:34 -08001423 rc = of_property_read_u32(node, "qcom,max-current", &val);
1424 if (!rc) {
Ankit Sharma8798ab12017-04-06 15:44:09 +05301425 if (val < min_ma)
1426 val = min_ma;
David Collins8885f792017-01-26 14:36:34 -08001427 fnode->max_current = val;
1428 fnode->cdev.max_brightness = val;
1429 } else {
1430 pr_err("Unable to read max current, rc=%d\n", rc);
1431 return rc;
1432 }
1433
1434 rc = of_property_read_u32(node, "qcom,current-ma", &val);
1435 if (!rc) {
Ankit Sharma8798ab12017-04-06 15:44:09 +05301436 if (val < min_ma || val > fnode->max_current)
David Collins8885f792017-01-26 14:36:34 -08001437 pr_warn("Invalid operational current specified, capping it\n");
Ankit Sharma8798ab12017-04-06 15:44:09 +05301438 if (val < min_ma)
1439 val = min_ma;
David Collins8885f792017-01-26 14:36:34 -08001440 if (val > fnode->max_current)
1441 val = fnode->max_current;
1442 fnode->current_ma = val;
1443 fnode->cdev.brightness = val;
1444 } else if (rc != -EINVAL) {
1445 pr_err("Unable to read operational current, rc=%d\n", rc);
1446 return rc;
1447 }
1448
1449 fnode->duration = FLASH_LED_SAFETY_TMR_DISABLED;
1450 rc = of_property_read_u32(node, "qcom,duration-ms", &val);
1451 if (!rc) {
1452 fnode->duration = (u8)(SAFETY_TMR_TO_REG_VAL(val) |
1453 FLASH_LED_SAFETY_TMR_ENABLE);
1454 } else if (rc == -EINVAL) {
1455 if (fnode->type == FLASH_LED_TYPE_FLASH) {
1456 pr_err("Timer duration is required for flash LED\n");
1457 return rc;
1458 }
1459 } else {
1460 pr_err("Unable to read timer duration\n");
1461 return rc;
1462 }
1463
1464 fnode->hdrm_val = FLASH_LED_HDRM_VOL_DEFAULT_MV;
1465 rc = of_property_read_u32(node, "qcom,hdrm-voltage-mv", &val);
1466 if (!rc) {
1467 val = (val - FLASH_LED_HDRM_VOL_BASE_MV) /
1468 FLASH_LED_HDRM_VOL_STEP_MV;
1469 fnode->hdrm_val = (val << FLASH_LED_HDRM_VOL_SHIFT) &
1470 FLASH_LED_HDRM_VOL_MASK;
1471 } else if (rc != -EINVAL) {
1472 pr_err("Unable to read headroom voltage\n");
1473 return rc;
1474 }
1475
1476 rc = of_property_read_u32(node, "qcom,hdrm-vol-hi-lo-win-mv", &val);
1477 if (!rc) {
1478 fnode->hdrm_val |= (val / FLASH_LED_HDRM_VOL_STEP_MV) &
1479 ~FLASH_LED_HDRM_VOL_MASK;
1480 } else if (rc == -EINVAL) {
1481 fnode->hdrm_val |= FLASH_LED_HDRM_VOL_HI_LO_WIN_DEFAULT_MV;
1482 } else {
1483 pr_err("Unable to read hdrm hi-lo window voltage\n");
1484 return rc;
1485 }
1486
1487 strobe_sel = of_property_read_bool(node, "qcom,hw-strobe-sel");
1488 if (strobe_sel) {
1489 edge_trigger = of_property_read_bool(node,
1490 "qcom,hw-strobe-edge-trigger");
1491 active_high = !of_property_read_bool(node,
1492 "qcom,hw-strobe-active-low");
1493 }
1494 fnode->trigger = (strobe_sel << 2) | (edge_trigger << 1) | active_high;
1495
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -07001496 rc = led_classdev_register(&led->pdev->dev, &fnode->cdev);
1497 if (rc < 0) {
1498 pr_err("Unable to register led node %d\n", fnode->id);
1499 return rc;
1500 }
1501
1502 fnode->cdev.dev->of_node = node;
1503 fnode->strobe_pinctrl = devm_pinctrl_get(fnode->cdev.dev);
1504 if (IS_ERR_OR_NULL(fnode->strobe_pinctrl)) {
1505 pr_debug("No pinctrl defined for %s, err=%ld\n",
1506 fnode->cdev.name, PTR_ERR(fnode->strobe_pinctrl));
1507 fnode->strobe_pinctrl = NULL;
1508 }
1509
David Collins8885f792017-01-26 14:36:34 -08001510 if (fnode->trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
1511 if (of_find_property(node, "qcom,hw-strobe-gpio", NULL)) {
1512 fnode->hw_strobe_gpio = of_get_named_gpio(node,
1513 "qcom,hw-strobe-gpio", 0);
1514 if (fnode->hw_strobe_gpio < 0) {
1515 pr_err("Invalid gpio specified\n");
1516 return fnode->hw_strobe_gpio;
1517 }
1518 gpio_direction_output(fnode->hw_strobe_gpio, 0);
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -07001519 } else if (fnode->strobe_pinctrl) {
David Collins8885f792017-01-26 14:36:34 -08001520 fnode->hw_strobe_gpio = -1;
1521 fnode->hw_strobe_state_active =
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -07001522 pinctrl_lookup_state(fnode->strobe_pinctrl,
1523 "strobe_enable");
David Collins8885f792017-01-26 14:36:34 -08001524 if (IS_ERR_OR_NULL(fnode->hw_strobe_state_active)) {
1525 pr_err("No active pin for hardware strobe, rc=%ld\n",
1526 PTR_ERR(fnode->hw_strobe_state_active));
1527 fnode->hw_strobe_state_active = NULL;
1528 }
1529
1530 fnode->hw_strobe_state_suspend =
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -07001531 pinctrl_lookup_state(fnode->strobe_pinctrl,
1532 "strobe_disable");
David Collins8885f792017-01-26 14:36:34 -08001533 if (IS_ERR_OR_NULL(fnode->hw_strobe_state_suspend)) {
1534 pr_err("No suspend pin for hardware strobe, rc=%ld\n",
1535 PTR_ERR(fnode->hw_strobe_state_suspend)
1536 );
1537 fnode->hw_strobe_state_suspend = NULL;
1538 }
1539 }
1540 }
1541
David Collins8885f792017-01-26 14:36:34 -08001542 return 0;
1543}
1544
1545static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led,
1546 struct flash_switch_data *snode,
1547 struct device_node *node)
1548{
1549 int rc = 0, num;
1550 char reg_name[16], reg_sup_name[16];
1551
1552 rc = of_property_read_string(node, "qcom,led-name", &snode->cdev.name);
1553 if (rc < 0) {
1554 pr_err("Failed to read switch node name, rc=%d\n", rc);
1555 return rc;
1556 }
1557
1558 rc = sscanf(snode->cdev.name, "led:switch_%d", &num);
1559 if (!rc) {
1560 pr_err("No number for switch device?\n");
1561 return -EINVAL;
1562 }
1563
1564 rc = of_property_read_string(node, "qcom,default-led-trigger",
1565 &snode->cdev.default_trigger);
1566 if (rc < 0) {
1567 pr_err("Unable to read trigger name, rc=%d\n", rc);
1568 return rc;
1569 }
1570
1571 rc = of_property_read_u32(node, "qcom,led-mask", &snode->led_mask);
1572 if (rc < 0) {
1573 pr_err("Unable to read led mask rc=%d\n", rc);
1574 return rc;
1575 }
1576
1577 if (snode->led_mask < 1 || snode->led_mask > 7) {
1578 pr_err("Invalid value for led-mask\n");
1579 return -EINVAL;
1580 }
1581
1582 scnprintf(reg_name, sizeof(reg_name), "switch%d-supply", num);
1583 if (of_find_property(led->pdev->dev.of_node, reg_name, NULL)) {
1584 scnprintf(reg_sup_name, sizeof(reg_sup_name), "switch%d", num);
1585 snode->vreg = devm_regulator_get(&led->pdev->dev, reg_sup_name);
1586 if (IS_ERR_OR_NULL(snode->vreg)) {
1587 rc = PTR_ERR(snode->vreg);
1588 if (rc != -EPROBE_DEFER)
1589 pr_err("Failed to get regulator, rc=%d\n", rc);
1590 snode->vreg = NULL;
1591 return rc;
1592 }
1593 }
1594
1595 snode->pdev = led->pdev;
1596 snode->cdev.brightness_set = qpnp_flash_led_brightness_set;
1597 snode->cdev.brightness_get = qpnp_flash_led_brightness_get;
1598 snode->cdev.flags |= LED_KEEP_TRIGGER;
1599 rc = led_classdev_register(&led->pdev->dev, &snode->cdev);
1600 if (rc < 0) {
1601 pr_err("Unable to register led switch node\n");
1602 return rc;
1603 }
1604
1605 snode->cdev.dev->of_node = node;
Subbaraman Narayanamurthy58377f02017-03-21 20:38:43 -07001606
1607 snode->led_en_pinctrl = devm_pinctrl_get(snode->cdev.dev);
1608 if (IS_ERR_OR_NULL(snode->led_en_pinctrl)) {
1609 pr_debug("No pinctrl defined for %s, err=%ld\n",
1610 snode->cdev.name, PTR_ERR(snode->led_en_pinctrl));
1611 snode->led_en_pinctrl = NULL;
1612 }
1613
1614 if (snode->led_en_pinctrl) {
1615 snode->gpio_state_active =
1616 pinctrl_lookup_state(snode->led_en_pinctrl,
1617 "led_enable");
1618 if (IS_ERR_OR_NULL(snode->gpio_state_active)) {
1619 pr_err("Cannot lookup LED active state\n");
1620 devm_pinctrl_put(snode->led_en_pinctrl);
1621 snode->led_en_pinctrl = NULL;
1622 return PTR_ERR(snode->gpio_state_active);
1623 }
1624
1625 snode->gpio_state_suspend =
1626 pinctrl_lookup_state(snode->led_en_pinctrl,
1627 "led_disable");
1628 if (IS_ERR_OR_NULL(snode->gpio_state_suspend)) {
1629 pr_err("Cannot lookup LED disable state\n");
1630 devm_pinctrl_put(snode->led_en_pinctrl);
1631 snode->led_en_pinctrl = NULL;
1632 return PTR_ERR(snode->gpio_state_suspend);
1633 }
1634 }
1635
David Collins8885f792017-01-26 14:36:34 -08001636 return 0;
1637}
1638
1639static int get_code_from_table(int *table, int len, int value)
1640{
1641 int i;
1642
1643 for (i = 0; i < len; i++) {
1644 if (value == table[i])
1645 break;
1646 }
1647
1648 if (i == len) {
1649 pr_err("Couldn't find %d from table\n", value);
1650 return -ENODATA;
1651 }
1652
1653 return i;
1654}
1655
1656static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
1657 struct device_node *node)
1658{
1659 struct device_node *revid_node;
1660 int rc;
1661 u32 val;
1662 bool short_circuit_det, open_circuit_det, vph_droop_det;
1663
1664 revid_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
1665 if (!revid_node) {
1666 pr_err("Missing qcom,pmic-revid property - driver failed\n");
1667 return -EINVAL;
1668 }
1669
1670 led->pdata->pmic_rev_id = get_revid_data(revid_node);
1671 if (IS_ERR_OR_NULL(led->pdata->pmic_rev_id)) {
1672 pr_err("Unable to get pmic_revid rc=%ld\n",
1673 PTR_ERR(led->pdata->pmic_rev_id));
1674 /*
1675 * the revid peripheral must be registered, any failure
1676 * here only indicates that the rev-id module has not
1677 * probed yet.
1678 */
1679 return -EPROBE_DEFER;
1680 }
1681
1682 pr_debug("PMIC subtype %d Digital major %d\n",
1683 led->pdata->pmic_rev_id->pmic_subtype,
1684 led->pdata->pmic_rev_id->rev4);
1685
1686 led->pdata->hdrm_auto_mode_en = of_property_read_bool(node,
1687 "qcom,hdrm-auto-mode");
1688
1689 led->pdata->isc_delay = FLASH_LED_ISC_DELAY_DEFAULT;
1690 rc = of_property_read_u32(node, "qcom,isc-delay-us", &val);
1691 if (!rc) {
1692 led->pdata->isc_delay =
1693 val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT;
1694 } else if (rc != -EINVAL) {
1695 pr_err("Unable to read ISC delay, rc=%d\n", rc);
1696 return rc;
1697 }
1698
1699 led->pdata->warmup_delay = FLASH_LED_WARMUP_DELAY_DEFAULT;
1700 rc = of_property_read_u32(node, "qcom,warmup-delay-us", &val);
1701 if (!rc) {
1702 led->pdata->warmup_delay =
1703 val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT;
1704 } else if (rc != -EINVAL) {
1705 pr_err("Unable to read WARMUP delay, rc=%d\n", rc);
1706 return rc;
1707 }
1708
1709 short_circuit_det =
1710 of_property_read_bool(node, "qcom,short-circuit-det");
1711 open_circuit_det = of_property_read_bool(node, "qcom,open-circuit-det");
1712 vph_droop_det = of_property_read_bool(node, "qcom,vph-droop-det");
1713 led->pdata->current_derate_en_cfg = (vph_droop_det << 2) |
1714 (open_circuit_det << 1) | short_circuit_det;
1715
1716 led->pdata->thermal_derate_en =
1717 of_property_read_bool(node, "qcom,thermal-derate-en");
1718
1719 if (led->pdata->thermal_derate_en) {
1720 led->pdata->thermal_derate_current =
1721 devm_kcalloc(&led->pdev->dev,
1722 FLASH_LED_THERMAL_OTST_LEVELS,
1723 sizeof(int), GFP_KERNEL);
1724 if (!led->pdata->thermal_derate_current)
1725 return -ENOMEM;
1726
1727 rc = of_property_read_u32_array(node,
1728 "qcom,thermal-derate-current",
1729 led->pdata->thermal_derate_current,
1730 FLASH_LED_THERMAL_OTST_LEVELS);
1731 if (rc < 0) {
1732 pr_err("Unable to read thermal current limits, rc=%d\n",
1733 rc);
1734 return rc;
1735 }
1736 }
1737
1738 led->pdata->otst_ramp_bkup_en =
1739 !of_property_read_bool(node, "qcom,otst-ramp-back-up-dis");
1740
1741 led->pdata->thermal_derate_slow = -EINVAL;
1742 rc = of_property_read_u32(node, "qcom,thermal-derate-slow", &val);
1743 if (!rc) {
1744 if (val < 0 || val > THERMAL_DERATE_SLOW_MAX) {
1745 pr_err("Invalid thermal_derate_slow %d\n", val);
1746 return -EINVAL;
1747 }
1748
1749 led->pdata->thermal_derate_slow =
1750 get_code_from_table(thermal_derate_slow_table,
1751 ARRAY_SIZE(thermal_derate_slow_table), val);
1752 } else if (rc != -EINVAL) {
1753 pr_err("Unable to read thermal derate slow, rc=%d\n", rc);
1754 return rc;
1755 }
1756
1757 led->pdata->thermal_derate_fast = -EINVAL;
1758 rc = of_property_read_u32(node, "qcom,thermal-derate-fast", &val);
1759 if (!rc) {
1760 if (val < 0 || val > THERMAL_DERATE_FAST_MAX) {
1761 pr_err("Invalid thermal_derate_fast %d\n", val);
1762 return -EINVAL;
1763 }
1764
1765 led->pdata->thermal_derate_fast =
1766 get_code_from_table(thermal_derate_fast_table,
1767 ARRAY_SIZE(thermal_derate_fast_table), val);
1768 } else if (rc != -EINVAL) {
1769 pr_err("Unable to read thermal derate fast, rc=%d\n", rc);
1770 return rc;
1771 }
1772
1773 led->pdata->thermal_debounce = -EINVAL;
1774 rc = of_property_read_u32(node, "qcom,thermal-debounce", &val);
1775 if (!rc) {
1776 if (val < 0 || val > THERMAL_DEBOUNCE_TIME_MAX) {
1777 pr_err("Invalid thermal_debounce %d\n", val);
1778 return -EINVAL;
1779 }
1780
1781 if (val >= 0 && val < 16)
1782 led->pdata->thermal_debounce = 0;
1783 else
1784 led->pdata->thermal_debounce = ilog2(val) - 3;
1785 } else if (rc != -EINVAL) {
1786 pr_err("Unable to read thermal debounce, rc=%d\n", rc);
1787 return rc;
1788 }
1789
1790 led->pdata->thermal_hysteresis = -EINVAL;
1791 rc = of_property_read_u32(node, "qcom,thermal-hysteresis", &val);
1792 if (!rc) {
1793 if (led->pdata->pmic_rev_id->pmic_subtype == PM660L_SUBTYPE)
1794 val = THERMAL_HYST_TEMP_TO_VAL(val, 20);
1795 else
1796 val = THERMAL_HYST_TEMP_TO_VAL(val, 15);
1797
1798 if (val < 0 || val > THERMAL_DERATE_HYSTERESIS_MAX) {
1799 pr_err("Invalid thermal_derate_hysteresis %d\n", val);
1800 return -EINVAL;
1801 }
1802
1803 led->pdata->thermal_hysteresis = val;
1804 } else if (rc != -EINVAL) {
1805 pr_err("Unable to read thermal hysteresis, rc=%d\n", rc);
1806 return rc;
1807 }
1808
1809 led->pdata->thermal_thrsh1 = -EINVAL;
1810 rc = of_property_read_u32(node, "qcom,thermal-thrsh1", &val);
1811 if (!rc) {
1812 led->pdata->thermal_thrsh1 =
1813 get_code_from_table(otst1_threshold_table,
1814 ARRAY_SIZE(otst1_threshold_table), val);
1815 } else if (rc != -EINVAL) {
1816 pr_err("Unable to read thermal thrsh1, rc=%d\n", rc);
1817 return rc;
1818 }
1819
1820 led->pdata->thermal_thrsh2 = -EINVAL;
1821 rc = of_property_read_u32(node, "qcom,thermal-thrsh2", &val);
1822 if (!rc) {
1823 led->pdata->thermal_thrsh2 =
1824 get_code_from_table(otst2_threshold_table,
1825 ARRAY_SIZE(otst2_threshold_table), val);
1826 } else if (rc != -EINVAL) {
1827 pr_err("Unable to read thermal thrsh2, rc=%d\n", rc);
1828 return rc;
1829 }
1830
1831 led->pdata->thermal_thrsh3 = -EINVAL;
1832 rc = of_property_read_u32(node, "qcom,thermal-thrsh3", &val);
1833 if (!rc) {
1834 led->pdata->thermal_thrsh3 =
1835 get_code_from_table(otst3_threshold_table,
1836 ARRAY_SIZE(otst3_threshold_table), val);
1837 } else if (rc != -EINVAL) {
1838 pr_err("Unable to read thermal thrsh3, rc=%d\n", rc);
1839 return rc;
1840 }
1841
1842 led->pdata->vph_droop_debounce = FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT;
1843 rc = of_property_read_u32(node, "qcom,vph-droop-debounce-us", &val);
1844 if (!rc) {
1845 led->pdata->vph_droop_debounce =
1846 VPH_DROOP_DEBOUNCE_US_TO_VAL(val);
1847 } else if (rc != -EINVAL) {
1848 pr_err("Unable to read VPH droop debounce, rc=%d\n", rc);
1849 return rc;
1850 }
1851
1852 if (led->pdata->vph_droop_debounce > FLASH_LED_DEBOUNCE_MAX) {
1853 pr_err("Invalid VPH droop debounce specified\n");
1854 return -EINVAL;
1855 }
1856
1857 led->pdata->vph_droop_threshold = FLASH_LED_VPH_DROOP_THRESH_DEFAULT;
1858 rc = of_property_read_u32(node, "qcom,vph-droop-threshold-mv", &val);
1859 if (!rc) {
1860 led->pdata->vph_droop_threshold =
1861 VPH_DROOP_THRESH_MV_TO_VAL(val);
1862 } else if (rc != -EINVAL) {
1863 pr_err("Unable to read VPH droop threshold, rc=%d\n", rc);
1864 return rc;
1865 }
1866
1867 if (led->pdata->vph_droop_threshold > FLASH_LED_VPH_DROOP_THRESH_MAX) {
1868 pr_err("Invalid VPH droop threshold specified\n");
1869 return -EINVAL;
1870 }
1871
1872 led->pdata->vph_droop_hysteresis =
1873 FLASH_LED_VPH_DROOP_HYST_DEFAULT;
1874 rc = of_property_read_u32(node, "qcom,vph-droop-hysteresis-mv", &val);
1875 if (!rc) {
1876 led->pdata->vph_droop_hysteresis =
1877 VPH_DROOP_HYST_MV_TO_VAL(val);
1878 } else if (rc != -EINVAL) {
1879 pr_err("Unable to read VPH droop hysteresis, rc=%d\n", rc);
1880 return rc;
1881 }
1882
1883 if (led->pdata->vph_droop_hysteresis > FLASH_LED_HYSTERESIS_MAX) {
1884 pr_err("Invalid VPH droop hysteresis specified\n");
1885 return -EINVAL;
1886 }
1887
1888 led->pdata->vph_droop_hysteresis <<= FLASH_LED_VPH_DROOP_HYST_SHIFT;
1889
1890 rc = of_property_read_u32(node, "qcom,hw-strobe-option", &val);
1891 if (!rc) {
1892 led->pdata->hw_strobe_option = (u8)val;
1893 } else if (rc != -EINVAL) {
1894 pr_err("Unable to parse hw strobe option, rc=%d\n", rc);
1895 return rc;
1896 }
1897
1898 rc = of_property_read_u32(node, "qcom,led1n2-iclamp-low-ma", &val);
1899 if (!rc) {
1900 led->pdata->led1n2_iclamp_low_ma = val;
1901 } else if (rc != -EINVAL) {
1902 pr_err("Unable to read led1n2_iclamp_low current, rc=%d\n", rc);
1903 return rc;
1904 }
1905
1906 rc = of_property_read_u32(node, "qcom,led1n2-iclamp-mid-ma", &val);
1907 if (!rc) {
1908 led->pdata->led1n2_iclamp_mid_ma = val;
1909 } else if (rc != -EINVAL) {
1910 pr_err("Unable to read led1n2_iclamp_mid current, rc=%d\n", rc);
1911 return rc;
1912 }
1913
1914 rc = of_property_read_u32(node, "qcom,led3-iclamp-low-ma", &val);
1915 if (!rc) {
1916 led->pdata->led3_iclamp_low_ma = val;
1917 } else if (rc != -EINVAL) {
1918 pr_err("Unable to read led3_iclamp_low current, rc=%d\n", rc);
1919 return rc;
1920 }
1921
1922 rc = of_property_read_u32(node, "qcom,led3-iclamp-mid-ma", &val);
1923 if (!rc) {
1924 led->pdata->led3_iclamp_mid_ma = val;
1925 } else if (rc != -EINVAL) {
1926 pr_err("Unable to read led3_iclamp_mid current, rc=%d\n", rc);
1927 return rc;
1928 }
1929
1930 led->pdata->vled_max_uv = FLASH_LED_VLED_MAX_DEFAULT_UV;
1931 rc = of_property_read_u32(node, "qcom,vled-max-uv", &val);
1932 if (!rc) {
1933 led->pdata->vled_max_uv = val;
1934 } else if (rc != -EINVAL) {
1935 pr_err("Unable to parse vled_max voltage, rc=%d\n", rc);
1936 return rc;
1937 }
1938
1939 led->pdata->ibatt_ocp_threshold_ua =
1940 FLASH_LED_IBATT_OCP_THRESH_DEFAULT_UA;
1941 rc = of_property_read_u32(node, "qcom,ibatt-ocp-threshold-ua", &val);
1942 if (!rc) {
1943 led->pdata->ibatt_ocp_threshold_ua = val;
1944 } else if (rc != -EINVAL) {
1945 pr_err("Unable to parse ibatt_ocp threshold, rc=%d\n", rc);
1946 return rc;
1947 }
1948
1949 led->pdata->rpara_uohm = FLASH_LED_RPARA_DEFAULT_UOHM;
1950 rc = of_property_read_u32(node, "qcom,rparasitic-uohm", &val);
1951 if (!rc) {
1952 led->pdata->rpara_uohm = val;
1953 } else if (rc != -EINVAL) {
1954 pr_err("Unable to parse rparasitic, rc=%d\n", rc);
1955 return rc;
1956 }
1957
1958 led->pdata->lmh_ocv_threshold_uv =
1959 FLASH_LED_LMH_OCV_THRESH_DEFAULT_UV;
1960 rc = of_property_read_u32(node, "qcom,lmh-ocv-threshold-uv", &val);
1961 if (!rc) {
1962 led->pdata->lmh_ocv_threshold_uv = val;
1963 } else if (rc != -EINVAL) {
1964 pr_err("Unable to parse lmh ocv threshold, rc=%d\n", rc);
1965 return rc;
1966 }
1967
1968 led->pdata->lmh_rbatt_threshold_uohm =
1969 FLASH_LED_LMH_RBATT_THRESH_DEFAULT_UOHM;
1970 rc = of_property_read_u32(node, "qcom,lmh-rbatt-threshold-uohm", &val);
1971 if (!rc) {
1972 led->pdata->lmh_rbatt_threshold_uohm = val;
1973 } else if (rc != -EINVAL) {
1974 pr_err("Unable to parse lmh rbatt threshold, rc=%d\n", rc);
1975 return rc;
1976 }
1977
1978 led->pdata->lmh_level = FLASH_LED_LMH_LEVEL_DEFAULT;
1979 rc = of_property_read_u32(node, "qcom,lmh-level", &val);
1980 if (!rc) {
1981 led->pdata->lmh_level = val;
1982 } else if (rc != -EINVAL) {
1983 pr_err("Unable to parse lmh_level, rc=%d\n", rc);
1984 return rc;
1985 }
1986
Ankit Sharmaa7153c32017-03-22 19:04:52 +05301987 led->pdata->lmh_mitigation_sel = FLASH_LED_LMH_MITIGATION_SEL_DEFAULT;
David Collins8885f792017-01-26 14:36:34 -08001988 rc = of_property_read_u32(node, "qcom,lmh-mitigation-sel", &val);
1989 if (!rc) {
1990 led->pdata->lmh_mitigation_sel = val;
1991 } else if (rc != -EINVAL) {
1992 pr_err("Unable to parse lmh_mitigation_sel, rc=%d\n", rc);
1993 return rc;
1994 }
1995
1996 if (led->pdata->lmh_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) {
1997 pr_err("Invalid lmh_mitigation_sel specified\n");
1998 return -EINVAL;
1999 }
2000
Ankit Sharmaa7153c32017-03-22 19:04:52 +05302001 led->pdata->chgr_mitigation_sel = FLASH_SW_CHARGER_MITIGATION;
David Collins8885f792017-01-26 14:36:34 -08002002 rc = of_property_read_u32(node, "qcom,chgr-mitigation-sel", &val);
2003 if (!rc) {
2004 led->pdata->chgr_mitigation_sel = val;
2005 } else if (rc != -EINVAL) {
2006 pr_err("Unable to parse chgr_mitigation_sel, rc=%d\n", rc);
2007 return rc;
2008 }
2009
2010 if (led->pdata->chgr_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) {
2011 pr_err("Invalid chgr_mitigation_sel specified\n");
2012 return -EINVAL;
2013 }
2014
Ankit Sharmaa7153c32017-03-22 19:04:52 +05302015 led->pdata->iled_thrsh_val = FLASH_LED_CHGR_MITIGATION_THRSH_DEFAULT;
David Collins8885f792017-01-26 14:36:34 -08002016 rc = of_property_read_u32(node, "qcom,iled-thrsh-ma", &val);
2017 if (!rc) {
2018 led->pdata->iled_thrsh_val = MITIGATION_THRSH_MA_TO_VAL(val);
2019 } else if (rc != -EINVAL) {
2020 pr_err("Unable to parse iled_thrsh_val, rc=%d\n", rc);
2021 return rc;
2022 }
2023
Ankit Sharmaa7153c32017-03-22 19:04:52 +05302024 if (led->pdata->iled_thrsh_val > FLASH_LED_CHGR_MITIGATION_THRSH_MAX) {
David Collins8885f792017-01-26 14:36:34 -08002025 pr_err("Invalid iled_thrsh_val specified\n");
2026 return -EINVAL;
2027 }
2028
2029 led->pdata->all_ramp_up_done_irq =
2030 of_irq_get_byname(node, "all-ramp-up-done-irq");
2031 if (led->pdata->all_ramp_up_done_irq < 0)
2032 pr_debug("all-ramp-up-done-irq not used\n");
2033
2034 led->pdata->all_ramp_down_done_irq =
2035 of_irq_get_byname(node, "all-ramp-down-done-irq");
2036 if (led->pdata->all_ramp_down_done_irq < 0)
2037 pr_debug("all-ramp-down-done-irq not used\n");
2038
2039 led->pdata->led_fault_irq =
2040 of_irq_get_byname(node, "led-fault-irq");
2041 if (led->pdata->led_fault_irq < 0)
2042 pr_debug("led-fault-irq not used\n");
2043
2044 return 0;
2045}
2046
2047static int qpnp_flash_led_probe(struct platform_device *pdev)
2048{
2049 struct qpnp_flash_led *led;
2050 struct device_node *node, *temp;
2051 const char *temp_string;
2052 unsigned int base;
2053 int rc, i = 0, j = 0;
2054
2055 node = pdev->dev.of_node;
2056 if (!node) {
2057 pr_err("No flash LED nodes defined\n");
2058 return -ENODEV;
2059 }
2060
2061 rc = of_property_read_u32(node, "reg", &base);
2062 if (rc < 0) {
2063 pr_err("Couldn't find reg in node %s, rc = %d\n",
2064 node->full_name, rc);
2065 return rc;
2066 }
2067
2068 led = devm_kzalloc(&pdev->dev, sizeof(struct qpnp_flash_led),
2069 GFP_KERNEL);
2070 if (!led)
2071 return -ENOMEM;
2072
2073 led->regmap = dev_get_regmap(pdev->dev.parent, NULL);
2074 if (!led->regmap) {
2075 pr_err("Couldn't get parent's regmap\n");
2076 return -EINVAL;
2077 }
2078
2079 led->base = base;
2080 led->pdev = pdev;
2081 led->pdata = devm_kzalloc(&pdev->dev,
2082 sizeof(struct flash_led_platform_data), GFP_KERNEL);
2083 if (!led->pdata)
2084 return -ENOMEM;
2085
2086 rc = qpnp_flash_led_parse_common_dt(led, node);
2087 if (rc < 0) {
2088 pr_err("Failed to parse common flash LED device tree\n");
2089 return rc;
2090 }
2091
2092 for_each_available_child_of_node(node, temp) {
2093 rc = of_property_read_string(temp, "label", &temp_string);
2094 if (rc < 0) {
2095 pr_err("Failed to parse label, rc=%d\n", rc);
2096 return rc;
2097 }
2098
2099 if (!strcmp("switch", temp_string)) {
2100 led->num_snodes++;
2101 } else if (!strcmp("flash", temp_string) ||
2102 !strcmp("torch", temp_string)) {
2103 led->num_fnodes++;
2104 } else {
2105 pr_err("Invalid label for led node\n");
2106 return -EINVAL;
2107 }
2108 }
2109
2110 if (!led->num_fnodes) {
2111 pr_err("No LED nodes defined\n");
2112 return -ECHILD;
2113 }
2114
2115 led->fnode = devm_kcalloc(&pdev->dev, led->num_fnodes,
2116 sizeof(*led->fnode),
2117 GFP_KERNEL);
2118 if (!led->fnode)
2119 return -ENOMEM;
2120
2121 led->snode = devm_kcalloc(&pdev->dev, led->num_snodes,
2122 sizeof(*led->snode),
2123 GFP_KERNEL);
2124 if (!led->snode)
2125 return -ENOMEM;
2126
2127 temp = NULL;
2128 i = 0;
2129 j = 0;
2130 for_each_available_child_of_node(node, temp) {
2131 rc = of_property_read_string(temp, "label", &temp_string);
2132 if (rc < 0) {
2133 pr_err("Failed to parse label, rc=%d\n", rc);
2134 return rc;
2135 }
2136
2137 if (!strcmp("flash", temp_string) ||
2138 !strcmp("torch", temp_string)) {
2139 rc = qpnp_flash_led_parse_each_led_dt(led,
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -07002140 &led->fnode[i], temp);
David Collins8885f792017-01-26 14:36:34 -08002141 if (rc < 0) {
2142 pr_err("Unable to parse flash node %d rc=%d\n",
2143 i, rc);
2144 goto error_led_register;
2145 }
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -07002146 i++;
David Collins8885f792017-01-26 14:36:34 -08002147 }
2148
2149 if (!strcmp("switch", temp_string)) {
2150 rc = qpnp_flash_led_parse_and_register_switch(led,
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -07002151 &led->snode[j], temp);
David Collins8885f792017-01-26 14:36:34 -08002152 if (rc < 0) {
2153 pr_err("Unable to parse and register switch node, rc=%d\n",
2154 rc);
2155 goto error_switch_register;
2156 }
Subbaraman Narayanamurthy01c99612017-04-03 12:26:06 -07002157 j++;
David Collins8885f792017-01-26 14:36:34 -08002158 }
2159 }
2160
2161 /* setup irqs */
2162 if (led->pdata->all_ramp_up_done_irq >= 0) {
2163 rc = devm_request_threaded_irq(&led->pdev->dev,
2164 led->pdata->all_ramp_up_done_irq,
2165 NULL, qpnp_flash_led_irq_handler,
2166 IRQF_ONESHOT,
2167 "qpnp_flash_led_all_ramp_up_done_irq", led);
2168 if (rc < 0) {
2169 pr_err("Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n",
2170 led->pdata->all_ramp_up_done_irq, rc);
2171 goto error_switch_register;
2172 }
2173 }
2174
2175 if (led->pdata->all_ramp_down_done_irq >= 0) {
2176 rc = devm_request_threaded_irq(&led->pdev->dev,
2177 led->pdata->all_ramp_down_done_irq,
2178 NULL, qpnp_flash_led_irq_handler,
2179 IRQF_ONESHOT,
2180 "qpnp_flash_led_all_ramp_down_done_irq", led);
2181 if (rc < 0) {
2182 pr_err("Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n",
2183 led->pdata->all_ramp_down_done_irq, rc);
2184 goto error_switch_register;
2185 }
2186 }
2187
2188 if (led->pdata->led_fault_irq >= 0) {
2189 rc = devm_request_threaded_irq(&led->pdev->dev,
2190 led->pdata->led_fault_irq,
2191 NULL, qpnp_flash_led_irq_handler,
2192 IRQF_ONESHOT,
2193 "qpnp_flash_led_fault_irq", led);
2194 if (rc < 0) {
2195 pr_err("Unable to request led_fault(%d) IRQ(err:%d)\n",
2196 led->pdata->led_fault_irq, rc);
2197 goto error_switch_register;
2198 }
2199 }
2200
2201 led->bms_psy = power_supply_get_by_name("bms");
2202 if (!led->bms_psy) {
2203 rc = flash_led_psy_register_notifier(led);
2204 if (rc < 0) {
2205 pr_err("Couldn't register psy notifier, rc = %d\n", rc);
2206 goto error_switch_register;
2207 }
2208 }
2209
2210 rc = qpnp_flash_led_init_settings(led);
2211 if (rc < 0) {
2212 pr_err("Failed to initialize flash LED, rc=%d\n", rc);
2213 goto unreg_notifier;
2214 }
2215
2216 for (i = 0; i < led->num_snodes; i++) {
2217 for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++) {
2218 rc = sysfs_create_file(&led->snode[i].cdev.dev->kobj,
2219 &qpnp_flash_led_attrs[j].attr);
2220 if (rc < 0) {
2221 pr_err("sysfs creation failed, rc=%d\n", rc);
2222 goto sysfs_fail;
2223 }
2224 }
2225 }
2226
2227 spin_lock_init(&led->lock);
2228
2229 dev_set_drvdata(&pdev->dev, led);
2230
2231 return 0;
2232
2233sysfs_fail:
2234 for (--j; j >= 0; j--)
2235 sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
2236 &qpnp_flash_led_attrs[j].attr);
2237
2238 for (--i; i >= 0; i--) {
2239 for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++)
2240 sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
2241 &qpnp_flash_led_attrs[j].attr);
2242 }
2243
2244 i = led->num_snodes;
2245unreg_notifier:
2246 power_supply_unreg_notifier(&led->nb);
2247error_switch_register:
2248 while (i > 0)
2249 led_classdev_unregister(&led->snode[--i].cdev);
2250 i = led->num_fnodes;
2251error_led_register:
2252 while (i > 0)
2253 led_classdev_unregister(&led->fnode[--i].cdev);
2254
2255 return rc;
2256}
2257
2258static int qpnp_flash_led_remove(struct platform_device *pdev)
2259{
2260 struct qpnp_flash_led *led = dev_get_drvdata(&pdev->dev);
2261 int i, j;
2262
2263 for (i = 0; i < led->num_snodes; i++) {
2264 for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++)
2265 sysfs_remove_file(&led->snode[i].cdev.dev->kobj,
2266 &qpnp_flash_led_attrs[j].attr);
2267
2268 if (led->snode[i].regulator_on)
2269 qpnp_flash_led_regulator_enable(led,
2270 &led->snode[i], false);
2271 }
2272
2273 while (i > 0)
2274 led_classdev_unregister(&led->snode[--i].cdev);
2275
2276 i = led->num_fnodes;
2277 while (i > 0)
2278 led_classdev_unregister(&led->fnode[--i].cdev);
2279
2280 power_supply_unreg_notifier(&led->nb);
2281 return 0;
2282}
2283
2284const struct of_device_id qpnp_flash_led_match_table[] = {
2285 { .compatible = "qcom,qpnp-flash-led-v2",},
2286 { },
2287};
2288
2289static struct platform_driver qpnp_flash_led_driver = {
2290 .driver = {
2291 .name = "qcom,qpnp-flash-led-v2",
2292 .of_match_table = qpnp_flash_led_match_table,
2293 },
2294 .probe = qpnp_flash_led_probe,
2295 .remove = qpnp_flash_led_remove,
2296};
2297
2298static int __init qpnp_flash_led_init(void)
2299{
2300 return platform_driver_register(&qpnp_flash_led_driver);
2301}
2302late_initcall(qpnp_flash_led_init);
2303
2304static void __exit qpnp_flash_led_exit(void)
2305{
2306 platform_driver_unregister(&qpnp_flash_led_driver);
2307}
2308module_exit(qpnp_flash_led_exit);
2309
2310MODULE_DESCRIPTION("QPNP Flash LED driver v2");
2311MODULE_LICENSE("GPL v2");
2312MODULE_ALIAS("leds:leds-qpnp-flash-v2");