blob: fca19097388b9464e4d0daa1d63b41f9a5f4434f [file] [log] [blame]
David Collins8885f792017-01-26 14:36:34 -08001/* Copyright (c) 2012-2015, 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#include <linux/kernel.h>
14#include <linux/regmap.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/leds.h>
19#include <linux/err.h>
20#include <linux/spinlock.h>
21#include <linux/of_platform.h>
22#include <linux/of_device.h>
23#include <linux/spmi.h>
24#include <linux/platform_device.h>
25#include <linux/qpnp/pwm.h>
26#include <linux/workqueue.h>
27#include <linux/delay.h>
28#include <linux/regulator/consumer.h>
29#include <linux/delay.h>
30
31#define WLED_MOD_EN_REG(base, n) (base + 0x60 + n*0x10)
32#define WLED_IDAC_DLY_REG(base, n) (WLED_MOD_EN_REG(base, n) + 0x01)
33#define WLED_FULL_SCALE_REG(base, n) (WLED_IDAC_DLY_REG(base, n) + 0x01)
34#define WLED_MOD_SRC_SEL_REG(base, n) (WLED_FULL_SCALE_REG(base, n) + 0x01)
35
36/* wled control registers */
37#define WLED_OVP_INT_STATUS(base) (base + 0x10)
38#define WLED_BRIGHTNESS_CNTL_LSB(base, n) (base + 0x40 + 2*n)
39#define WLED_BRIGHTNESS_CNTL_MSB(base, n) (base + 0x41 + 2*n)
40#define WLED_MOD_CTRL_REG(base) (base + 0x46)
41#define WLED_SYNC_REG(base) (base + 0x47)
42#define WLED_FDBCK_CTRL_REG(base) (base + 0x48)
43#define WLED_SWITCHING_FREQ_REG(base) (base + 0x4C)
44#define WLED_OVP_CFG_REG(base) (base + 0x4D)
45#define WLED_BOOST_LIMIT_REG(base) (base + 0x4E)
46#define WLED_CURR_SINK_REG(base) (base + 0x4F)
47#define WLED_HIGH_POLE_CAP_REG(base) (base + 0x58)
48#define WLED_CURR_SINK_MASK 0xE0
49#define WLED_CURR_SINK_SHFT 0x05
50#define WLED_DISABLE_ALL_SINKS 0x00
51#define WLED_DISABLE_1_2_SINKS 0x80
52#define WLED_SWITCH_FREQ_MASK 0x0F
53#define WLED_OVP_VAL_MASK 0x03
54#define WLED_OVP_INT_MASK 0x02
55#define WLED_OVP_VAL_BIT_SHFT 0x00
56#define WLED_BOOST_LIMIT_MASK 0x07
57#define WLED_BOOST_LIMIT_BIT_SHFT 0x00
58#define WLED_BOOST_ON 0x80
59#define WLED_BOOST_OFF 0x00
60#define WLED_EN_MASK 0x80
61#define WLED_NO_MASK 0x00
62#define WLED_CP_SELECT_MAX 0x03
63#define WLED_CP_SELECT_MASK 0x02
64#define WLED_USE_EXT_GEN_MOD_SRC 0x01
65#define WLED_CTL_DLY_STEP 200
66#define WLED_CTL_DLY_MAX 1400
67#define WLED_MAX_CURR 25
68#define WLED_NO_CURRENT 0x00
69#define WLED_OVP_DELAY 1000
70#define WLED_OVP_DELAY_INT 200
71#define WLED_OVP_DELAY_LOOP 100
72#define WLED_MSB_MASK 0x0F
73#define WLED_MAX_CURR_MASK 0x1F
74#define WLED_OP_FDBCK_MASK 0x07
75#define WLED_OP_FDBCK_BIT_SHFT 0x00
76#define WLED_OP_FDBCK_DEFAULT 0x00
77
78#define WLED_SET_ILIM_CODE 0x01
79
80#define WLED_MAX_LEVEL 4095
81#define WLED_8_BIT_MASK 0xFF
82#define WLED_4_BIT_MASK 0x0F
83#define WLED_8_BIT_SHFT 0x08
84#define WLED_MAX_DUTY_CYCLE 0xFFF
85
86#define WLED_SYNC_VAL 0x07
87#define WLED_SYNC_RESET_VAL 0x00
88
89#define PMIC_VER_8026 0x04
90#define PMIC_VER_8941 0x01
91#define PMIC_VERSION_REG 0x0105
92
93#define WLED_DEFAULT_STRINGS 0x01
94#define WLED_THREE_STRINGS 0x03
95#define WLED_MAX_TRIES 5
96#define WLED_DEFAULT_OVP_VAL 0x02
97#define WLED_BOOST_LIM_DEFAULT 0x03
98#define WLED_CP_SEL_DEFAULT 0x00
99#define WLED_CTRL_DLY_DEFAULT 0x00
100#define WLED_SWITCH_FREQ_DEFAULT 0x0B
101
102#define FLASH_SAFETY_TIMER(base) (base + 0x40)
103#define FLASH_MAX_CURR(base) (base + 0x41)
104#define FLASH_LED_0_CURR(base) (base + 0x42)
105#define FLASH_LED_1_CURR(base) (base + 0x43)
106#define FLASH_CLAMP_CURR(base) (base + 0x44)
107#define FLASH_LED_TMR_CTRL(base) (base + 0x48)
108#define FLASH_HEADROOM(base) (base + 0x4A)
109#define FLASH_STARTUP_DELAY(base) (base + 0x4B)
110#define FLASH_MASK_ENABLE(base) (base + 0x4C)
111#define FLASH_VREG_OK_FORCE(base) (base + 0x4F)
112#define FLASH_ENABLE_CONTROL(base) (base + 0x46)
113#define FLASH_LED_STROBE_CTRL(base) (base + 0x47)
114#define FLASH_WATCHDOG_TMR(base) (base + 0x49)
115#define FLASH_FAULT_DETECT(base) (base + 0x51)
116#define FLASH_PERIPHERAL_SUBTYPE(base) (base + 0x05)
117#define FLASH_CURRENT_RAMP(base) (base + 0x54)
118
119#define FLASH_MAX_LEVEL 0x4F
120#define TORCH_MAX_LEVEL 0x0F
121#define FLASH_NO_MASK 0x00
122
123#define FLASH_MASK_1 0x20
124#define FLASH_MASK_REG_MASK 0xE0
125#define FLASH_HEADROOM_MASK 0x03
126#define FLASH_SAFETY_TIMER_MASK 0x7F
127#define FLASH_CURRENT_MASK 0xFF
128#define FLASH_MAX_CURRENT_MASK 0x7F
129#define FLASH_TMR_MASK 0x03
130#define FLASH_TMR_WATCHDOG 0x03
131#define FLASH_TMR_SAFETY 0x00
132#define FLASH_FAULT_DETECT_MASK 0X80
133#define FLASH_HW_VREG_OK 0x40
134#define FLASH_SW_VREG_OK 0x80
135#define FLASH_VREG_MASK 0xC0
136#define FLASH_STARTUP_DLY_MASK 0x02
137#define FLASH_CURRENT_RAMP_MASK 0xBF
138
139#define FLASH_ENABLE_ALL 0xE0
140#define FLASH_ENABLE_MODULE 0x80
141#define FLASH_ENABLE_MODULE_MASK 0x80
142#define FLASH_DISABLE_ALL 0x00
143#define FLASH_ENABLE_MASK 0xE0
144#define FLASH_ENABLE_LED_0 0xC0
145#define FLASH_ENABLE_LED_1 0xA0
146#define FLASH_INIT_MASK 0xE0
147#define FLASH_SELFCHECK_ENABLE 0x80
148#define FLASH_WATCHDOG_MASK 0x1F
149#define FLASH_RAMP_STEP_27US 0xBF
150
151#define FLASH_HW_SW_STROBE_SEL_MASK 0x04
152#define FLASH_STROBE_MASK 0xC7
153#define FLASH_LED_0_OUTPUT 0x80
154#define FLASH_LED_1_OUTPUT 0x40
155#define FLASH_TORCH_OUTPUT 0xC0
156
157#define FLASH_CURRENT_PRGM_MIN 1
158#define FLASH_CURRENT_PRGM_SHIFT 1
159#define FLASH_CURRENT_MAX 0x4F
160#define FLASH_CURRENT_TORCH 0x07
161
162#define FLASH_DURATION_200ms 0x13
163#define TORCH_DURATION_12s 0x0A
164#define FLASH_CLAMP_200mA 0x0F
165
166#define FLASH_SUBTYPE_DUAL 0x01
167#define FLASH_SUBTYPE_SINGLE 0x02
168
169#define FLASH_RAMP_UP_DELAY_US 1000
170#define FLASH_RAMP_DN_DELAY_US 2160
171
172#define LED_TRIGGER_DEFAULT "none"
173
174#define RGB_LED_SRC_SEL(base) (base + 0x45)
175#define RGB_LED_EN_CTL(base) (base + 0x46)
176#define RGB_LED_ATC_CTL(base) (base + 0x47)
177
178#define RGB_MAX_LEVEL LED_FULL
179#define RGB_LED_ENABLE_RED 0x80
180#define RGB_LED_ENABLE_GREEN 0x40
181#define RGB_LED_ENABLE_BLUE 0x20
182#define RGB_LED_SOURCE_VPH_PWR 0x01
183#define RGB_LED_ENABLE_MASK 0xE0
184#define RGB_LED_SRC_MASK 0x03
185#define QPNP_LED_PWM_FLAGS (PM_PWM_LUT_LOOP | PM_PWM_LUT_RAMP_UP)
186#define QPNP_LUT_RAMP_STEP_DEFAULT 255
187#define PWM_LUT_MAX_SIZE 63
188#define PWM_GPLED_LUT_MAX_SIZE 31
189#define RGB_LED_DISABLE 0x00
190
191#define MPP_MAX_LEVEL LED_FULL
192#define LED_MPP_MODE_CTRL(base) (base + 0x40)
193#define LED_MPP_VIN_CTRL(base) (base + 0x41)
194#define LED_MPP_EN_CTRL(base) (base + 0x46)
195#define LED_MPP_SINK_CTRL(base) (base + 0x4C)
196
197#define LED_MPP_CURRENT_MIN 5
198#define LED_MPP_CURRENT_MAX 40
199#define LED_MPP_VIN_CTRL_DEFAULT 0
200#define LED_MPP_CURRENT_PER_SETTING 5
201#define LED_MPP_SOURCE_SEL_DEFAULT LED_MPP_MODE_ENABLE
202
203#define LED_MPP_SINK_MASK 0x07
204#define LED_MPP_MODE_MASK 0x7F
205#define LED_MPP_VIN_MASK 0x03
206#define LED_MPP_EN_MASK 0x80
207#define LED_MPP_SRC_MASK 0x0F
208#define LED_MPP_MODE_CTRL_MASK 0x70
209
210#define LED_MPP_MODE_SINK (0x06 << 4)
211#define LED_MPP_MODE_ENABLE 0x01
212#define LED_MPP_MODE_OUTPUT 0x10
213#define LED_MPP_MODE_DISABLE 0x00
214#define LED_MPP_EN_ENABLE 0x80
215#define LED_MPP_EN_DISABLE 0x00
216
217#define MPP_SOURCE_DTEST1 0x08
218
219#define GPIO_MAX_LEVEL LED_FULL
220#define LED_GPIO_MODE_CTRL(base) (base + 0x40)
221#define LED_GPIO_VIN_CTRL(base) (base + 0x41)
222#define LED_GPIO_EN_CTRL(base) (base + 0x46)
223
224#define LED_GPIO_VIN_CTRL_DEFAULT 0
225#define LED_GPIO_SOURCE_SEL_DEFAULT LED_GPIO_MODE_ENABLE
226
227#define LED_GPIO_MODE_MASK 0x3F
228#define LED_GPIO_VIN_MASK 0x0F
229#define LED_GPIO_EN_MASK 0x80
230#define LED_GPIO_SRC_MASK 0x0F
231#define LED_GPIO_MODE_CTRL_MASK 0x30
232
233#define LED_GPIO_MODE_ENABLE 0x01
234#define LED_GPIO_MODE_DISABLE 0x00
235#define LED_GPIO_MODE_OUTPUT 0x10
236#define LED_GPIO_EN_ENABLE 0x80
237#define LED_GPIO_EN_DISABLE 0x00
238
239#define KPDBL_MAX_LEVEL LED_FULL
240#define KPDBL_ROW_SRC_SEL(base) (base + 0x40)
241#define KPDBL_ENABLE(base) (base + 0x46)
242#define KPDBL_ROW_SRC(base) (base + 0xE5)
243
244#define KPDBL_ROW_SRC_SEL_VAL_MASK 0x0F
245#define KPDBL_ROW_SCAN_EN_MASK 0x80
246#define KPDBL_ROW_SCAN_VAL_MASK 0x0F
247#define KPDBL_ROW_SCAN_EN_SHIFT 7
248#define KPDBL_MODULE_EN 0x80
249#define KPDBL_MODULE_DIS 0x00
250#define KPDBL_MODULE_EN_MASK 0x80
251#define NUM_KPDBL_LEDS 4
252#define KPDBL_MASTER_BIT_INDEX 0
253
254/**
255 * enum qpnp_leds - QPNP supported led ids
256 * @QPNP_ID_WLED - White led backlight
257 */
258enum qpnp_leds {
259 QPNP_ID_WLED = 0,
260 QPNP_ID_FLASH1_LED0,
261 QPNP_ID_FLASH1_LED1,
262 QPNP_ID_RGB_RED,
263 QPNP_ID_RGB_GREEN,
264 QPNP_ID_RGB_BLUE,
265 QPNP_ID_LED_MPP,
266 QPNP_ID_KPDBL,
267 QPNP_ID_LED_GPIO,
268 QPNP_ID_MAX,
269};
270
271/* current boost limit */
272enum wled_current_boost_limit {
273 WLED_CURR_LIMIT_105mA,
274 WLED_CURR_LIMIT_385mA,
275 WLED_CURR_LIMIT_525mA,
276 WLED_CURR_LIMIT_805mA,
277 WLED_CURR_LIMIT_980mA,
278 WLED_CURR_LIMIT_1260mA,
279 WLED_CURR_LIMIT_1400mA,
280 WLED_CURR_LIMIT_1680mA,
281};
282
283/* over voltage protection threshold */
284enum wled_ovp_threshold {
285 WLED_OVP_35V,
286 WLED_OVP_32V,
287 WLED_OVP_29V,
288 WLED_OVP_27V,
289};
290
291enum flash_headroom {
292 HEADROOM_250mV = 0,
293 HEADROOM_300mV,
294 HEADROOM_400mV,
295 HEADROOM_500mV,
296};
297
298enum flash_startup_dly {
299 DELAY_10us = 0,
300 DELAY_32us,
301 DELAY_64us,
302 DELAY_128us,
303};
304
305enum led_mode {
306 PWM_MODE = 0,
307 LPG_MODE,
308 MANUAL_MODE,
309};
310
311static u8 wled_debug_regs[] = {
312 /* brightness registers */
313 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
314 /* common registers */
315 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
316 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
317 /* LED1 */
318 0x60, 0x61, 0x62, 0x63, 0x66,
319 /* LED2 */
320 0x70, 0x71, 0x72, 0x73, 0x76,
321 /* LED3 */
322 0x80, 0x81, 0x82, 0x83, 0x86,
323};
324
325static u8 flash_debug_regs[] = {
326 0x40, 0x41, 0x42, 0x43, 0x44, 0x48, 0x49, 0x4b, 0x4c,
327 0x4f, 0x46, 0x47,
328};
329
330static u8 rgb_pwm_debug_regs[] = {
331 0x45, 0x46, 0x47,
332};
333
334static u8 mpp_debug_regs[] = {
335 0x40, 0x41, 0x42, 0x45, 0x46, 0x4c,
336};
337
338static u8 kpdbl_debug_regs[] = {
339 0x40, 0x46, 0xb1, 0xb3, 0xb4, 0xe5,
340};
341
342static u8 gpio_debug_regs[] = {
343 0x40, 0x41, 0x42, 0x45, 0x46,
344};
345
346/**
347 * pwm_config_data - pwm configuration data
348 * @lut_params - lut parameters to be used by pwm driver
349 * @pwm_device - pwm device
350 * @pwm_period_us - period for pwm, in us
351 * @mode - mode the led operates in
352 * @old_duty_pcts - storage for duty pcts that may need to be reused
353 * @default_mode - default mode of LED as set in device tree
354 * @use_blink - use blink sysfs entry
355 * @blinking - device is currently blinking w/LPG mode
356 */
357struct pwm_config_data {
358 struct lut_params lut_params;
359 struct pwm_device *pwm_dev;
360 u32 pwm_period_us;
361 struct pwm_duty_cycles *duty_cycles;
362 int *old_duty_pcts;
363 u8 mode;
364 u8 default_mode;
365 bool pwm_enabled;
366 bool use_blink;
367 bool blinking;
368};
369
370/**
371 * wled_config_data - wled configuration data
372 * @num_strings - number of wled strings to be configured
373 * @num_physical_strings - physical number of strings supported
374 * @ovp_val - over voltage protection threshold
375 * @boost_curr_lim - boot current limit
376 * @cp_select - high pole capacitance
377 * @ctrl_delay_us - delay in activation of led
378 * @dig_mod_gen_en - digital module generator
379 * @cs_out_en - current sink output enable
380 * @op_fdbck - selection of output as feedback for the boost
381 */
382struct wled_config_data {
383 u8 num_strings;
384 u8 num_physical_strings;
385 u8 ovp_val;
386 u8 boost_curr_lim;
387 u8 cp_select;
388 u8 ctrl_delay_us;
389 u8 switch_freq;
390 u8 op_fdbck;
391 u8 pmic_version;
392 bool dig_mod_gen_en;
393 bool cs_out_en;
394};
395
396/**
397 * mpp_config_data - mpp configuration data
398 * @pwm_cfg - device pwm configuration
399 * @current_setting - current setting, 5ma-40ma in 5ma increments
400 * @source_sel - source selection
401 * @mode_ctrl - mode control
402 * @vin_ctrl - input control
403 * @min_brightness - minimum brightness supported
404 * @pwm_mode - pwm mode in use
405 * @max_uV - maximum regulator voltage
406 * @min_uV - minimum regulator voltage
407 * @mpp_reg - regulator to power mpp based LED
408 * @enable - flag indicating LED on or off
409 */
410struct mpp_config_data {
411 struct pwm_config_data *pwm_cfg;
412 u8 current_setting;
413 u8 source_sel;
414 u8 mode_ctrl;
415 u8 vin_ctrl;
416 u8 min_brightness;
417 u8 pwm_mode;
418 u32 max_uV;
419 u32 min_uV;
420 struct regulator *mpp_reg;
421 bool enable;
422};
423
424/**
425 * flash_config_data - flash configuration data
426 * @current_prgm - current to be programmed, scaled by max level
427 * @clamp_curr - clamp current to use
428 * @headroom - headroom value to use
429 * @duration - duration of the flash
430 * @enable_module - enable address for particular flash
431 * @trigger_flash - trigger flash
432 * @startup_dly - startup delay for flash
433 * @strobe_type - select between sw and hw strobe
434 * @peripheral_subtype - module peripheral subtype
435 * @current_addr - address to write for current
436 * @second_addr - address of secondary flash to be written
437 * @safety_timer - enable safety timer or watchdog timer
438 * @torch_enable - enable flash LED torch mode
439 * @flash_reg_get - flash regulator attached or not
440 * @flash_wa_reg_get - workaround regulator attached or not
441 * @flash_on - flash status, on or off
442 * @torch_on - torch status, on or off
443 * @vreg_ok - specifies strobe type, sw or hw
444 * @no_smbb_support - specifies if smbb boost is not required and there is a
445 single regulator for both flash and torch
446 * @flash_boost_reg - boost regulator for flash
447 * @torch_boost_reg - boost regulator for torch
448 * @flash_wa_reg - flash regulator for wa
449 */
450struct flash_config_data {
451 u8 current_prgm;
452 u8 clamp_curr;
453 u8 headroom;
454 u8 duration;
455 u8 enable_module;
456 u8 trigger_flash;
457 u8 startup_dly;
458 u8 strobe_type;
459 u8 peripheral_subtype;
460 u16 current_addr;
461 u16 second_addr;
462 bool safety_timer;
463 bool torch_enable;
464 bool flash_reg_get;
465 bool flash_wa_reg_get;
466 bool flash_on;
467 bool torch_on;
468 bool vreg_ok;
469 bool no_smbb_support;
470 struct regulator *flash_boost_reg;
471 struct regulator *torch_boost_reg;
472 struct regulator *flash_wa_reg;
473};
474
475/**
476 * kpdbl_config_data - kpdbl configuration data
477 * @pwm_cfg - device pwm configuration
478 * @mode - running mode: pwm or lut
479 * @row_id - row id of the led
480 * @row_src_vbst - 0 for vph_pwr and 1 for vbst
481 * @row_src_en - enable row source
482 * @always_on - always on row
483 * @lut_params - lut parameters to be used by pwm driver
484 * @duty_cycles - duty cycles for lut
485 * @pwm_mode - pwm mode in use
486 */
487struct kpdbl_config_data {
488 struct pwm_config_data *pwm_cfg;
489 u32 row_id;
490 bool row_src_vbst;
491 bool row_src_en;
492 bool always_on;
493 struct pwm_duty_cycles *duty_cycles;
494 struct lut_params lut_params;
495 u8 pwm_mode;
496};
497
498/**
499 * rgb_config_data - rgb configuration data
500 * @pwm_cfg - device pwm configuration
501 * @enable - bits to enable led
502 */
503struct rgb_config_data {
504 struct pwm_config_data *pwm_cfg;
505 u8 enable;
506};
507
508/**
509 * gpio_config_data - gpio configuration data
510 * @source_sel - source selection
511 * @mode_ctrl - mode control
512 * @vin_ctrl - input control
513 * @enable - flag indicating LED on or off
514 */
515struct gpio_config_data {
516 u8 source_sel;
517 u8 mode_ctrl;
518 u8 vin_ctrl;
519 bool enable;
520};
521
522/**
523 * struct qpnp_led_data - internal led data structure
524 * @led_classdev - led class device
525 * @delayed_work - delayed work for turning off the LED
526 * @workqueue - dedicated workqueue to handle concurrency
527 * @work - workqueue for led
528 * @id - led index
529 * @base_reg - base register given in device tree
530 * @lock - to protect the transactions
531 * @reg - cached value of led register
532 * @num_leds - number of leds in the module
533 * @max_current - maximum current supported by LED
534 * @default_on - true: default state max, false, default state 0
535 * @turn_off_delay_ms - number of msec before turning off the LED
536 */
537struct qpnp_led_data {
538 struct led_classdev cdev;
539 struct platform_device *pdev;
540 struct regmap *regmap;
541 struct delayed_work dwork;
542 struct workqueue_struct *workqueue;
543 struct work_struct work;
544 int id;
545 u16 base;
546 u8 reg;
547 u8 num_leds;
548 struct mutex lock;
549 struct wled_config_data *wled_cfg;
550 struct flash_config_data *flash_cfg;
551 struct kpdbl_config_data *kpdbl_cfg;
552 struct rgb_config_data *rgb_cfg;
553 struct mpp_config_data *mpp_cfg;
554 struct gpio_config_data *gpio_cfg;
555 int max_current;
556 bool default_on;
557 bool in_order_command_processing;
558 int turn_off_delay_ms;
559};
560
561static DEFINE_MUTEX(flash_lock);
562static struct pwm_device *kpdbl_master;
563static u32 kpdbl_master_period_us;
564DECLARE_BITMAP(kpdbl_leds_in_use, NUM_KPDBL_LEDS);
565static bool is_kpdbl_master_turn_on;
566
567static int
568qpnp_led_masked_write(struct qpnp_led_data *led, u16 addr, u8 mask, u8 val)
569{
570 int rc;
571
572 rc = regmap_update_bits(led->regmap, addr, mask, val);
573 if (rc)
574 dev_err(&led->pdev->dev,
575 "Unable to regmap_update_bits to addr=%x, rc(%d)\n",
576 addr, rc);
577 return rc;
578}
579
580static void qpnp_dump_regs(struct qpnp_led_data *led, u8 regs[], u8 array_size)
581{
582 int i;
583 u8 val;
584
585 pr_debug("===== %s LED register dump start =====\n", led->cdev.name);
586 for (i = 0; i < array_size; i++) {
587 regmap_bulk_read(led->regmap, led->base + regs[i], &val,
588 sizeof(val));
589 pr_debug("%s: 0x%x = 0x%x\n", led->cdev.name,
590 led->base + regs[i], val);
591 }
592 pr_debug("===== %s LED register dump end =====\n", led->cdev.name);
593}
594
595static int qpnp_wled_sync(struct qpnp_led_data *led)
596{
597 int rc;
598 u8 val;
599
600 /* sync */
601 val = WLED_SYNC_VAL;
602 rc = regmap_write(led->regmap, WLED_SYNC_REG(led->base), val);
603 if (rc) {
604 dev_err(&led->pdev->dev,
605 "WLED set sync reg failed(%d)\n", rc);
606 return rc;
607 }
608
609 val = WLED_SYNC_RESET_VAL;
610 rc = regmap_write(led->regmap, WLED_SYNC_REG(led->base), val);
611 if (rc) {
612 dev_err(&led->pdev->dev,
613 "WLED reset sync reg failed(%d)\n", rc);
614 return rc;
615 }
616 return 0;
617}
618
619static int qpnp_wled_set(struct qpnp_led_data *led)
620{
621 int rc, duty, level, tries = 0;
622 u8 val, i, num_wled_strings;
623 uint sink_val, ilim_val, ovp_val;
624
625 num_wled_strings = led->wled_cfg->num_strings;
626
627 level = led->cdev.brightness;
628
629 if (level > WLED_MAX_LEVEL)
630 level = WLED_MAX_LEVEL;
631 if (level == 0) {
632 for (i = 0; i < num_wled_strings; i++) {
633 rc = qpnp_led_masked_write(led,
634 WLED_FULL_SCALE_REG(led->base, i),
635 WLED_MAX_CURR_MASK, WLED_NO_CURRENT);
636 if (rc) {
637 dev_err(&led->pdev->dev,
638 "Write max current failure (%d)\n",
639 rc);
640 return rc;
641 }
642 }
643
644 rc = qpnp_wled_sync(led);
645 if (rc) {
646 dev_err(&led->pdev->dev,
647 "WLED sync failed(%d)\n", rc);
648 return rc;
649 }
650
651 rc = regmap_read(led->regmap, WLED_CURR_SINK_REG(led->base),
652 &sink_val);
653 if (rc) {
654 dev_err(&led->pdev->dev,
655 "WLED read sink reg failed(%d)\n", rc);
656 return rc;
657 }
658
659 if (led->wled_cfg->pmic_version == PMIC_VER_8026) {
660 val = WLED_DISABLE_ALL_SINKS;
661 rc = regmap_write(led->regmap,
662 WLED_CURR_SINK_REG(led->base), val);
663 if (rc) {
664 dev_err(&led->pdev->dev,
665 "WLED write sink reg failed(%d)\n", rc);
666 return rc;
667 }
668
669 usleep_range(WLED_OVP_DELAY, WLED_OVP_DELAY + 10);
670 } else if (led->wled_cfg->pmic_version == PMIC_VER_8941) {
671 if (led->wled_cfg->num_physical_strings <=
672 WLED_THREE_STRINGS) {
673 val = WLED_DISABLE_1_2_SINKS;
674 rc = regmap_write(led->regmap,
675 WLED_CURR_SINK_REG(led->base),
676 val);
677 if (rc) {
678 dev_err(&led->pdev->dev,
679 "WLED write sink reg failed");
680 return rc;
681 }
682
683 rc = regmap_read(led->regmap,
684 WLED_BOOST_LIMIT_REG(led->base),
685 &ilim_val);
686 if (rc) {
687 dev_err(&led->pdev->dev,
688 "Unable to read boost reg");
689 }
690 val = WLED_SET_ILIM_CODE;
691 rc = regmap_write(led->regmap,
692 WLED_BOOST_LIMIT_REG(led->base),
693 val);
694 if (rc) {
695 dev_err(&led->pdev->dev,
696 "WLED write sink reg failed");
697 return rc;
698 }
699 usleep_range(WLED_OVP_DELAY,
700 WLED_OVP_DELAY + 10);
701 } else {
702 val = WLED_DISABLE_ALL_SINKS;
703 rc = regmap_write(led->regmap,
704 WLED_CURR_SINK_REG(led->base),
705 val);
706 if (rc) {
707 dev_err(&led->pdev->dev,
708 "WLED write sink reg failed");
709 return rc;
710 }
711
712 msleep(WLED_OVP_DELAY_INT);
713 while (tries < WLED_MAX_TRIES) {
714 rc = regmap_read(led->regmap,
715 WLED_OVP_INT_STATUS(led->base),
716 &ovp_val);
717 if (rc) {
718 dev_err(&led->pdev->dev,
719 "Unable to read boost reg");
720 }
721
722 if (ovp_val & WLED_OVP_INT_MASK)
723 break;
724
725 msleep(WLED_OVP_DELAY_LOOP);
726 tries++;
727 }
728 usleep_range(WLED_OVP_DELAY,
729 WLED_OVP_DELAY + 10);
730 }
731 }
732
733 val = WLED_BOOST_OFF;
734 rc = regmap_write(led->regmap, WLED_MOD_CTRL_REG(led->base),
735 val);
736 if (rc) {
737 dev_err(&led->pdev->dev,
738 "WLED write ctrl reg failed(%d)\n", rc);
739 return rc;
740 }
741
742 for (i = 0; i < num_wled_strings; i++) {
743 rc = qpnp_led_masked_write(led,
744 WLED_FULL_SCALE_REG(led->base, i),
745 WLED_MAX_CURR_MASK, (u8)led->max_current);
746 if (rc) {
747 dev_err(&led->pdev->dev,
748 "Write max current failure (%d)\n",
749 rc);
750 return rc;
751 }
752 }
753
754 rc = qpnp_wled_sync(led);
755 if (rc) {
756 dev_err(&led->pdev->dev,
757 "WLED sync failed(%d)\n", rc);
758 return rc;
759 }
760
761 if (led->wled_cfg->pmic_version == PMIC_VER_8941) {
762 if (led->wled_cfg->num_physical_strings <=
763 WLED_THREE_STRINGS) {
764 rc = regmap_write(led->regmap,
765 WLED_BOOST_LIMIT_REG(led->base),
766 ilim_val);
767 if (rc) {
768 dev_err(&led->pdev->dev,
769 "WLED write sink reg failed");
770 return rc;
771 }
772 } else {
773 /* restore OVP to original value */
774 rc = regmap_write(led->regmap,
775 WLED_OVP_CFG_REG(led->base),
776 *&led->wled_cfg->ovp_val);
777 if (rc) {
778 dev_err(&led->pdev->dev,
779 "WLED write sink reg failed");
780 return rc;
781 }
782 }
783 }
784
785 /* re-enable all sinks */
786 rc = regmap_write(led->regmap, WLED_CURR_SINK_REG(led->base),
787 sink_val);
788 if (rc) {
789 dev_err(&led->pdev->dev,
790 "WLED write sink reg failed(%d)\n", rc);
791 return rc;
792 }
793
794 } else {
795 val = WLED_BOOST_ON;
796 rc = regmap_write(led->regmap, WLED_MOD_CTRL_REG(led->base),
797 val);
798 if (rc) {
799 dev_err(&led->pdev->dev,
800 "WLED write ctrl reg failed(%d)\n", rc);
801 return rc;
802 }
803 }
804
805 duty = (WLED_MAX_DUTY_CYCLE * level) / WLED_MAX_LEVEL;
806
807 /* program brightness control registers */
808 for (i = 0; i < num_wled_strings; i++) {
809 rc = qpnp_led_masked_write(led,
810 WLED_BRIGHTNESS_CNTL_MSB(led->base, i), WLED_MSB_MASK,
811 (duty >> WLED_8_BIT_SHFT) & WLED_4_BIT_MASK);
812 if (rc) {
813 dev_err(&led->pdev->dev,
814 "WLED set brightness MSB failed(%d)\n", rc);
815 return rc;
816 }
817 val = duty & WLED_8_BIT_MASK;
818 rc = regmap_write(led->regmap,
819 WLED_BRIGHTNESS_CNTL_LSB(led->base, i), val);
820 if (rc) {
821 dev_err(&led->pdev->dev,
822 "WLED set brightness LSB failed(%d)\n", rc);
823 return rc;
824 }
825 }
826
827 rc = qpnp_wled_sync(led);
828 if (rc) {
829 dev_err(&led->pdev->dev, "WLED sync failed(%d)\n", rc);
830 return rc;
831 }
832 return 0;
833}
834
835static int qpnp_mpp_set(struct qpnp_led_data *led)
836{
837 int rc;
838 u8 val;
839 int duty_us, duty_ns, period_us;
840
841 if (led->cdev.brightness) {
842 if (led->mpp_cfg->mpp_reg && !led->mpp_cfg->enable) {
843 rc = regulator_set_voltage(led->mpp_cfg->mpp_reg,
844 led->mpp_cfg->min_uV,
845 led->mpp_cfg->max_uV);
846 if (rc) {
847 dev_err(&led->pdev->dev,
848 "Regulator voltage set failed rc=%d\n",
849 rc);
850 return rc;
851 }
852
853 rc = regulator_enable(led->mpp_cfg->mpp_reg);
854 if (rc) {
855 dev_err(&led->pdev->dev,
856 "Regulator enable failed(%d)\n", rc);
857 goto err_reg_enable;
858 }
859 }
860
861 led->mpp_cfg->enable = true;
862
863 if (led->cdev.brightness < led->mpp_cfg->min_brightness) {
864 dev_warn(&led->pdev->dev, "brightness is less than supported, set to minimum supported\n");
865 led->cdev.brightness = led->mpp_cfg->min_brightness;
866 }
867
868 if (led->mpp_cfg->pwm_mode != MANUAL_MODE) {
869 if (!led->mpp_cfg->pwm_cfg->blinking) {
870 led->mpp_cfg->pwm_cfg->mode =
871 led->mpp_cfg->pwm_cfg->default_mode;
872 led->mpp_cfg->pwm_mode =
873 led->mpp_cfg->pwm_cfg->default_mode;
874 }
875 }
876 if (led->mpp_cfg->pwm_mode == PWM_MODE) {
877 /*config pwm for brightness scaling*/
Fenglin Wu9a5329e2017-08-14 12:50:10 +0800878 rc = pwm_change_mode(led->mpp_cfg->pwm_cfg->pwm_dev,
879 PM_PWM_MODE_PWM);
880 if (rc < 0) {
881 dev_err(&led->pdev->dev,
882 "Failed to set PWM mode, rc = %d\n",
883 rc);
884 return rc;
885 }
David Collins8885f792017-01-26 14:36:34 -0800886 period_us = led->mpp_cfg->pwm_cfg->pwm_period_us;
887 if (period_us > INT_MAX / NSEC_PER_USEC) {
888 duty_us = (period_us * led->cdev.brightness) /
889 LED_FULL;
890 rc = pwm_config_us(
891 led->mpp_cfg->pwm_cfg->pwm_dev,
892 duty_us,
893 period_us);
894 } else {
895 duty_ns = ((period_us * NSEC_PER_USEC) /
896 LED_FULL) * led->cdev.brightness;
897 rc = pwm_config(
898 led->mpp_cfg->pwm_cfg->pwm_dev,
899 duty_ns,
900 period_us * NSEC_PER_USEC);
901 }
902 if (rc < 0) {
903 dev_err(&led->pdev->dev, "Failed to configure pwm for new values\n");
904 goto err_mpp_reg_write;
905 }
906 }
907
Fenglin Wu325e6de2017-03-16 13:40:26 +0800908 if (led->mpp_cfg->pwm_mode != MANUAL_MODE) {
David Collins8885f792017-01-26 14:36:34 -0800909 pwm_enable(led->mpp_cfg->pwm_cfg->pwm_dev);
Fenglin Wu325e6de2017-03-16 13:40:26 +0800910 led->mpp_cfg->pwm_cfg->pwm_enabled = 1;
911 } else {
David Collins8885f792017-01-26 14:36:34 -0800912 if (led->cdev.brightness < LED_MPP_CURRENT_MIN)
913 led->cdev.brightness = LED_MPP_CURRENT_MIN;
914 else {
915 /*
916 * PMIC supports LED intensity from 5mA - 40mA
917 * in steps of 5mA. Brightness is rounded to
918 * 5mA or nearest lower supported values
919 */
920 led->cdev.brightness /= LED_MPP_CURRENT_MIN;
921 led->cdev.brightness *= LED_MPP_CURRENT_MIN;
922 }
923
924 val = (led->cdev.brightness / LED_MPP_CURRENT_MIN) - 1;
925
926 rc = qpnp_led_masked_write(led,
927 LED_MPP_SINK_CTRL(led->base),
928 LED_MPP_SINK_MASK, val);
929 if (rc) {
930 dev_err(&led->pdev->dev,
931 "Failed to write sink control reg\n");
932 goto err_mpp_reg_write;
933 }
934 }
935
936 val = (led->mpp_cfg->source_sel & LED_MPP_SRC_MASK) |
937 (led->mpp_cfg->mode_ctrl & LED_MPP_MODE_CTRL_MASK);
938
939 rc = qpnp_led_masked_write(led,
940 LED_MPP_MODE_CTRL(led->base), LED_MPP_MODE_MASK,
941 val);
942 if (rc) {
943 dev_err(&led->pdev->dev,
944 "Failed to write led mode reg\n");
945 goto err_mpp_reg_write;
946 }
947
948 rc = qpnp_led_masked_write(led,
949 LED_MPP_EN_CTRL(led->base), LED_MPP_EN_MASK,
950 LED_MPP_EN_ENABLE);
951 if (rc) {
952 dev_err(&led->pdev->dev, "Failed to write led enable reg\n");
953 goto err_mpp_reg_write;
954 }
955 } else {
956 if (led->mpp_cfg->pwm_mode != MANUAL_MODE) {
957 led->mpp_cfg->pwm_cfg->mode =
958 led->mpp_cfg->pwm_cfg->default_mode;
959 led->mpp_cfg->pwm_mode =
960 led->mpp_cfg->pwm_cfg->default_mode;
961 pwm_disable(led->mpp_cfg->pwm_cfg->pwm_dev);
Fenglin Wu325e6de2017-03-16 13:40:26 +0800962 led->mpp_cfg->pwm_cfg->pwm_enabled = 0;
David Collins8885f792017-01-26 14:36:34 -0800963 }
964 rc = qpnp_led_masked_write(led,
965 LED_MPP_MODE_CTRL(led->base),
966 LED_MPP_MODE_MASK,
967 LED_MPP_MODE_DISABLE);
968 if (rc) {
969 dev_err(&led->pdev->dev,
970 "Failed to write led mode reg\n");
971 goto err_mpp_reg_write;
972 }
973
974 rc = qpnp_led_masked_write(led,
975 LED_MPP_EN_CTRL(led->base),
976 LED_MPP_EN_MASK,
977 LED_MPP_EN_DISABLE);
978 if (rc) {
979 dev_err(&led->pdev->dev,
980 "Failed to write led enable reg\n");
981 goto err_mpp_reg_write;
982 }
983
984 if (led->mpp_cfg->mpp_reg && led->mpp_cfg->enable) {
985 rc = regulator_disable(led->mpp_cfg->mpp_reg);
986 if (rc) {
987 dev_err(&led->pdev->dev,
988 "MPP regulator disable failed(%d)\n",
989 rc);
990 return rc;
991 }
992
993 rc = regulator_set_voltage(led->mpp_cfg->mpp_reg,
994 0, led->mpp_cfg->max_uV);
995 if (rc) {
996 dev_err(&led->pdev->dev,
997 "MPP regulator voltage set failed(%d)\n",
998 rc);
999 return rc;
1000 }
1001 }
1002
1003 led->mpp_cfg->enable = false;
1004 }
1005
1006 if (led->mpp_cfg->pwm_mode != MANUAL_MODE)
1007 led->mpp_cfg->pwm_cfg->blinking = false;
1008 qpnp_dump_regs(led, mpp_debug_regs, ARRAY_SIZE(mpp_debug_regs));
1009
1010 return 0;
1011
1012err_mpp_reg_write:
1013 if (led->mpp_cfg->mpp_reg)
1014 regulator_disable(led->mpp_cfg->mpp_reg);
1015err_reg_enable:
1016 if (led->mpp_cfg->mpp_reg)
1017 regulator_set_voltage(led->mpp_cfg->mpp_reg, 0,
1018 led->mpp_cfg->max_uV);
1019 led->mpp_cfg->enable = false;
1020
1021 return rc;
1022}
1023
1024static int qpnp_gpio_set(struct qpnp_led_data *led)
1025{
1026 int rc, val;
1027
1028 if (led->cdev.brightness) {
1029 val = (led->gpio_cfg->source_sel & LED_GPIO_SRC_MASK) |
1030 (led->gpio_cfg->mode_ctrl & LED_GPIO_MODE_CTRL_MASK);
1031
1032 rc = qpnp_led_masked_write(led,
1033 LED_GPIO_MODE_CTRL(led->base),
1034 LED_GPIO_MODE_MASK,
1035 val);
1036 if (rc) {
1037 dev_err(&led->pdev->dev,
1038 "Failed to write led mode reg\n");
1039 goto err_gpio_reg_write;
1040 }
1041
1042 rc = qpnp_led_masked_write(led,
1043 LED_GPIO_EN_CTRL(led->base),
1044 LED_GPIO_EN_MASK,
1045 LED_GPIO_EN_ENABLE);
1046 if (rc) {
1047 dev_err(&led->pdev->dev,
1048 "Failed to write led enable reg\n");
1049 goto err_gpio_reg_write;
1050 }
1051
1052 led->gpio_cfg->enable = true;
1053 } else {
1054 rc = qpnp_led_masked_write(led,
1055 LED_GPIO_MODE_CTRL(led->base),
1056 LED_GPIO_MODE_MASK,
1057 LED_GPIO_MODE_DISABLE);
1058 if (rc) {
1059 dev_err(&led->pdev->dev,
1060 "Failed to write led mode reg\n");
1061 goto err_gpio_reg_write;
1062 }
1063
1064 rc = qpnp_led_masked_write(led,
1065 LED_GPIO_EN_CTRL(led->base),
1066 LED_GPIO_EN_MASK,
1067 LED_GPIO_EN_DISABLE);
1068 if (rc) {
1069 dev_err(&led->pdev->dev,
1070 "Failed to write led enable reg\n");
1071 goto err_gpio_reg_write;
1072 }
1073
1074 led->gpio_cfg->enable = false;
1075 }
1076
1077 qpnp_dump_regs(led, gpio_debug_regs, ARRAY_SIZE(gpio_debug_regs));
1078
1079 return 0;
1080
1081err_gpio_reg_write:
1082 led->gpio_cfg->enable = false;
1083
1084 return rc;
1085}
1086
1087static int qpnp_flash_regulator_operate(struct qpnp_led_data *led, bool on)
1088{
1089 int rc, i;
1090 struct qpnp_led_data *led_array;
1091 bool regulator_on = false;
1092
1093 led_array = dev_get_drvdata(&led->pdev->dev);
1094 if (!led_array) {
1095 dev_err(&led->pdev->dev, "Unable to get LED array\n");
1096 return -EINVAL;
1097 }
1098
1099 for (i = 0; i < led->num_leds; i++)
1100 regulator_on |= led_array[i].flash_cfg->flash_on;
1101
1102 if (!on)
1103 goto regulator_turn_off;
1104
1105 if (!regulator_on && !led->flash_cfg->flash_on) {
1106 for (i = 0; i < led->num_leds; i++) {
1107 if (led_array[i].flash_cfg->flash_reg_get) {
1108 if (led_array[i].flash_cfg->flash_wa_reg_get) {
1109 rc = regulator_enable(
1110 led_array[i].flash_cfg->
1111 flash_wa_reg);
1112 if (rc) {
1113 dev_err(&led->pdev->dev, "Flash wa regulator enable failed(%d)\n",
1114 rc);
1115 return rc;
1116 }
1117 }
1118
1119 rc = regulator_enable(
1120 led_array[i].flash_cfg->flash_boost_reg);
1121 if (rc) {
1122 if (led_array[i].flash_cfg->
1123 flash_wa_reg_get)
1124 /*
1125 * Disable flash wa regulator
1126 * when flash boost regulator
1127 * enable fails
1128 */
1129 regulator_disable(
1130 led_array[i].flash_cfg->
1131 flash_wa_reg);
1132 dev_err(&led->pdev->dev, "Flash boost regulator enable failed(%d)\n",
1133 rc);
1134 return rc;
1135 }
1136 led->flash_cfg->flash_on = true;
1137 }
1138 break;
1139 }
1140 }
1141
1142 return 0;
1143
1144regulator_turn_off:
1145 if (regulator_on && led->flash_cfg->flash_on) {
1146 for (i = 0; i < led->num_leds; i++) {
1147 if (led_array[i].flash_cfg->flash_reg_get) {
1148 rc = qpnp_led_masked_write(led,
1149 FLASH_ENABLE_CONTROL(led->base),
1150 FLASH_ENABLE_MASK,
1151 FLASH_DISABLE_ALL);
1152 if (rc) {
1153 dev_err(&led->pdev->dev,
1154 "Enable reg write failed(%d)\n",
1155 rc);
1156 }
1157
1158 rc = regulator_disable(
1159 led_array[i].flash_cfg->flash_boost_reg);
1160 if (rc) {
1161 dev_err(&led->pdev->dev, "Flash boost regulator disable failed(%d)\n",
1162 rc);
1163 return rc;
1164 }
1165 if (led_array[i].flash_cfg->flash_wa_reg_get) {
1166 rc = regulator_disable(
1167 led_array[i].flash_cfg->
1168 flash_wa_reg);
1169 if (rc) {
1170 dev_err(&led->pdev->dev, "Flash_wa regulator disable failed(%d)\n",
1171 rc);
1172 return rc;
1173 }
1174 }
1175 led->flash_cfg->flash_on = false;
1176 }
1177 break;
1178 }
1179 }
1180
1181 return 0;
1182}
1183
1184static int qpnp_torch_regulator_operate(struct qpnp_led_data *led, bool on)
1185{
1186 int rc;
1187
1188 if (!on)
1189 goto regulator_turn_off;
1190
1191 if (!led->flash_cfg->torch_on) {
1192 rc = regulator_enable(led->flash_cfg->torch_boost_reg);
1193 if (rc) {
1194 dev_err(&led->pdev->dev,
1195 "Regulator enable failed(%d)\n", rc);
1196 return rc;
1197 }
1198 led->flash_cfg->torch_on = true;
1199 }
1200 return 0;
1201
1202regulator_turn_off:
1203 if (led->flash_cfg->torch_on) {
1204 rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
1205 FLASH_ENABLE_MODULE_MASK, FLASH_DISABLE_ALL);
1206 if (rc) {
1207 dev_err(&led->pdev->dev,
1208 "Enable reg write failed(%d)\n", rc);
1209 }
1210
1211 rc = regulator_disable(led->flash_cfg->torch_boost_reg);
1212 if (rc) {
1213 dev_err(&led->pdev->dev,
1214 "Regulator disable failed(%d)\n", rc);
1215 return rc;
1216 }
1217 led->flash_cfg->torch_on = false;
1218 }
1219 return 0;
1220}
1221
1222static int qpnp_flash_set(struct qpnp_led_data *led)
1223{
Ankit Sharma53252892017-05-22 16:50:52 +05301224 int rc = 0, error;
David Collins8885f792017-01-26 14:36:34 -08001225 int val = led->cdev.brightness;
1226
1227 if (led->flash_cfg->torch_enable)
1228 led->flash_cfg->current_prgm =
1229 (val * TORCH_MAX_LEVEL / led->max_current);
1230 else
1231 led->flash_cfg->current_prgm =
1232 (val * FLASH_MAX_LEVEL / led->max_current);
1233
1234 /* Set led current */
1235 if (val > 0) {
1236 if (led->flash_cfg->torch_enable) {
1237 if (led->flash_cfg->peripheral_subtype ==
1238 FLASH_SUBTYPE_DUAL) {
1239 if (!led->flash_cfg->no_smbb_support)
1240 rc = qpnp_torch_regulator_operate(led,
1241 true);
1242 else
1243 rc = qpnp_flash_regulator_operate(led,
1244 true);
1245 if (rc) {
1246 dev_err(&led->pdev->dev,
1247 "Torch regulator operate failed(%d)\n",
1248 rc);
1249 return rc;
1250 }
1251 } else if (led->flash_cfg->peripheral_subtype ==
1252 FLASH_SUBTYPE_SINGLE) {
1253 rc = qpnp_flash_regulator_operate(led, true);
1254 if (rc) {
1255 dev_err(&led->pdev->dev,
1256 "Flash regulator operate failed(%d)\n",
1257 rc);
1258 goto error_flash_set;
1259 }
1260 }
1261
Ankit Sharma53252892017-05-22 16:50:52 +05301262 rc = qpnp_led_masked_write(led,
1263 FLASH_MAX_CURR(led->base),
David Collins8885f792017-01-26 14:36:34 -08001264 FLASH_CURRENT_MASK,
1265 TORCH_MAX_LEVEL);
1266 if (rc) {
1267 dev_err(&led->pdev->dev,
1268 "Max current reg write failed(%d)\n",
1269 rc);
1270 goto error_reg_write;
1271 }
1272
Ankit Sharma53252892017-05-22 16:50:52 +05301273 rc = qpnp_led_masked_write(led,
David Collins8885f792017-01-26 14:36:34 -08001274 FLASH_LED_TMR_CTRL(led->base),
1275 FLASH_TMR_MASK,
1276 FLASH_TMR_WATCHDOG);
1277 if (rc) {
1278 dev_err(&led->pdev->dev,
1279 "Timer control reg write failed(%d)\n",
1280 rc);
1281 goto error_reg_write;
1282 }
1283
1284 rc = qpnp_led_masked_write(led,
1285 led->flash_cfg->current_addr,
1286 FLASH_CURRENT_MASK,
1287 led->flash_cfg->current_prgm);
1288 if (rc) {
1289 dev_err(&led->pdev->dev,
1290 "Current reg write failed(%d)\n", rc);
1291 goto error_reg_write;
1292 }
1293
1294 rc = qpnp_led_masked_write(led,
1295 led->flash_cfg->second_addr,
1296 FLASH_CURRENT_MASK,
1297 led->flash_cfg->current_prgm);
1298 if (rc) {
1299 dev_err(&led->pdev->dev,
1300 "2nd Current reg write failed(%d)\n",
1301 rc);
1302 goto error_reg_write;
1303 }
1304
Ankit Sharma53252892017-05-22 16:50:52 +05301305 rc = qpnp_led_masked_write(led,
David Collins8885f792017-01-26 14:36:34 -08001306 FLASH_WATCHDOG_TMR(led->base),
1307 FLASH_WATCHDOG_MASK,
1308 led->flash_cfg->duration);
1309 if (rc) {
1310 dev_err(&led->pdev->dev,
1311 "Max current reg write failed(%d)\n",
1312 rc);
1313 goto error_reg_write;
1314 }
1315
1316 rc = qpnp_led_masked_write(led,
1317 FLASH_ENABLE_CONTROL(led->base),
1318 FLASH_ENABLE_MASK,
1319 led->flash_cfg->enable_module);
1320 if (rc) {
1321 dev_err(&led->pdev->dev,
1322 "Enable reg write failed(%d)\n",
1323 rc);
1324 goto error_reg_write;
1325 }
1326
1327 if (!led->flash_cfg->strobe_type)
1328 led->flash_cfg->trigger_flash &=
1329 ~FLASH_HW_SW_STROBE_SEL_MASK;
1330 else
1331 led->flash_cfg->trigger_flash |=
1332 FLASH_HW_SW_STROBE_SEL_MASK;
1333
1334 rc = qpnp_led_masked_write(led,
1335 FLASH_LED_STROBE_CTRL(led->base),
1336 led->flash_cfg->trigger_flash,
1337 led->flash_cfg->trigger_flash);
1338 if (rc) {
1339 dev_err(&led->pdev->dev,
1340 "LED %d strobe reg write failed(%d)\n",
1341 led->id, rc);
1342 goto error_reg_write;
1343 }
1344 } else {
1345 rc = qpnp_flash_regulator_operate(led, true);
1346 if (rc) {
1347 dev_err(&led->pdev->dev,
1348 "Flash regulator operate failed(%d)\n",
1349 rc);
1350 goto error_flash_set;
1351 }
1352
Ankit Sharma53252892017-05-22 16:50:52 +05301353 rc = qpnp_led_masked_write(led,
David Collins8885f792017-01-26 14:36:34 -08001354 FLASH_LED_TMR_CTRL(led->base),
1355 FLASH_TMR_MASK,
1356 FLASH_TMR_SAFETY);
1357 if (rc) {
1358 dev_err(&led->pdev->dev,
1359 "Timer control reg write failed(%d)\n",
1360 rc);
1361 goto error_reg_write;
1362 }
1363
1364 /* Set flash safety timer */
1365 rc = qpnp_led_masked_write(led,
1366 FLASH_SAFETY_TIMER(led->base),
1367 FLASH_SAFETY_TIMER_MASK,
1368 led->flash_cfg->duration);
1369 if (rc) {
1370 dev_err(&led->pdev->dev,
1371 "Safety timer reg write failed(%d)\n",
1372 rc);
1373 goto error_flash_set;
1374 }
1375
1376 /* Set max current */
1377 rc = qpnp_led_masked_write(led,
1378 FLASH_MAX_CURR(led->base), FLASH_CURRENT_MASK,
1379 FLASH_MAX_LEVEL);
1380 if (rc) {
1381 dev_err(&led->pdev->dev,
1382 "Max current reg write failed(%d)\n",
1383 rc);
1384 goto error_flash_set;
1385 }
1386
1387 /* Set clamp current */
1388 rc = qpnp_led_masked_write(led,
1389 FLASH_CLAMP_CURR(led->base),
1390 FLASH_CURRENT_MASK,
1391 led->flash_cfg->clamp_curr);
1392 if (rc) {
1393 dev_err(&led->pdev->dev,
1394 "Clamp current reg write failed(%d)\n",
1395 rc);
1396 goto error_flash_set;
1397 }
1398
1399 rc = qpnp_led_masked_write(led,
1400 led->flash_cfg->current_addr,
1401 FLASH_CURRENT_MASK,
1402 led->flash_cfg->current_prgm);
1403 if (rc) {
1404 dev_err(&led->pdev->dev,
1405 "Current reg write failed(%d)\n", rc);
1406 goto error_flash_set;
1407 }
1408
1409 rc = qpnp_led_masked_write(led,
1410 FLASH_ENABLE_CONTROL(led->base),
1411 led->flash_cfg->enable_module,
1412 led->flash_cfg->enable_module);
1413 if (rc) {
1414 dev_err(&led->pdev->dev,
1415 "Enable reg write failed(%d)\n", rc);
1416 goto error_flash_set;
1417 }
1418
1419 /*
1420 * Add 1ms delay for bharger enter stable state
1421 */
1422 usleep_range(FLASH_RAMP_UP_DELAY_US,
1423 FLASH_RAMP_UP_DELAY_US + 10);
1424
1425 if (!led->flash_cfg->strobe_type)
1426 led->flash_cfg->trigger_flash &=
1427 ~FLASH_HW_SW_STROBE_SEL_MASK;
1428 else
1429 led->flash_cfg->trigger_flash |=
1430 FLASH_HW_SW_STROBE_SEL_MASK;
1431
1432 rc = qpnp_led_masked_write(led,
1433 FLASH_LED_STROBE_CTRL(led->base),
1434 led->flash_cfg->trigger_flash,
1435 led->flash_cfg->trigger_flash);
1436 if (rc) {
1437 dev_err(&led->pdev->dev,
1438 "LED %d strobe reg write failed(%d)\n",
1439 led->id, rc);
1440 goto error_flash_set;
1441 }
1442 }
1443 } else {
1444 rc = qpnp_led_masked_write(led,
1445 FLASH_LED_STROBE_CTRL(led->base),
1446 led->flash_cfg->trigger_flash,
1447 FLASH_DISABLE_ALL);
1448 if (rc) {
1449 dev_err(&led->pdev->dev,
1450 "LED %d flash write failed(%d)\n", led->id, rc);
1451 if (led->flash_cfg->torch_enable)
1452 goto error_torch_set;
1453 else
1454 goto error_flash_set;
1455 }
1456
1457 if (led->flash_cfg->torch_enable) {
1458 if (led->flash_cfg->peripheral_subtype ==
1459 FLASH_SUBTYPE_DUAL) {
1460 if (!led->flash_cfg->no_smbb_support)
1461 rc = qpnp_torch_regulator_operate(led,
1462 false);
1463 else
1464 rc = qpnp_flash_regulator_operate(led,
1465 false);
1466 if (rc) {
1467 dev_err(&led->pdev->dev,
1468 "Torch regulator operate failed(%d)\n",
1469 rc);
1470 return rc;
1471 }
1472 } else if (led->flash_cfg->peripheral_subtype ==
1473 FLASH_SUBTYPE_SINGLE) {
1474 rc = qpnp_flash_regulator_operate(led, false);
1475 if (rc) {
1476 dev_err(&led->pdev->dev,
1477 "Flash regulator operate failed(%d)\n",
1478 rc);
1479 return rc;
1480 }
1481 }
1482 } else {
1483 /*
1484 * Disable module after ramp down complete for stable
1485 * behavior
1486 */
1487 usleep_range(FLASH_RAMP_UP_DELAY_US,
1488 FLASH_RAMP_UP_DELAY_US + 10);
1489
1490 rc = qpnp_led_masked_write(led,
1491 FLASH_ENABLE_CONTROL(led->base),
1492 led->flash_cfg->enable_module &
1493 ~FLASH_ENABLE_MODULE_MASK,
1494 FLASH_DISABLE_ALL);
1495 if (rc) {
1496 dev_err(&led->pdev->dev,
1497 "Enable reg write failed(%d)\n", rc);
1498 if (led->flash_cfg->torch_enable)
1499 goto error_torch_set;
1500 else
1501 goto error_flash_set;
1502 }
1503
1504 rc = qpnp_flash_regulator_operate(led, false);
1505 if (rc) {
1506 dev_err(&led->pdev->dev,
1507 "Flash regulator operate failed(%d)\n",
1508 rc);
1509 return rc;
1510 }
1511 }
1512 }
1513
1514 qpnp_dump_regs(led, flash_debug_regs, ARRAY_SIZE(flash_debug_regs));
1515
1516 return 0;
1517
1518error_reg_write:
1519 if (led->flash_cfg->peripheral_subtype == FLASH_SUBTYPE_SINGLE)
1520 goto error_flash_set;
1521
1522error_torch_set:
1523 if (!led->flash_cfg->no_smbb_support)
1524 error = qpnp_torch_regulator_operate(led, false);
1525 else
1526 error = qpnp_flash_regulator_operate(led, false);
1527 if (error) {
1528 dev_err(&led->pdev->dev,
1529 "Torch regulator operate failed(%d)\n", rc);
1530 return error;
1531 }
1532 return rc;
1533
1534error_flash_set:
1535 error = qpnp_flash_regulator_operate(led, false);
1536 if (error) {
1537 dev_err(&led->pdev->dev,
1538 "Flash regulator operate failed(%d)\n", rc);
1539 return error;
1540 }
1541 return rc;
1542}
1543
1544static int qpnp_kpdbl_set(struct qpnp_led_data *led)
1545{
1546 int rc;
1547 int duty_us, duty_ns, period_us;
1548
1549 if (led->cdev.brightness) {
1550 if (!led->kpdbl_cfg->pwm_cfg->blinking)
1551 led->kpdbl_cfg->pwm_cfg->mode =
1552 led->kpdbl_cfg->pwm_cfg->default_mode;
1553
1554 if (bitmap_empty(kpdbl_leds_in_use, NUM_KPDBL_LEDS)) {
1555 rc = qpnp_led_masked_write(led, KPDBL_ENABLE(led->base),
1556 KPDBL_MODULE_EN_MASK, KPDBL_MODULE_EN);
1557 if (rc) {
1558 dev_err(&led->pdev->dev,
1559 "Enable reg write failed(%d)\n", rc);
1560 return rc;
1561 }
1562 }
1563
1564 /* On some platforms, GPLED1 channel should always be enabled
1565 * for the other GPLEDs 2/3/4 to glow. Before enabling GPLED
1566 * 2/3/4, first check if GPLED1 is already enabled. If GPLED1
1567 * channel is not enabled, then enable the GPLED1 channel but
1568 * with a 0 brightness
1569 */
1570 if (!led->kpdbl_cfg->always_on &&
1571 !test_bit(KPDBL_MASTER_BIT_INDEX, kpdbl_leds_in_use) &&
1572 kpdbl_master) {
1573 rc = pwm_config_us(kpdbl_master, 0,
1574 kpdbl_master_period_us);
1575 if (rc < 0) {
1576 dev_err(&led->pdev->dev,
1577 "pwm config failed\n");
1578 return rc;
1579 }
1580
1581 rc = pwm_enable(kpdbl_master);
1582 if (rc < 0) {
1583 dev_err(&led->pdev->dev,
1584 "pwm enable failed\n");
1585 return rc;
1586 }
1587 set_bit(KPDBL_MASTER_BIT_INDEX,
1588 kpdbl_leds_in_use);
1589 }
1590
1591 if (led->kpdbl_cfg->pwm_cfg->mode == PWM_MODE) {
Fenglin Wu9a5329e2017-08-14 12:50:10 +08001592 rc = pwm_change_mode(led->kpdbl_cfg->pwm_cfg->pwm_dev,
1593 PM_PWM_MODE_PWM);
1594 if (rc < 0) {
1595 dev_err(&led->pdev->dev,
1596 "Failed to set PWM mode, rc = %d\n",
1597 rc);
1598 return rc;
1599 }
David Collins8885f792017-01-26 14:36:34 -08001600 period_us = led->kpdbl_cfg->pwm_cfg->pwm_period_us;
1601 if (period_us > INT_MAX / NSEC_PER_USEC) {
1602 duty_us = (period_us * led->cdev.brightness) /
1603 KPDBL_MAX_LEVEL;
1604 rc = pwm_config_us(
1605 led->kpdbl_cfg->pwm_cfg->pwm_dev,
1606 duty_us,
1607 period_us);
1608 } else {
1609 duty_ns = ((period_us * NSEC_PER_USEC) /
1610 KPDBL_MAX_LEVEL) * led->cdev.brightness;
1611 rc = pwm_config(
1612 led->kpdbl_cfg->pwm_cfg->pwm_dev,
1613 duty_ns,
1614 period_us * NSEC_PER_USEC);
1615 }
1616 if (rc < 0) {
1617 dev_err(&led->pdev->dev,
1618 "pwm config failed\n");
1619 return rc;
1620 }
1621 }
1622
1623 rc = pwm_enable(led->kpdbl_cfg->pwm_cfg->pwm_dev);
1624 if (rc < 0) {
1625 dev_err(&led->pdev->dev, "pwm enable failed\n");
1626 return rc;
1627 }
Fenglin Wu325e6de2017-03-16 13:40:26 +08001628 led->kpdbl_cfg->pwm_cfg->pwm_enabled = 1;
David Collins8885f792017-01-26 14:36:34 -08001629 set_bit(led->kpdbl_cfg->row_id, kpdbl_leds_in_use);
1630
1631 /* is_kpdbl_master_turn_on will be set to true when GPLED1
1632 * channel is enabled and has a valid brightness value
1633 */
1634 if (led->kpdbl_cfg->always_on)
1635 is_kpdbl_master_turn_on = true;
1636
1637 } else {
1638 led->kpdbl_cfg->pwm_cfg->mode =
1639 led->kpdbl_cfg->pwm_cfg->default_mode;
1640
1641 /* Before disabling GPLED1, check if any other GPLED 2/3/4 is
1642 * on. If any of the other GPLED 2/3/4 is on, then have the
1643 * GPLED1 channel enabled with 0 brightness.
1644 */
1645 if (led->kpdbl_cfg->always_on) {
1646 if (bitmap_weight(kpdbl_leds_in_use,
1647 NUM_KPDBL_LEDS) > 1) {
1648 rc = pwm_config_us(
1649 led->kpdbl_cfg->pwm_cfg->pwm_dev, 0,
1650 led->kpdbl_cfg->pwm_cfg->pwm_period_us);
1651 if (rc < 0) {
1652 dev_err(&led->pdev->dev,
1653 "pwm config failed\n");
1654 return rc;
1655 }
1656
1657 rc = pwm_enable(led->kpdbl_cfg->pwm_cfg->
1658 pwm_dev);
1659 if (rc < 0) {
1660 dev_err(&led->pdev->dev,
1661 "pwm enable failed\n");
1662 return rc;
1663 }
Fenglin Wu325e6de2017-03-16 13:40:26 +08001664 led->kpdbl_cfg->pwm_cfg->pwm_enabled = 1;
David Collins8885f792017-01-26 14:36:34 -08001665 } else {
1666 if (kpdbl_master) {
1667 pwm_disable(kpdbl_master);
1668 clear_bit(KPDBL_MASTER_BIT_INDEX,
1669 kpdbl_leds_in_use);
1670 rc = qpnp_led_masked_write(
1671 led, KPDBL_ENABLE(led->base),
1672 KPDBL_MODULE_EN_MASK,
1673 KPDBL_MODULE_DIS);
1674 if (rc) {
1675 dev_err(&led->pdev->dev, "Failed to write led enable reg\n");
1676 return rc;
1677 }
1678 }
1679 }
1680 is_kpdbl_master_turn_on = false;
1681 } else {
1682 pwm_disable(led->kpdbl_cfg->pwm_cfg->pwm_dev);
Fenglin Wu325e6de2017-03-16 13:40:26 +08001683 led->kpdbl_cfg->pwm_cfg->pwm_enabled = 0;
David Collins8885f792017-01-26 14:36:34 -08001684 clear_bit(led->kpdbl_cfg->row_id, kpdbl_leds_in_use);
1685 if (bitmap_weight(kpdbl_leds_in_use,
1686 NUM_KPDBL_LEDS) == 1 && kpdbl_master &&
1687 !is_kpdbl_master_turn_on) {
1688 pwm_disable(kpdbl_master);
1689 clear_bit(KPDBL_MASTER_BIT_INDEX,
1690 kpdbl_leds_in_use);
1691 rc = qpnp_led_masked_write(
1692 led, KPDBL_ENABLE(led->base),
1693 KPDBL_MODULE_EN_MASK, KPDBL_MODULE_DIS);
1694 if (rc) {
1695 dev_err(&led->pdev->dev,
1696 "Failed to write led enable reg\n");
1697 return rc;
1698 }
1699 is_kpdbl_master_turn_on = false;
1700 }
1701 }
1702 }
1703
1704 led->kpdbl_cfg->pwm_cfg->blinking = false;
1705
1706 qpnp_dump_regs(led, kpdbl_debug_regs, ARRAY_SIZE(kpdbl_debug_regs));
1707
1708 return 0;
1709}
1710
1711static int qpnp_rgb_set(struct qpnp_led_data *led)
1712{
1713 int rc;
1714 int duty_us, duty_ns, period_us;
1715
1716 if (led->cdev.brightness) {
1717 if (!led->rgb_cfg->pwm_cfg->blinking)
1718 led->rgb_cfg->pwm_cfg->mode =
1719 led->rgb_cfg->pwm_cfg->default_mode;
1720 if (led->rgb_cfg->pwm_cfg->mode == PWM_MODE) {
Fenglin Wu9a5329e2017-08-14 12:50:10 +08001721 rc = pwm_change_mode(led->rgb_cfg->pwm_cfg->pwm_dev,
1722 PM_PWM_MODE_PWM);
1723 if (rc < 0) {
1724 dev_err(&led->pdev->dev,
1725 "Failed to set PWM mode, rc = %d\n",
1726 rc);
1727 return rc;
1728 }
Fenglin Wud4ebece2017-12-22 10:33:39 +08001729 }
1730 period_us = led->rgb_cfg->pwm_cfg->pwm_period_us;
1731 if (period_us > INT_MAX / NSEC_PER_USEC) {
1732 duty_us = (period_us * led->cdev.brightness) /
1733 LED_FULL;
1734 rc = pwm_config_us(
1735 led->rgb_cfg->pwm_cfg->pwm_dev,
1736 duty_us,
1737 period_us);
1738 } else {
1739 duty_ns = ((period_us * NSEC_PER_USEC) /
1740 LED_FULL) * led->cdev.brightness;
1741 rc = pwm_config(
1742 led->rgb_cfg->pwm_cfg->pwm_dev,
1743 duty_ns,
1744 period_us * NSEC_PER_USEC);
1745 }
1746 if (rc < 0) {
1747 dev_err(&led->pdev->dev,
1748 "pwm config failed\n");
1749 return rc;
David Collins8885f792017-01-26 14:36:34 -08001750 }
1751 rc = qpnp_led_masked_write(led,
1752 RGB_LED_EN_CTL(led->base),
1753 led->rgb_cfg->enable, led->rgb_cfg->enable);
1754 if (rc) {
1755 dev_err(&led->pdev->dev,
1756 "Failed to write led enable reg\n");
1757 return rc;
1758 }
Fenglin Wu325e6de2017-03-16 13:40:26 +08001759 if (!led->rgb_cfg->pwm_cfg->pwm_enabled) {
1760 pwm_enable(led->rgb_cfg->pwm_cfg->pwm_dev);
1761 led->rgb_cfg->pwm_cfg->pwm_enabled = 1;
1762 }
1763 } else {
1764 led->rgb_cfg->pwm_cfg->mode =
1765 led->rgb_cfg->pwm_cfg->default_mode;
David Collins8885f792017-01-26 14:36:34 -08001766 if (led->rgb_cfg->pwm_cfg->pwm_enabled) {
1767 pwm_disable(led->rgb_cfg->pwm_cfg->pwm_dev);
1768 led->rgb_cfg->pwm_cfg->pwm_enabled = 0;
1769 }
David Collins8885f792017-01-26 14:36:34 -08001770 rc = qpnp_led_masked_write(led,
1771 RGB_LED_EN_CTL(led->base),
1772 led->rgb_cfg->enable, RGB_LED_DISABLE);
1773 if (rc) {
1774 dev_err(&led->pdev->dev,
1775 "Failed to write led enable reg\n");
1776 return rc;
1777 }
1778 }
1779
1780 led->rgb_cfg->pwm_cfg->blinking = false;
1781 qpnp_dump_regs(led, rgb_pwm_debug_regs, ARRAY_SIZE(rgb_pwm_debug_regs));
1782
1783 return 0;
1784}
1785
1786static void qpnp_led_set(struct led_classdev *led_cdev,
1787 enum led_brightness value)
1788{
1789 struct qpnp_led_data *led;
1790
1791 led = container_of(led_cdev, struct qpnp_led_data, cdev);
1792 if (value < LED_OFF) {
1793 dev_err(&led->pdev->dev, "Invalid brightness value\n");
1794 return;
1795 }
1796
1797 if (value > led->cdev.max_brightness)
1798 value = led->cdev.max_brightness;
1799
1800 led->cdev.brightness = value;
1801 if (led->in_order_command_processing)
1802 queue_work(led->workqueue, &led->work);
1803 else
1804 schedule_work(&led->work);
1805}
1806
1807static void __qpnp_led_work(struct qpnp_led_data *led,
1808 enum led_brightness value)
1809{
1810 int rc;
1811
1812 if (led->id == QPNP_ID_FLASH1_LED0 || led->id == QPNP_ID_FLASH1_LED1)
1813 mutex_lock(&flash_lock);
1814 else
1815 mutex_lock(&led->lock);
1816
1817 switch (led->id) {
1818 case QPNP_ID_WLED:
1819 rc = qpnp_wled_set(led);
1820 if (rc < 0)
1821 dev_err(&led->pdev->dev,
1822 "WLED set brightness failed (%d)\n", rc);
1823 break;
1824 case QPNP_ID_FLASH1_LED0:
1825 case QPNP_ID_FLASH1_LED1:
1826 rc = qpnp_flash_set(led);
1827 if (rc < 0)
1828 dev_err(&led->pdev->dev,
1829 "FLASH set brightness failed (%d)\n", rc);
1830 break;
1831 case QPNP_ID_RGB_RED:
1832 case QPNP_ID_RGB_GREEN:
1833 case QPNP_ID_RGB_BLUE:
1834 rc = qpnp_rgb_set(led);
1835 if (rc < 0)
1836 dev_err(&led->pdev->dev,
1837 "RGB set brightness failed (%d)\n", rc);
1838 break;
1839 case QPNP_ID_LED_MPP:
1840 rc = qpnp_mpp_set(led);
1841 if (rc < 0)
1842 dev_err(&led->pdev->dev,
1843 "MPP set brightness failed (%d)\n", rc);
1844 break;
1845 case QPNP_ID_LED_GPIO:
1846 rc = qpnp_gpio_set(led);
1847 if (rc < 0)
1848 dev_err(&led->pdev->dev,
1849 "GPIO set brightness failed (%d)\n",
1850 rc);
1851 break;
1852 case QPNP_ID_KPDBL:
1853 rc = qpnp_kpdbl_set(led);
1854 if (rc < 0)
1855 dev_err(&led->pdev->dev,
1856 "KPDBL set brightness failed (%d)\n", rc);
1857 break;
1858 default:
1859 dev_err(&led->pdev->dev, "Invalid LED(%d)\n", led->id);
1860 break;
1861 }
1862 if (led->id == QPNP_ID_FLASH1_LED0 || led->id == QPNP_ID_FLASH1_LED1)
1863 mutex_unlock(&flash_lock);
1864 else
1865 mutex_unlock(&led->lock);
1866
1867}
1868
1869static void qpnp_led_work(struct work_struct *work)
1870{
1871 struct qpnp_led_data *led = container_of(work,
1872 struct qpnp_led_data, work);
1873
1874 __qpnp_led_work(led, led->cdev.brightness);
1875}
1876
1877static int qpnp_led_set_max_brightness(struct qpnp_led_data *led)
1878{
1879 switch (led->id) {
1880 case QPNP_ID_WLED:
1881 led->cdev.max_brightness = WLED_MAX_LEVEL;
1882 break;
1883 case QPNP_ID_FLASH1_LED0:
1884 case QPNP_ID_FLASH1_LED1:
1885 led->cdev.max_brightness = led->max_current;
1886 break;
1887 case QPNP_ID_RGB_RED:
1888 case QPNP_ID_RGB_GREEN:
1889 case QPNP_ID_RGB_BLUE:
1890 led->cdev.max_brightness = RGB_MAX_LEVEL;
1891 break;
1892 case QPNP_ID_LED_MPP:
1893 if (led->mpp_cfg->pwm_mode == MANUAL_MODE)
1894 led->cdev.max_brightness = led->max_current;
1895 else
1896 led->cdev.max_brightness = MPP_MAX_LEVEL;
1897 break;
1898 case QPNP_ID_LED_GPIO:
1899 led->cdev.max_brightness = led->max_current;
1900 break;
1901 case QPNP_ID_KPDBL:
1902 led->cdev.max_brightness = KPDBL_MAX_LEVEL;
1903 break;
1904 default:
1905 dev_err(&led->pdev->dev, "Invalid LED(%d)\n", led->id);
1906 return -EINVAL;
1907 }
1908
1909 return 0;
1910}
1911
1912static enum led_brightness qpnp_led_get(struct led_classdev *led_cdev)
1913{
1914 struct qpnp_led_data *led;
1915
1916 led = container_of(led_cdev, struct qpnp_led_data, cdev);
1917
1918 return led->cdev.brightness;
1919}
1920
1921static void qpnp_led_turn_off_delayed(struct work_struct *work)
1922{
1923 struct delayed_work *dwork = to_delayed_work(work);
1924 struct qpnp_led_data *led
1925 = container_of(dwork, struct qpnp_led_data, dwork);
1926
1927 led->cdev.brightness = LED_OFF;
1928 qpnp_led_set(&led->cdev, led->cdev.brightness);
1929}
1930
1931static void qpnp_led_turn_off(struct qpnp_led_data *led)
1932{
1933 INIT_DELAYED_WORK(&led->dwork, qpnp_led_turn_off_delayed);
1934 schedule_delayed_work(&led->dwork,
1935 msecs_to_jiffies(led->turn_off_delay_ms));
1936}
1937
1938static int qpnp_wled_init(struct qpnp_led_data *led)
1939{
1940 int rc, i;
1941 u8 num_wled_strings, val = 0;
1942
1943 num_wled_strings = led->wled_cfg->num_strings;
1944
1945 /* verify ranges */
1946 if (led->wled_cfg->ovp_val > WLED_OVP_27V) {
1947 dev_err(&led->pdev->dev, "Invalid ovp value\n");
1948 return -EINVAL;
1949 }
1950
1951 if (led->wled_cfg->boost_curr_lim > WLED_CURR_LIMIT_1680mA) {
1952 dev_err(&led->pdev->dev, "Invalid boost current limit\n");
1953 return -EINVAL;
1954 }
1955
1956 if (led->wled_cfg->cp_select > WLED_CP_SELECT_MAX) {
1957 dev_err(&led->pdev->dev, "Invalid pole capacitance\n");
1958 return -EINVAL;
1959 }
1960
1961 if (led->max_current > WLED_MAX_CURR) {
1962 dev_err(&led->pdev->dev, "Invalid max current\n");
1963 return -EINVAL;
1964 }
1965
1966 if ((led->wled_cfg->ctrl_delay_us % WLED_CTL_DLY_STEP) ||
1967 (led->wled_cfg->ctrl_delay_us > WLED_CTL_DLY_MAX)) {
1968 dev_err(&led->pdev->dev, "Invalid control delay\n");
1969 return -EINVAL;
1970 }
1971
1972 /* program over voltage protection threshold */
1973 rc = qpnp_led_masked_write(led, WLED_OVP_CFG_REG(led->base),
1974 WLED_OVP_VAL_MASK,
1975 (led->wled_cfg->ovp_val << WLED_OVP_VAL_BIT_SHFT));
1976 if (rc) {
1977 dev_err(&led->pdev->dev,
1978 "WLED OVP reg write failed(%d)\n", rc);
1979 return rc;
1980 }
1981
1982 /* program current boost limit */
1983 rc = qpnp_led_masked_write(led, WLED_BOOST_LIMIT_REG(led->base),
1984 WLED_BOOST_LIMIT_MASK, led->wled_cfg->boost_curr_lim);
1985 if (rc) {
1986 dev_err(&led->pdev->dev,
1987 "WLED boost limit reg write failed(%d)\n", rc);
1988 return rc;
1989 }
1990
1991 /* program output feedback */
1992 rc = qpnp_led_masked_write(led, WLED_FDBCK_CTRL_REG(led->base),
1993 WLED_OP_FDBCK_MASK,
1994 (led->wled_cfg->op_fdbck << WLED_OP_FDBCK_BIT_SHFT));
1995 if (rc) {
1996 dev_err(&led->pdev->dev,
1997 "WLED fdbck ctrl reg write failed(%d)\n", rc);
1998 return rc;
1999 }
2000
2001 /* program switch frequency */
2002 rc = qpnp_led_masked_write(led,
2003 WLED_SWITCHING_FREQ_REG(led->base),
2004 WLED_SWITCH_FREQ_MASK, led->wled_cfg->switch_freq);
2005 if (rc) {
2006 dev_err(&led->pdev->dev,
2007 "WLED switch freq reg write failed(%d)\n", rc);
2008 return rc;
2009 }
2010
2011 /* program current sink */
2012 if (led->wled_cfg->cs_out_en) {
2013 for (i = 0; i < led->wled_cfg->num_strings; i++)
2014 val |= 1 << i;
2015 rc = qpnp_led_masked_write(led, WLED_CURR_SINK_REG(led->base),
2016 WLED_CURR_SINK_MASK, (val << WLED_CURR_SINK_SHFT));
2017 if (rc) {
2018 dev_err(&led->pdev->dev,
2019 "WLED curr sink reg write failed(%d)\n", rc);
2020 return rc;
2021 }
2022 }
2023
2024 /* program high pole capacitance */
2025 rc = qpnp_led_masked_write(led, WLED_HIGH_POLE_CAP_REG(led->base),
2026 WLED_CP_SELECT_MASK, led->wled_cfg->cp_select);
2027 if (rc) {
2028 dev_err(&led->pdev->dev,
2029 "WLED pole cap reg write failed(%d)\n", rc);
2030 return rc;
2031 }
2032
2033 /* program modulator, current mod src and cabc */
2034 for (i = 0; i < num_wled_strings; i++) {
2035 rc = qpnp_led_masked_write(led, WLED_MOD_EN_REG(led->base, i),
2036 WLED_NO_MASK, WLED_EN_MASK);
2037 if (rc) {
2038 dev_err(&led->pdev->dev,
2039 "WLED mod enable reg write failed(%d)\n", rc);
2040 return rc;
2041 }
2042
2043 if (led->wled_cfg->dig_mod_gen_en) {
2044 rc = qpnp_led_masked_write(led,
2045 WLED_MOD_SRC_SEL_REG(led->base, i),
2046 WLED_NO_MASK, WLED_USE_EXT_GEN_MOD_SRC);
2047 if (rc) {
2048 dev_err(&led->pdev->dev,
2049 "WLED dig mod en reg write failed(%d)\n", rc);
2050 }
2051 }
2052
2053 rc = qpnp_led_masked_write(led,
2054 WLED_FULL_SCALE_REG(led->base, i), WLED_MAX_CURR_MASK,
2055 (u8)led->max_current);
2056 if (rc) {
2057 dev_err(&led->pdev->dev,
2058 "WLED max current reg write failed(%d)\n", rc);
2059 return rc;
2060 }
2061
2062 }
2063
2064 /* Reset WLED enable register */
2065 rc = qpnp_led_masked_write(led, WLED_MOD_CTRL_REG(led->base),
2066 WLED_8_BIT_MASK, WLED_BOOST_OFF);
2067 if (rc) {
2068 dev_err(&led->pdev->dev,
2069 "WLED write ctrl reg failed(%d)\n", rc);
2070 return rc;
2071 }
2072
2073 /* dump wled registers */
2074 qpnp_dump_regs(led, wled_debug_regs, ARRAY_SIZE(wled_debug_regs));
2075
2076 return 0;
2077}
2078
2079static ssize_t led_mode_store(struct device *dev,
2080 struct device_attribute *attr,
2081 const char *buf, size_t count)
2082{
2083 struct qpnp_led_data *led;
2084 unsigned long state;
2085 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2086 ssize_t ret = -EINVAL;
2087
2088 ret = kstrtoul(buf, 10, &state);
2089 if (ret)
2090 return ret;
2091
2092 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2093
2094 /* '1' to enable torch mode; '0' to switch to flash mode */
2095 if (state == 1)
2096 led->flash_cfg->torch_enable = true;
2097 else
2098 led->flash_cfg->torch_enable = false;
2099
2100 return count;
2101}
2102
2103static ssize_t led_strobe_type_store(struct device *dev,
2104 struct device_attribute *attr,
2105 const char *buf, size_t count)
2106{
2107 struct qpnp_led_data *led;
2108 unsigned long state;
2109 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2110 ssize_t ret = -EINVAL;
2111
2112 ret = kstrtoul(buf, 10, &state);
2113 if (ret)
2114 return ret;
2115
2116 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2117
2118 /* '0' for sw strobe; '1' for hw strobe */
2119 if (state == 1)
2120 led->flash_cfg->strobe_type = 1;
2121 else
2122 led->flash_cfg->strobe_type = 0;
2123
2124 return count;
2125}
2126
2127static int qpnp_pwm_init(struct pwm_config_data *pwm_cfg,
2128 struct platform_device *pdev,
2129 const char *name)
2130{
2131 int rc, start_idx, idx_len, lut_max_size;
2132
2133 if (pwm_cfg->pwm_dev) {
2134 if (pwm_cfg->mode == LPG_MODE) {
2135 start_idx =
2136 pwm_cfg->duty_cycles->start_idx;
2137 idx_len =
2138 pwm_cfg->duty_cycles->num_duty_pcts;
2139
2140 if (strnstr(name, "kpdbl", sizeof("kpdbl")))
2141 lut_max_size = PWM_GPLED_LUT_MAX_SIZE;
2142 else
2143 lut_max_size = PWM_LUT_MAX_SIZE;
2144
2145 if (idx_len >= lut_max_size && start_idx) {
2146 dev_err(&pdev->dev,
2147 "Wrong LUT size or index\n");
2148 return -EINVAL;
2149 }
2150
2151 if ((start_idx + idx_len) > lut_max_size) {
2152 dev_err(&pdev->dev, "Exceed LUT limit\n");
2153 return -EINVAL;
2154 }
2155 rc = pwm_lut_config(pwm_cfg->pwm_dev,
2156 pwm_cfg->pwm_period_us,
2157 pwm_cfg->duty_cycles->duty_pcts,
2158 pwm_cfg->lut_params);
2159 if (rc < 0) {
2160 dev_err(&pdev->dev, "Failed to configure pwm LUT\n");
2161 return rc;
2162 }
Fenglin Wu9a5329e2017-08-14 12:50:10 +08002163 rc = pwm_change_mode(pwm_cfg->pwm_dev, PM_PWM_MODE_LPG);
2164 if (rc < 0) {
2165 dev_err(&pdev->dev, "Failed to set LPG mode\n");
2166 return rc;
2167 }
David Collins8885f792017-01-26 14:36:34 -08002168 }
2169 } else {
2170 dev_err(&pdev->dev, "Invalid PWM device\n");
2171 return -EINVAL;
2172 }
2173
2174 return 0;
2175}
2176
2177static ssize_t pwm_us_store(struct device *dev,
2178 struct device_attribute *attr,
2179 const char *buf, size_t count)
2180{
2181 struct qpnp_led_data *led;
2182 u32 pwm_us;
2183 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2184 ssize_t ret;
2185 u32 previous_pwm_us;
2186 struct pwm_config_data *pwm_cfg;
2187
2188 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2189
2190 ret = kstrtou32(buf, 10, &pwm_us);
2191 if (ret)
2192 return ret;
2193
2194 switch (led->id) {
2195 case QPNP_ID_LED_MPP:
2196 pwm_cfg = led->mpp_cfg->pwm_cfg;
2197 break;
2198 case QPNP_ID_RGB_RED:
2199 case QPNP_ID_RGB_GREEN:
2200 case QPNP_ID_RGB_BLUE:
2201 pwm_cfg = led->rgb_cfg->pwm_cfg;
2202 break;
2203 case QPNP_ID_KPDBL:
2204 pwm_cfg = led->kpdbl_cfg->pwm_cfg;
2205 break;
2206 default:
2207 dev_err(&led->pdev->dev, "Invalid LED id type for pwm_us\n");
2208 return -EINVAL;
2209 }
2210
2211 if (pwm_cfg->mode == LPG_MODE)
2212 pwm_cfg->blinking = true;
2213
2214 previous_pwm_us = pwm_cfg->pwm_period_us;
2215
2216 pwm_cfg->pwm_period_us = pwm_us;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002217 if (pwm_cfg->pwm_enabled) {
2218 pwm_disable(pwm_cfg->pwm_dev);
2219 pwm_cfg->pwm_enabled = 0;
2220 }
David Collins8885f792017-01-26 14:36:34 -08002221 ret = qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2222 if (ret) {
2223 pwm_cfg->pwm_period_us = previous_pwm_us;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002224 if (pwm_cfg->pwm_enabled) {
2225 pwm_disable(pwm_cfg->pwm_dev);
2226 pwm_cfg->pwm_enabled = 0;
2227 }
David Collins8885f792017-01-26 14:36:34 -08002228 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2229 qpnp_led_set(&led->cdev, led->cdev.brightness);
2230 dev_err(&led->pdev->dev,
2231 "Failed to initialize pwm with new pwm_us value\n");
2232 return ret;
2233 }
2234 qpnp_led_set(&led->cdev, led->cdev.brightness);
2235 return count;
2236}
2237
2238static ssize_t pause_lo_store(struct device *dev,
2239 struct device_attribute *attr,
2240 const char *buf, size_t count)
2241{
2242 struct qpnp_led_data *led;
2243 u32 pause_lo;
2244 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2245 ssize_t ret;
2246 u32 previous_pause_lo;
2247 struct pwm_config_data *pwm_cfg;
2248
2249 ret = kstrtou32(buf, 10, &pause_lo);
2250 if (ret)
2251 return ret;
2252 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2253
2254 switch (led->id) {
2255 case QPNP_ID_LED_MPP:
2256 pwm_cfg = led->mpp_cfg->pwm_cfg;
2257 break;
2258 case QPNP_ID_RGB_RED:
2259 case QPNP_ID_RGB_GREEN:
2260 case QPNP_ID_RGB_BLUE:
2261 pwm_cfg = led->rgb_cfg->pwm_cfg;
2262 break;
2263 case QPNP_ID_KPDBL:
2264 pwm_cfg = led->kpdbl_cfg->pwm_cfg;
2265 break;
2266 default:
2267 dev_err(&led->pdev->dev,
2268 "Invalid LED id type for pause lo\n");
2269 return -EINVAL;
2270 }
2271
2272 if (pwm_cfg->mode == LPG_MODE)
2273 pwm_cfg->blinking = true;
2274
2275 previous_pause_lo = pwm_cfg->lut_params.lut_pause_lo;
2276
Fenglin Wu325e6de2017-03-16 13:40:26 +08002277 if (pwm_cfg->pwm_enabled) {
2278 pwm_disable(pwm_cfg->pwm_dev);
2279 pwm_cfg->pwm_enabled = 0;
2280 }
David Collins8885f792017-01-26 14:36:34 -08002281 pwm_cfg->lut_params.lut_pause_lo = pause_lo;
2282 ret = qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2283 if (ret) {
2284 pwm_cfg->lut_params.lut_pause_lo = previous_pause_lo;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002285 if (pwm_cfg->pwm_enabled) {
2286 pwm_disable(pwm_cfg->pwm_dev);
2287 pwm_cfg->pwm_enabled = 0;
2288 }
David Collins8885f792017-01-26 14:36:34 -08002289 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2290 qpnp_led_set(&led->cdev, led->cdev.brightness);
2291 dev_err(&led->pdev->dev,
2292 "Failed to initialize pwm with new pause lo value\n");
2293 return ret;
2294 }
2295 qpnp_led_set(&led->cdev, led->cdev.brightness);
2296 return count;
2297}
2298
2299static ssize_t pause_hi_store(struct device *dev,
2300 struct device_attribute *attr,
2301 const char *buf, size_t count)
2302{
2303 struct qpnp_led_data *led;
2304 u32 pause_hi;
2305 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2306 ssize_t ret;
2307 u32 previous_pause_hi;
2308 struct pwm_config_data *pwm_cfg;
2309
2310 ret = kstrtou32(buf, 10, &pause_hi);
2311 if (ret)
2312 return ret;
2313 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2314
2315 switch (led->id) {
2316 case QPNP_ID_LED_MPP:
2317 pwm_cfg = led->mpp_cfg->pwm_cfg;
2318 break;
2319 case QPNP_ID_RGB_RED:
2320 case QPNP_ID_RGB_GREEN:
2321 case QPNP_ID_RGB_BLUE:
2322 pwm_cfg = led->rgb_cfg->pwm_cfg;
2323 break;
2324 case QPNP_ID_KPDBL:
2325 pwm_cfg = led->kpdbl_cfg->pwm_cfg;
2326 break;
2327 default:
2328 dev_err(&led->pdev->dev,
2329 "Invalid LED id type for pause hi\n");
2330 return -EINVAL;
2331 }
2332
2333 if (pwm_cfg->mode == LPG_MODE)
2334 pwm_cfg->blinking = true;
2335
2336 previous_pause_hi = pwm_cfg->lut_params.lut_pause_hi;
2337
Fenglin Wu325e6de2017-03-16 13:40:26 +08002338 if (pwm_cfg->pwm_enabled) {
2339 pwm_disable(pwm_cfg->pwm_dev);
2340 pwm_cfg->pwm_enabled = 0;
2341 }
David Collins8885f792017-01-26 14:36:34 -08002342 pwm_cfg->lut_params.lut_pause_hi = pause_hi;
2343 ret = qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2344 if (ret) {
2345 pwm_cfg->lut_params.lut_pause_hi = previous_pause_hi;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002346 if (pwm_cfg->pwm_enabled) {
2347 pwm_disable(pwm_cfg->pwm_dev);
2348 pwm_cfg->pwm_enabled = 0;
2349 }
David Collins8885f792017-01-26 14:36:34 -08002350 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2351 qpnp_led_set(&led->cdev, led->cdev.brightness);
2352 dev_err(&led->pdev->dev,
2353 "Failed to initialize pwm with new pause hi value\n");
2354 return ret;
2355 }
2356 qpnp_led_set(&led->cdev, led->cdev.brightness);
2357 return count;
2358}
2359
2360static ssize_t start_idx_store(struct device *dev,
2361 struct device_attribute *attr,
2362 const char *buf, size_t count)
2363{
2364 struct qpnp_led_data *led;
2365 u32 start_idx;
2366 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2367 ssize_t ret;
2368 u32 previous_start_idx;
2369 struct pwm_config_data *pwm_cfg;
2370
2371 ret = kstrtou32(buf, 10, &start_idx);
2372 if (ret)
2373 return ret;
2374 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2375
2376 switch (led->id) {
2377 case QPNP_ID_LED_MPP:
2378 pwm_cfg = led->mpp_cfg->pwm_cfg;
2379 break;
2380 case QPNP_ID_RGB_RED:
2381 case QPNP_ID_RGB_GREEN:
2382 case QPNP_ID_RGB_BLUE:
2383 pwm_cfg = led->rgb_cfg->pwm_cfg;
2384 break;
2385 case QPNP_ID_KPDBL:
2386 pwm_cfg = led->kpdbl_cfg->pwm_cfg;
2387 break;
2388 default:
2389 dev_err(&led->pdev->dev,
2390 "Invalid LED id type for start idx\n");
2391 return -EINVAL;
2392 }
2393
2394 if (pwm_cfg->mode == LPG_MODE)
2395 pwm_cfg->blinking = true;
2396
2397 previous_start_idx = pwm_cfg->duty_cycles->start_idx;
2398 pwm_cfg->duty_cycles->start_idx = start_idx;
2399 pwm_cfg->lut_params.start_idx = pwm_cfg->duty_cycles->start_idx;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002400 if (pwm_cfg->pwm_enabled) {
2401 pwm_disable(pwm_cfg->pwm_dev);
2402 pwm_cfg->pwm_enabled = 0;
2403 }
David Collins8885f792017-01-26 14:36:34 -08002404 ret = qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2405 if (ret) {
2406 pwm_cfg->duty_cycles->start_idx = previous_start_idx;
2407 pwm_cfg->lut_params.start_idx = pwm_cfg->duty_cycles->start_idx;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002408 if (pwm_cfg->pwm_enabled) {
2409 pwm_disable(pwm_cfg->pwm_dev);
2410 pwm_cfg->pwm_enabled = 0;
2411 }
David Collins8885f792017-01-26 14:36:34 -08002412 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2413 qpnp_led_set(&led->cdev, led->cdev.brightness);
2414 dev_err(&led->pdev->dev,
2415 "Failed to initialize pwm with new start idx value\n");
2416 return ret;
2417 }
2418 qpnp_led_set(&led->cdev, led->cdev.brightness);
2419 return count;
2420}
2421
2422static ssize_t ramp_step_ms_store(struct device *dev,
2423 struct device_attribute *attr,
2424 const char *buf, size_t count)
2425{
2426 struct qpnp_led_data *led;
2427 u32 ramp_step_ms;
2428 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2429 ssize_t ret;
2430 u32 previous_ramp_step_ms;
2431 struct pwm_config_data *pwm_cfg;
2432
2433 ret = kstrtou32(buf, 10, &ramp_step_ms);
2434 if (ret)
2435 return ret;
2436 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2437
2438 switch (led->id) {
2439 case QPNP_ID_LED_MPP:
2440 pwm_cfg = led->mpp_cfg->pwm_cfg;
2441 break;
2442 case QPNP_ID_RGB_RED:
2443 case QPNP_ID_RGB_GREEN:
2444 case QPNP_ID_RGB_BLUE:
2445 pwm_cfg = led->rgb_cfg->pwm_cfg;
2446 break;
2447 case QPNP_ID_KPDBL:
2448 pwm_cfg = led->kpdbl_cfg->pwm_cfg;
2449 break;
2450 default:
2451 dev_err(&led->pdev->dev,
2452 "Invalid LED id type for ramp step\n");
2453 return -EINVAL;
2454 }
2455
2456 if (pwm_cfg->mode == LPG_MODE)
2457 pwm_cfg->blinking = true;
2458
2459 previous_ramp_step_ms = pwm_cfg->lut_params.ramp_step_ms;
2460
Fenglin Wu325e6de2017-03-16 13:40:26 +08002461 if (pwm_cfg->pwm_enabled) {
2462 pwm_disable(pwm_cfg->pwm_dev);
2463 pwm_cfg->pwm_enabled = 0;
2464 }
David Collins8885f792017-01-26 14:36:34 -08002465 pwm_cfg->lut_params.ramp_step_ms = ramp_step_ms;
2466 ret = qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2467 if (ret) {
2468 pwm_cfg->lut_params.ramp_step_ms = previous_ramp_step_ms;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002469 if (pwm_cfg->pwm_enabled) {
2470 pwm_disable(pwm_cfg->pwm_dev);
2471 pwm_cfg->pwm_enabled = 0;
2472 }
David Collins8885f792017-01-26 14:36:34 -08002473 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2474 qpnp_led_set(&led->cdev, led->cdev.brightness);
2475 dev_err(&led->pdev->dev,
2476 "Failed to initialize pwm with new ramp step value\n");
2477 return ret;
2478 }
2479 qpnp_led_set(&led->cdev, led->cdev.brightness);
2480 return count;
2481}
2482
2483static ssize_t lut_flags_store(struct device *dev,
2484 struct device_attribute *attr,
2485 const char *buf, size_t count)
2486{
2487 struct qpnp_led_data *led;
2488 u32 lut_flags;
2489 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2490 ssize_t ret;
2491 u32 previous_lut_flags;
2492 struct pwm_config_data *pwm_cfg;
2493
2494 ret = kstrtou32(buf, 10, &lut_flags);
2495 if (ret)
2496 return ret;
2497 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2498
2499 switch (led->id) {
2500 case QPNP_ID_LED_MPP:
2501 pwm_cfg = led->mpp_cfg->pwm_cfg;
2502 break;
2503 case QPNP_ID_RGB_RED:
2504 case QPNP_ID_RGB_GREEN:
2505 case QPNP_ID_RGB_BLUE:
2506 pwm_cfg = led->rgb_cfg->pwm_cfg;
2507 break;
2508 case QPNP_ID_KPDBL:
2509 pwm_cfg = led->kpdbl_cfg->pwm_cfg;
2510 break;
2511 default:
2512 dev_err(&led->pdev->dev,
2513 "Invalid LED id type for lut flags\n");
2514 return -EINVAL;
2515 }
2516
2517 if (pwm_cfg->mode == LPG_MODE)
2518 pwm_cfg->blinking = true;
2519
2520 previous_lut_flags = pwm_cfg->lut_params.flags;
2521
Fenglin Wu325e6de2017-03-16 13:40:26 +08002522 if (pwm_cfg->pwm_enabled) {
2523 pwm_disable(pwm_cfg->pwm_dev);
2524 pwm_cfg->pwm_enabled = 0;
2525 }
David Collins8885f792017-01-26 14:36:34 -08002526 pwm_cfg->lut_params.flags = lut_flags;
2527 ret = qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2528 if (ret) {
2529 pwm_cfg->lut_params.flags = previous_lut_flags;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002530 if (pwm_cfg->pwm_enabled) {
2531 pwm_disable(pwm_cfg->pwm_dev);
2532 pwm_cfg->pwm_enabled = 0;
2533 }
David Collins8885f792017-01-26 14:36:34 -08002534 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2535 qpnp_led_set(&led->cdev, led->cdev.brightness);
2536 dev_err(&led->pdev->dev,
2537 "Failed to initialize pwm with new lut flags value\n");
2538 return ret;
2539 }
2540 qpnp_led_set(&led->cdev, led->cdev.brightness);
2541 return count;
2542}
2543
2544static ssize_t duty_pcts_store(struct device *dev,
2545 struct device_attribute *attr,
2546 const char *buf, size_t count)
2547{
2548 struct qpnp_led_data *led;
2549 int num_duty_pcts = 0;
2550 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2551 char *buffer;
2552 ssize_t ret;
2553 int i = 0;
2554 int max_duty_pcts;
2555 struct pwm_config_data *pwm_cfg;
2556 u32 previous_num_duty_pcts;
2557 int value;
2558 int *previous_duty_pcts;
2559
2560 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2561
2562 switch (led->id) {
2563 case QPNP_ID_LED_MPP:
2564 pwm_cfg = led->mpp_cfg->pwm_cfg;
2565 max_duty_pcts = PWM_LUT_MAX_SIZE;
2566 break;
2567 case QPNP_ID_RGB_RED:
2568 case QPNP_ID_RGB_GREEN:
2569 case QPNP_ID_RGB_BLUE:
2570 pwm_cfg = led->rgb_cfg->pwm_cfg;
2571 max_duty_pcts = PWM_LUT_MAX_SIZE;
2572 break;
2573 case QPNP_ID_KPDBL:
2574 pwm_cfg = led->kpdbl_cfg->pwm_cfg;
2575 max_duty_pcts = PWM_GPLED_LUT_MAX_SIZE;
2576 break;
2577 default:
2578 dev_err(&led->pdev->dev,
2579 "Invalid LED id type for duty pcts\n");
2580 return -EINVAL;
2581 }
2582
2583 if (pwm_cfg->mode == LPG_MODE)
2584 pwm_cfg->blinking = true;
2585
2586 buffer = (char *)buf;
2587
2588 for (i = 0; i < max_duty_pcts; i++) {
2589 if (buffer == NULL)
2590 break;
2591 ret = sscanf((const char *)buffer, "%u,%s", &value, buffer);
2592 pwm_cfg->old_duty_pcts[i] = value;
2593 num_duty_pcts++;
2594 if (ret <= 1)
2595 break;
2596 }
2597
2598 if (num_duty_pcts >= max_duty_pcts) {
2599 dev_err(&led->pdev->dev,
2600 "Number of duty pcts given exceeds max (%d)\n",
2601 max_duty_pcts);
2602 return -EINVAL;
2603 }
2604
2605 previous_num_duty_pcts = pwm_cfg->duty_cycles->num_duty_pcts;
2606 previous_duty_pcts = pwm_cfg->duty_cycles->duty_pcts;
2607
2608 pwm_cfg->duty_cycles->num_duty_pcts = num_duty_pcts;
2609 pwm_cfg->duty_cycles->duty_pcts = pwm_cfg->old_duty_pcts;
2610 pwm_cfg->old_duty_pcts = previous_duty_pcts;
2611 pwm_cfg->lut_params.idx_len = pwm_cfg->duty_cycles->num_duty_pcts;
2612
Fenglin Wu325e6de2017-03-16 13:40:26 +08002613 if (pwm_cfg->pwm_enabled) {
2614 pwm_disable(pwm_cfg->pwm_dev);
2615 pwm_cfg->pwm_enabled = 0;
2616 }
2617
David Collins8885f792017-01-26 14:36:34 -08002618 ret = qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2619 if (ret)
2620 goto restore;
2621
2622 qpnp_led_set(&led->cdev, led->cdev.brightness);
2623 return count;
2624
2625restore:
2626 dev_err(&led->pdev->dev,
2627 "Failed to initialize pwm with new duty pcts value\n");
2628 pwm_cfg->duty_cycles->num_duty_pcts = previous_num_duty_pcts;
2629 pwm_cfg->old_duty_pcts = pwm_cfg->duty_cycles->duty_pcts;
2630 pwm_cfg->duty_cycles->duty_pcts = previous_duty_pcts;
2631 pwm_cfg->lut_params.idx_len = pwm_cfg->duty_cycles->num_duty_pcts;
Fenglin Wu325e6de2017-03-16 13:40:26 +08002632 if (pwm_cfg->pwm_enabled) {
2633 pwm_disable(pwm_cfg->pwm_dev);
2634 pwm_cfg->pwm_enabled = 0;
2635 }
David Collins8885f792017-01-26 14:36:34 -08002636 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2637 qpnp_led_set(&led->cdev, led->cdev.brightness);
2638 return ret;
2639}
2640
2641static void led_blink(struct qpnp_led_data *led,
2642 struct pwm_config_data *pwm_cfg)
2643{
2644 int rc;
2645
2646 flush_work(&led->work);
2647 mutex_lock(&led->lock);
2648 if (pwm_cfg->use_blink) {
2649 if (led->cdev.brightness) {
2650 pwm_cfg->blinking = true;
2651 if (led->id == QPNP_ID_LED_MPP)
2652 led->mpp_cfg->pwm_mode = LPG_MODE;
2653 else if (led->id == QPNP_ID_KPDBL)
2654 led->kpdbl_cfg->pwm_mode = LPG_MODE;
2655 pwm_cfg->mode = LPG_MODE;
2656 } else {
2657 pwm_cfg->blinking = false;
2658 pwm_cfg->mode = pwm_cfg->default_mode;
2659 if (led->id == QPNP_ID_LED_MPP)
2660 led->mpp_cfg->pwm_mode = pwm_cfg->default_mode;
2661 else if (led->id == QPNP_ID_KPDBL)
2662 led->kpdbl_cfg->pwm_mode =
2663 pwm_cfg->default_mode;
2664 }
Fenglin Wu325e6de2017-03-16 13:40:26 +08002665 if (pwm_cfg->pwm_enabled) {
2666 pwm_disable(pwm_cfg->pwm_dev);
2667 pwm_cfg->pwm_enabled = 0;
2668 }
David Collins8885f792017-01-26 14:36:34 -08002669 qpnp_pwm_init(pwm_cfg, led->pdev, led->cdev.name);
2670 if (led->id == QPNP_ID_RGB_RED || led->id == QPNP_ID_RGB_GREEN
2671 || led->id == QPNP_ID_RGB_BLUE) {
2672 rc = qpnp_rgb_set(led);
2673 if (rc < 0)
2674 dev_err(&led->pdev->dev,
2675 "RGB set brightness failed (%d)\n", rc);
2676 } else if (led->id == QPNP_ID_LED_MPP) {
2677 rc = qpnp_mpp_set(led);
2678 if (rc < 0)
2679 dev_err(&led->pdev->dev,
2680 "MPP set brightness failed (%d)\n", rc);
2681 } else if (led->id == QPNP_ID_KPDBL) {
2682 rc = qpnp_kpdbl_set(led);
2683 if (rc < 0)
2684 dev_err(&led->pdev->dev,
2685 "KPDBL set brightness failed (%d)\n", rc);
2686 }
2687 }
2688 mutex_unlock(&led->lock);
2689}
2690
2691static ssize_t blink_store(struct device *dev,
2692 struct device_attribute *attr,
2693 const char *buf, size_t count)
2694{
2695 struct qpnp_led_data *led;
2696 unsigned long blinking;
2697 struct led_classdev *led_cdev = dev_get_drvdata(dev);
2698 ssize_t ret = -EINVAL;
2699
2700 ret = kstrtoul(buf, 10, &blinking);
2701 if (ret)
2702 return ret;
2703 led = container_of(led_cdev, struct qpnp_led_data, cdev);
2704 led->cdev.brightness = blinking ? led->cdev.max_brightness : 0;
2705
2706 switch (led->id) {
2707 case QPNP_ID_LED_MPP:
2708 led_blink(led, led->mpp_cfg->pwm_cfg);
2709 break;
2710 case QPNP_ID_RGB_RED:
2711 case QPNP_ID_RGB_GREEN:
2712 case QPNP_ID_RGB_BLUE:
2713 led_blink(led, led->rgb_cfg->pwm_cfg);
2714 break;
2715 case QPNP_ID_KPDBL:
2716 led_blink(led, led->kpdbl_cfg->pwm_cfg);
2717 break;
2718 default:
2719 dev_err(&led->pdev->dev, "Invalid LED id type for blink\n");
2720 return -EINVAL;
2721 }
2722 return count;
2723}
2724
2725static DEVICE_ATTR(led_mode, 0664, NULL, led_mode_store);
2726static DEVICE_ATTR(strobe, 0664, NULL, led_strobe_type_store);
2727static DEVICE_ATTR(pwm_us, 0664, NULL, pwm_us_store);
2728static DEVICE_ATTR(pause_lo, 0664, NULL, pause_lo_store);
2729static DEVICE_ATTR(pause_hi, 0664, NULL, pause_hi_store);
2730static DEVICE_ATTR(start_idx, 0664, NULL, start_idx_store);
2731static DEVICE_ATTR(ramp_step_ms, 0664, NULL, ramp_step_ms_store);
2732static DEVICE_ATTR(lut_flags, 0664, NULL, lut_flags_store);
2733static DEVICE_ATTR(duty_pcts, 0664, NULL, duty_pcts_store);
2734static DEVICE_ATTR(blink, 0664, NULL, blink_store);
2735
2736static struct attribute *led_attrs[] = {
2737 &dev_attr_led_mode.attr,
2738 &dev_attr_strobe.attr,
2739 NULL
2740};
2741
2742static const struct attribute_group led_attr_group = {
2743 .attrs = led_attrs,
2744};
2745
2746static struct attribute *pwm_attrs[] = {
2747 &dev_attr_pwm_us.attr,
2748 NULL
2749};
2750
2751static struct attribute *lpg_attrs[] = {
2752 &dev_attr_pause_lo.attr,
2753 &dev_attr_pause_hi.attr,
2754 &dev_attr_start_idx.attr,
2755 &dev_attr_ramp_step_ms.attr,
2756 &dev_attr_lut_flags.attr,
2757 &dev_attr_duty_pcts.attr,
2758 NULL
2759};
2760
2761static struct attribute *blink_attrs[] = {
2762 &dev_attr_blink.attr,
2763 NULL
2764};
2765
2766static const struct attribute_group pwm_attr_group = {
2767 .attrs = pwm_attrs,
2768};
2769
2770static const struct attribute_group lpg_attr_group = {
2771 .attrs = lpg_attrs,
2772};
2773
2774static const struct attribute_group blink_attr_group = {
2775 .attrs = blink_attrs,
2776};
2777
2778static int qpnp_flash_init(struct qpnp_led_data *led)
2779{
2780 int rc;
2781
2782 led->flash_cfg->flash_on = false;
2783
2784 rc = qpnp_led_masked_write(led,
2785 FLASH_LED_STROBE_CTRL(led->base),
2786 FLASH_STROBE_MASK, FLASH_DISABLE_ALL);
2787 if (rc) {
2788 dev_err(&led->pdev->dev,
2789 "LED %d flash write failed(%d)\n", led->id, rc);
2790 return rc;
2791 }
2792
2793 /* Disable flash LED module */
2794 rc = qpnp_led_masked_write(led, FLASH_ENABLE_CONTROL(led->base),
2795 FLASH_ENABLE_MASK, FLASH_DISABLE_ALL);
2796 if (rc) {
2797 dev_err(&led->pdev->dev, "Enable reg write failed(%d)\n", rc);
2798 return rc;
2799 }
2800
2801 if (led->flash_cfg->torch_enable)
2802 return 0;
2803
2804 /* Set headroom */
2805 rc = qpnp_led_masked_write(led, FLASH_HEADROOM(led->base),
2806 FLASH_HEADROOM_MASK, led->flash_cfg->headroom);
2807 if (rc) {
2808 dev_err(&led->pdev->dev,
2809 "Headroom reg write failed(%d)\n", rc);
2810 return rc;
2811 }
2812
2813 /* Set startup delay */
2814 rc = qpnp_led_masked_write(led,
2815 FLASH_STARTUP_DELAY(led->base), FLASH_STARTUP_DLY_MASK,
2816 led->flash_cfg->startup_dly);
2817 if (rc) {
2818 dev_err(&led->pdev->dev,
2819 "Startup delay reg write failed(%d)\n", rc);
2820 return rc;
2821 }
2822
2823 /* Set timer control - safety or watchdog */
2824 if (led->flash_cfg->safety_timer) {
2825 rc = qpnp_led_masked_write(led,
2826 FLASH_LED_TMR_CTRL(led->base),
2827 FLASH_TMR_MASK, FLASH_TMR_SAFETY);
2828 if (rc) {
2829 dev_err(&led->pdev->dev,
2830 "LED timer ctrl reg write failed(%d)\n",
2831 rc);
2832 return rc;
2833 }
2834 }
2835
2836 /* Set Vreg force */
2837 if (led->flash_cfg->vreg_ok)
2838 rc = qpnp_led_masked_write(led, FLASH_VREG_OK_FORCE(led->base),
2839 FLASH_VREG_MASK, FLASH_SW_VREG_OK);
2840 else
2841 rc = qpnp_led_masked_write(led, FLASH_VREG_OK_FORCE(led->base),
2842 FLASH_VREG_MASK, FLASH_HW_VREG_OK);
2843
2844 if (rc) {
2845 dev_err(&led->pdev->dev,
2846 "Vreg OK reg write failed(%d)\n", rc);
2847 return rc;
2848 }
2849
2850 /* Set self fault check */
2851 rc = qpnp_led_masked_write(led, FLASH_FAULT_DETECT(led->base),
2852 FLASH_FAULT_DETECT_MASK, FLASH_SELFCHECK_ENABLE);
2853 if (rc) {
2854 dev_err(&led->pdev->dev,
2855 "Fault detect reg write failed(%d)\n", rc);
2856 return rc;
2857 }
2858
2859 /* Set mask enable */
2860 rc = qpnp_led_masked_write(led, FLASH_MASK_ENABLE(led->base),
2861 FLASH_MASK_REG_MASK, FLASH_MASK_1);
2862 if (rc) {
2863 dev_err(&led->pdev->dev,
2864 "Mask enable reg write failed(%d)\n", rc);
2865 return rc;
2866 }
2867
2868 /* Set current ramp */
2869 rc = qpnp_led_masked_write(led, FLASH_CURRENT_RAMP(led->base),
2870 FLASH_CURRENT_RAMP_MASK, FLASH_RAMP_STEP_27US);
2871 if (rc) {
2872 dev_err(&led->pdev->dev,
2873 "Current ramp reg write failed(%d)\n", rc);
2874 return rc;
2875 }
2876
2877 led->flash_cfg->strobe_type = 0;
2878
2879 /* dump flash registers */
2880 qpnp_dump_regs(led, flash_debug_regs, ARRAY_SIZE(flash_debug_regs));
2881
2882 return 0;
2883}
2884
2885static int qpnp_kpdbl_init(struct qpnp_led_data *led)
2886{
2887 int rc;
2888 uint val;
2889
2890 /* select row source - vbst or vph */
2891 rc = regmap_read(led->regmap, KPDBL_ROW_SRC_SEL(led->base), &val);
2892 if (rc) {
2893 dev_err(&led->pdev->dev,
2894 "Unable to read from addr=%x, rc(%d)\n",
2895 KPDBL_ROW_SRC_SEL(led->base), rc);
2896 return rc;
2897 }
2898
2899 if (led->kpdbl_cfg->row_src_vbst)
2900 val |= 1 << led->kpdbl_cfg->row_id;
2901 else
2902 val &= ~(1 << led->kpdbl_cfg->row_id);
2903
2904 rc = regmap_write(led->regmap, KPDBL_ROW_SRC_SEL(led->base), val);
2905 if (rc) {
2906 dev_err(&led->pdev->dev,
2907 "Unable to read from addr=%x, rc(%d)\n",
2908 KPDBL_ROW_SRC_SEL(led->base), rc);
2909 return rc;
2910 }
2911
2912 /* row source enable */
2913 rc = regmap_read(led->regmap, KPDBL_ROW_SRC(led->base), &val);
2914 if (rc) {
2915 dev_err(&led->pdev->dev,
2916 "Unable to read from addr=%x, rc(%d)\n",
2917 KPDBL_ROW_SRC(led->base), rc);
2918 return rc;
2919 }
2920
2921 if (led->kpdbl_cfg->row_src_en)
2922 val |= KPDBL_ROW_SCAN_EN_MASK | (1 << led->kpdbl_cfg->row_id);
2923 else
2924 val &= ~(1 << led->kpdbl_cfg->row_id);
2925
2926 rc = regmap_write(led->regmap, KPDBL_ROW_SRC(led->base), val);
2927 if (rc) {
2928 dev_err(&led->pdev->dev,
2929 "Unable to write to addr=%x, rc(%d)\n",
2930 KPDBL_ROW_SRC(led->base), rc);
2931 return rc;
2932 }
2933
2934 /* enable module */
2935 rc = qpnp_led_masked_write(led, KPDBL_ENABLE(led->base),
2936 KPDBL_MODULE_EN_MASK, KPDBL_MODULE_EN);
2937 if (rc) {
2938 dev_err(&led->pdev->dev,
2939 "Enable module write failed(%d)\n", rc);
2940 return rc;
2941 }
2942
2943 rc = qpnp_pwm_init(led->kpdbl_cfg->pwm_cfg, led->pdev,
2944 led->cdev.name);
2945 if (rc) {
2946 dev_err(&led->pdev->dev, "Failed to initialize pwm\n");
2947 return rc;
2948 }
2949
2950 if (led->kpdbl_cfg->always_on) {
2951 kpdbl_master = led->kpdbl_cfg->pwm_cfg->pwm_dev;
2952 kpdbl_master_period_us = led->kpdbl_cfg->pwm_cfg->pwm_period_us;
2953 }
2954
2955 /* dump kpdbl registers */
2956 qpnp_dump_regs(led, kpdbl_debug_regs, ARRAY_SIZE(kpdbl_debug_regs));
2957
2958 return 0;
2959}
2960
2961static int qpnp_rgb_init(struct qpnp_led_data *led)
2962{
2963 int rc;
2964
2965 rc = qpnp_led_masked_write(led, RGB_LED_SRC_SEL(led->base),
2966 RGB_LED_SRC_MASK, RGB_LED_SOURCE_VPH_PWR);
2967 if (rc) {
2968 dev_err(&led->pdev->dev,
2969 "Failed to write led source select register\n");
2970 return rc;
2971 }
2972
2973 rc = qpnp_pwm_init(led->rgb_cfg->pwm_cfg, led->pdev, led->cdev.name);
2974 if (rc) {
2975 dev_err(&led->pdev->dev, "Failed to initialize pwm\n");
2976 return rc;
2977 }
2978 /* Initialize led for use in auto trickle charging mode */
2979 rc = qpnp_led_masked_write(led, RGB_LED_ATC_CTL(led->base),
2980 led->rgb_cfg->enable, led->rgb_cfg->enable);
2981
2982 return 0;
2983}
2984
2985static int qpnp_mpp_init(struct qpnp_led_data *led)
2986{
2987 int rc;
2988 u8 val;
2989
2990
2991 if (led->max_current < LED_MPP_CURRENT_MIN ||
2992 led->max_current > LED_MPP_CURRENT_MAX) {
2993 dev_err(&led->pdev->dev,
2994 "max current for mpp is not valid\n");
2995 return -EINVAL;
2996 }
2997
2998 val = (led->mpp_cfg->current_setting / LED_MPP_CURRENT_PER_SETTING) - 1;
2999
3000 if (val < 0)
3001 val = 0;
3002
3003 rc = qpnp_led_masked_write(led, LED_MPP_VIN_CTRL(led->base),
3004 LED_MPP_VIN_MASK, led->mpp_cfg->vin_ctrl);
3005 if (rc) {
3006 dev_err(&led->pdev->dev,
3007 "Failed to write led vin control reg\n");
3008 return rc;
3009 }
3010
3011 rc = qpnp_led_masked_write(led, LED_MPP_SINK_CTRL(led->base),
3012 LED_MPP_SINK_MASK, val);
3013 if (rc) {
3014 dev_err(&led->pdev->dev,
3015 "Failed to write sink control reg\n");
3016 return rc;
3017 }
3018
3019 if (led->mpp_cfg->pwm_mode != MANUAL_MODE) {
3020 rc = qpnp_pwm_init(led->mpp_cfg->pwm_cfg, led->pdev,
3021 led->cdev.name);
3022 if (rc) {
3023 dev_err(&led->pdev->dev,
3024 "Failed to initialize pwm\n");
3025 return rc;
3026 }
3027 }
3028
3029 return 0;
3030}
3031
3032static int qpnp_gpio_init(struct qpnp_led_data *led)
3033{
3034 int rc;
3035
3036 rc = qpnp_led_masked_write(led, LED_GPIO_VIN_CTRL(led->base),
3037 LED_GPIO_VIN_MASK, led->gpio_cfg->vin_ctrl);
3038 if (rc) {
3039 dev_err(&led->pdev->dev,
3040 "Failed to write led vin control reg\n");
3041 return rc;
3042 }
3043
3044 return 0;
3045}
3046
3047static int qpnp_led_initialize(struct qpnp_led_data *led)
3048{
3049 int rc = 0;
3050
3051 switch (led->id) {
3052 case QPNP_ID_WLED:
3053 rc = qpnp_wled_init(led);
3054 if (rc)
3055 dev_err(&led->pdev->dev,
3056 "WLED initialize failed(%d)\n", rc);
3057 break;
3058 case QPNP_ID_FLASH1_LED0:
3059 case QPNP_ID_FLASH1_LED1:
3060 rc = qpnp_flash_init(led);
3061 if (rc)
3062 dev_err(&led->pdev->dev,
3063 "FLASH initialize failed(%d)\n", rc);
3064 break;
3065 case QPNP_ID_RGB_RED:
3066 case QPNP_ID_RGB_GREEN:
3067 case QPNP_ID_RGB_BLUE:
3068 rc = qpnp_rgb_init(led);
3069 if (rc)
3070 dev_err(&led->pdev->dev,
3071 "RGB initialize failed(%d)\n", rc);
3072 break;
3073 case QPNP_ID_LED_MPP:
3074 rc = qpnp_mpp_init(led);
3075 if (rc)
3076 dev_err(&led->pdev->dev,
3077 "MPP initialize failed(%d)\n", rc);
3078 break;
3079 case QPNP_ID_LED_GPIO:
3080 rc = qpnp_gpio_init(led);
3081 if (rc)
3082 dev_err(&led->pdev->dev,
3083 "GPIO initialize failed(%d)\n", rc);
3084 break;
3085 case QPNP_ID_KPDBL:
3086 rc = qpnp_kpdbl_init(led);
3087 if (rc)
3088 dev_err(&led->pdev->dev,
3089 "KPDBL initialize failed(%d)\n", rc);
3090 break;
3091 default:
3092 dev_err(&led->pdev->dev, "Invalid LED(%d)\n", led->id);
3093 return -EINVAL;
3094 }
3095
3096 return rc;
3097}
3098
3099static int qpnp_get_common_configs(struct qpnp_led_data *led,
3100 struct device_node *node)
3101{
3102 int rc;
3103 u32 val;
3104 const char *temp_string;
3105
3106 led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
3107 rc = of_property_read_string(node, "linux,default-trigger",
3108 &temp_string);
3109 if (!rc)
3110 led->cdev.default_trigger = temp_string;
3111 else if (rc != -EINVAL)
3112 return rc;
3113
3114 led->default_on = false;
3115 rc = of_property_read_string(node, "qcom,default-state",
3116 &temp_string);
3117 if (!rc) {
3118 if (strcmp(temp_string, "on") == 0)
3119 led->default_on = true;
3120 } else if (rc != -EINVAL)
3121 return rc;
3122
3123 led->turn_off_delay_ms = 0;
3124 rc = of_property_read_u32(node, "qcom,turn-off-delay-ms", &val);
3125 if (!rc)
3126 led->turn_off_delay_ms = val;
3127 else if (rc != -EINVAL)
3128 return rc;
3129
3130 return 0;
3131}
3132
3133/*
3134 * Handlers for alternative sources of platform_data
3135 */
3136static int qpnp_get_config_wled(struct qpnp_led_data *led,
3137 struct device_node *node)
3138{
3139 u32 val;
3140 uint tmp;
3141 int rc;
3142
3143 led->wled_cfg = devm_kzalloc(&led->pdev->dev,
3144 sizeof(struct wled_config_data), GFP_KERNEL);
3145 if (!led->wled_cfg)
3146 return -ENOMEM;
3147
3148 rc = regmap_read(led->regmap, PMIC_VERSION_REG, &tmp);
3149 if (rc) {
3150 dev_err(&led->pdev->dev,
3151 "Unable to read pmic ver, rc(%d)\n", rc);
3152 }
3153 led->wled_cfg->pmic_version = (u8)tmp;
3154
3155 led->wled_cfg->num_strings = WLED_DEFAULT_STRINGS;
3156 rc = of_property_read_u32(node, "qcom,num-strings", &val);
3157 if (!rc)
3158 led->wled_cfg->num_strings = (u8) val;
3159 else if (rc != -EINVAL)
3160 return rc;
3161
3162 led->wled_cfg->num_physical_strings = led->wled_cfg->num_strings;
3163 rc = of_property_read_u32(node, "qcom,num-physical-strings", &val);
3164 if (!rc)
3165 led->wled_cfg->num_physical_strings = (u8) val;
3166 else if (rc != -EINVAL)
3167 return rc;
3168
3169 led->wled_cfg->ovp_val = WLED_DEFAULT_OVP_VAL;
3170 rc = of_property_read_u32(node, "qcom,ovp-val", &val);
3171 if (!rc)
3172 led->wled_cfg->ovp_val = (u8) val;
3173 else if (rc != -EINVAL)
3174 return rc;
3175
3176 led->wled_cfg->boost_curr_lim = WLED_BOOST_LIM_DEFAULT;
3177 rc = of_property_read_u32(node, "qcom,boost-curr-lim", &val);
3178 if (!rc)
3179 led->wled_cfg->boost_curr_lim = (u8) val;
3180 else if (rc != -EINVAL)
3181 return rc;
3182
3183 led->wled_cfg->cp_select = WLED_CP_SEL_DEFAULT;
3184 rc = of_property_read_u32(node, "qcom,cp-sel", &val);
3185 if (!rc)
3186 led->wled_cfg->cp_select = (u8) val;
3187 else if (rc != -EINVAL)
3188 return rc;
3189
3190 led->wled_cfg->ctrl_delay_us = WLED_CTRL_DLY_DEFAULT;
3191 rc = of_property_read_u32(node, "qcom,ctrl-delay-us", &val);
3192 if (!rc)
3193 led->wled_cfg->ctrl_delay_us = (u8) val;
3194 else if (rc != -EINVAL)
3195 return rc;
3196
3197 led->wled_cfg->op_fdbck = WLED_OP_FDBCK_DEFAULT;
3198 rc = of_property_read_u32(node, "qcom,op-fdbck", &val);
3199 if (!rc)
3200 led->wled_cfg->op_fdbck = (u8) val;
3201 else if (rc != -EINVAL)
3202 return rc;
3203
3204 led->wled_cfg->switch_freq = WLED_SWITCH_FREQ_DEFAULT;
3205 rc = of_property_read_u32(node, "qcom,switch-freq", &val);
3206 if (!rc)
3207 led->wled_cfg->switch_freq = (u8) val;
3208 else if (rc != -EINVAL)
3209 return rc;
3210
3211 led->wled_cfg->dig_mod_gen_en =
3212 of_property_read_bool(node, "qcom,dig-mod-gen-en");
3213
3214 led->wled_cfg->cs_out_en =
3215 of_property_read_bool(node, "qcom,cs-out-en");
3216
3217 return 0;
3218}
3219
3220static int qpnp_get_config_flash(struct qpnp_led_data *led,
3221 struct device_node *node, bool *reg_set)
3222{
3223 int rc;
3224 u32 val;
3225 uint tmp;
3226
3227 led->flash_cfg = devm_kzalloc(&led->pdev->dev,
3228 sizeof(struct flash_config_data), GFP_KERNEL);
3229 if (!led->flash_cfg)
3230 return -ENOMEM;
3231
3232 rc = regmap_read(led->regmap, FLASH_PERIPHERAL_SUBTYPE(led->base),
3233 &tmp);
3234 if (rc) {
3235 dev_err(&led->pdev->dev,
3236 "Unable to read from addr=%x, rc(%d)\n",
3237 FLASH_PERIPHERAL_SUBTYPE(led->base), rc);
3238 }
3239 led->flash_cfg->peripheral_subtype = (u8)tmp;
3240
3241 led->flash_cfg->torch_enable =
3242 of_property_read_bool(node, "qcom,torch-enable");
3243
3244 led->flash_cfg->no_smbb_support =
3245 of_property_read_bool(node, "qcom,no-smbb-support");
3246
3247 if (of_find_property(of_get_parent(node), "flash-wa-supply",
3248 NULL) && (!*reg_set)) {
3249 led->flash_cfg->flash_wa_reg =
3250 devm_regulator_get(&led->pdev->dev, "flash-wa");
3251 if (IS_ERR_OR_NULL(led->flash_cfg->flash_wa_reg)) {
3252 rc = PTR_ERR(led->flash_cfg->flash_wa_reg);
3253 if (rc != EPROBE_DEFER) {
3254 dev_err(&led->pdev->dev,
3255 "Flash wa regulator get failed(%d)\n",
3256 rc);
3257 }
3258 } else {
3259 led->flash_cfg->flash_wa_reg_get = true;
3260 }
3261 }
3262
3263 if (led->id == QPNP_ID_FLASH1_LED0) {
3264 led->flash_cfg->enable_module = FLASH_ENABLE_LED_0;
3265 led->flash_cfg->current_addr = FLASH_LED_0_CURR(led->base);
3266 led->flash_cfg->trigger_flash = FLASH_LED_0_OUTPUT;
3267 if (!*reg_set) {
3268 led->flash_cfg->flash_boost_reg =
3269 regulator_get(&led->pdev->dev,
3270 "flash-boost");
3271 if (IS_ERR(led->flash_cfg->flash_boost_reg)) {
3272 rc = PTR_ERR(led->flash_cfg->flash_boost_reg);
3273 dev_err(&led->pdev->dev,
3274 "Regulator get failed(%d)\n", rc);
3275 goto error_get_flash_reg;
3276 }
3277 led->flash_cfg->flash_reg_get = true;
3278 *reg_set = true;
3279 } else
3280 led->flash_cfg->flash_reg_get = false;
3281
3282 if (led->flash_cfg->torch_enable) {
3283 led->flash_cfg->second_addr =
3284 FLASH_LED_1_CURR(led->base);
3285 }
3286 } else if (led->id == QPNP_ID_FLASH1_LED1) {
3287 led->flash_cfg->enable_module = FLASH_ENABLE_LED_1;
3288 led->flash_cfg->current_addr = FLASH_LED_1_CURR(led->base);
3289 led->flash_cfg->trigger_flash = FLASH_LED_1_OUTPUT;
3290 if (!*reg_set) {
3291 led->flash_cfg->flash_boost_reg =
3292 regulator_get(&led->pdev->dev,
3293 "flash-boost");
3294 if (IS_ERR(led->flash_cfg->flash_boost_reg)) {
3295 rc = PTR_ERR(led->flash_cfg->flash_boost_reg);
3296 dev_err(&led->pdev->dev,
3297 "Regulator get failed(%d)\n", rc);
3298 goto error_get_flash_reg;
3299 }
3300 led->flash_cfg->flash_reg_get = true;
3301 *reg_set = true;
3302 } else
3303 led->flash_cfg->flash_reg_get = false;
3304
3305 if (led->flash_cfg->torch_enable) {
3306 led->flash_cfg->second_addr =
3307 FLASH_LED_0_CURR(led->base);
3308 }
3309 } else {
3310 dev_err(&led->pdev->dev, "Unknown flash LED name given\n");
3311 return -EINVAL;
3312 }
3313
3314 if (led->flash_cfg->torch_enable) {
3315 if (of_find_property(of_get_parent(node), "torch-boost-supply",
3316 NULL)) {
3317 if (!led->flash_cfg->no_smbb_support) {
3318 led->flash_cfg->torch_boost_reg =
3319 regulator_get(&led->pdev->dev,
3320 "torch-boost");
3321 if (IS_ERR(led->flash_cfg->torch_boost_reg)) {
3322 rc = PTR_ERR(led->flash_cfg->
3323 torch_boost_reg);
3324 dev_err(&led->pdev->dev,
3325 "Torch regulator get failed(%d)\n", rc);
3326 goto error_get_torch_reg;
3327 }
3328 }
3329 led->flash_cfg->enable_module = FLASH_ENABLE_MODULE;
3330 } else
3331 led->flash_cfg->enable_module = FLASH_ENABLE_ALL;
3332 led->flash_cfg->trigger_flash = FLASH_TORCH_OUTPUT;
3333
3334 rc = of_property_read_u32(node, "qcom,duration", &val);
3335 if (!rc)
3336 led->flash_cfg->duration = ((u8) val) - 2;
3337 else if (rc == -EINVAL)
3338 led->flash_cfg->duration = TORCH_DURATION_12s;
3339 else {
3340 if (led->flash_cfg->peripheral_subtype ==
3341 FLASH_SUBTYPE_SINGLE)
3342 goto error_get_flash_reg;
3343 else if (led->flash_cfg->peripheral_subtype ==
3344 FLASH_SUBTYPE_DUAL)
3345 goto error_get_torch_reg;
3346 }
3347
3348 rc = of_property_read_u32(node, "qcom,current", &val);
3349 if (!rc)
3350 led->flash_cfg->current_prgm = (val *
3351 TORCH_MAX_LEVEL / led->max_current);
3352 else {
3353 if (led->flash_cfg->peripheral_subtype ==
3354 FLASH_SUBTYPE_SINGLE)
3355 goto error_get_flash_reg;
3356 else if (led->flash_cfg->peripheral_subtype ==
3357 FLASH_SUBTYPE_DUAL)
3358 goto error_get_torch_reg;
3359 goto error_get_torch_reg;
3360 }
3361
3362 return 0;
3363 }
3364
3365 rc = of_property_read_u32(node, "qcom,duration", &val);
3366 if (!rc)
3367 led->flash_cfg->duration = (u8)((val - 10) / 10);
3368 else if (rc == -EINVAL)
3369 led->flash_cfg->duration = FLASH_DURATION_200ms;
3370 else
3371 goto error_get_flash_reg;
3372
3373 rc = of_property_read_u32(node, "qcom,current", &val);
3374 if (!rc)
3375 led->flash_cfg->current_prgm = val * FLASH_MAX_LEVEL
3376 / led->max_current;
3377 else
3378 goto error_get_flash_reg;
3379
3380 rc = of_property_read_u32(node, "qcom,headroom", &val);
3381 if (!rc)
3382 led->flash_cfg->headroom = (u8) val;
3383 else if (rc == -EINVAL)
3384 led->flash_cfg->headroom = HEADROOM_500mV;
3385 else
3386 goto error_get_flash_reg;
3387
3388 rc = of_property_read_u32(node, "qcom,clamp-curr", &val);
3389 if (!rc)
3390 led->flash_cfg->clamp_curr = (val *
3391 FLASH_MAX_LEVEL / led->max_current);
3392 else if (rc == -EINVAL)
3393 led->flash_cfg->clamp_curr = FLASH_CLAMP_200mA;
3394 else
3395 goto error_get_flash_reg;
3396
3397 rc = of_property_read_u32(node, "qcom,startup-dly", &val);
3398 if (!rc)
3399 led->flash_cfg->startup_dly = (u8) val;
3400 else if (rc == -EINVAL)
3401 led->flash_cfg->startup_dly = DELAY_128us;
3402 else
3403 goto error_get_flash_reg;
3404
3405 led->flash_cfg->safety_timer =
3406 of_property_read_bool(node, "qcom,safety-timer");
3407
3408 led->flash_cfg->vreg_ok =
3409 of_property_read_bool(node, "qcom,sw_vreg_ok");
3410
3411 return 0;
3412
3413error_get_torch_reg:
3414 if (led->flash_cfg->no_smbb_support)
3415 regulator_put(led->flash_cfg->flash_boost_reg);
3416 else
3417 regulator_put(led->flash_cfg->torch_boost_reg);
3418
3419error_get_flash_reg:
3420 regulator_put(led->flash_cfg->flash_boost_reg);
3421 return rc;
3422
3423}
3424
3425static int qpnp_get_config_pwm(struct pwm_config_data *pwm_cfg,
3426 struct platform_device *pdev,
3427 struct device_node *node)
3428{
3429 struct property *prop;
3430 int rc, i, lut_max_size;
3431 u32 val;
3432 u8 *temp_cfg;
3433 const char *led_label;
3434
3435 pwm_cfg->pwm_dev = of_pwm_get(node, NULL);
3436
3437 if (IS_ERR(pwm_cfg->pwm_dev)) {
3438 rc = PTR_ERR(pwm_cfg->pwm_dev);
3439 dev_err(&pdev->dev, "Cannot get PWM device rc:(%d)\n", rc);
3440 pwm_cfg->pwm_dev = NULL;
3441 return rc;
3442 }
3443
3444 if (pwm_cfg->mode != MANUAL_MODE) {
3445 rc = of_property_read_u32(node, "qcom,pwm-us", &val);
3446 if (!rc)
3447 pwm_cfg->pwm_period_us = val;
3448 else
3449 return rc;
3450 }
3451
3452 pwm_cfg->use_blink =
3453 of_property_read_bool(node, "qcom,use-blink");
3454
3455 if (pwm_cfg->mode == LPG_MODE || pwm_cfg->use_blink) {
3456 pwm_cfg->duty_cycles =
3457 devm_kzalloc(&pdev->dev,
3458 sizeof(struct pwm_duty_cycles), GFP_KERNEL);
3459 if (!pwm_cfg->duty_cycles) {
3460 dev_err(&pdev->dev, "Unable to allocate memory\n");
3461 rc = -ENOMEM;
3462 goto bad_lpg_params;
3463 }
3464
3465 prop = of_find_property(node, "qcom,duty-pcts",
3466 &pwm_cfg->duty_cycles->num_duty_pcts);
3467 if (!prop) {
3468 dev_err(&pdev->dev, "Looking up property node qcom,duty-pcts failed\n");
3469 rc = -ENODEV;
3470 goto bad_lpg_params;
3471 } else if (!pwm_cfg->duty_cycles->num_duty_pcts) {
3472 dev_err(&pdev->dev, "Invalid length of duty pcts\n");
3473 rc = -EINVAL;
3474 goto bad_lpg_params;
3475 }
3476
3477 rc = of_property_read_string(node, "label", &led_label);
3478
3479 if (rc < 0) {
3480 dev_err(&pdev->dev,
3481 "Failure reading label, rc = %d\n", rc);
3482 return rc;
3483 }
3484
3485 if (strcmp(led_label, "kpdbl") == 0)
3486 lut_max_size = PWM_GPLED_LUT_MAX_SIZE;
3487 else
3488 lut_max_size = PWM_LUT_MAX_SIZE;
3489
3490 pwm_cfg->duty_cycles->duty_pcts =
3491 devm_kzalloc(&pdev->dev,
3492 sizeof(int) * lut_max_size,
3493 GFP_KERNEL);
3494 if (!pwm_cfg->duty_cycles->duty_pcts) {
3495 dev_err(&pdev->dev, "Unable to allocate memory\n");
3496 rc = -ENOMEM;
3497 goto bad_lpg_params;
3498 }
3499
3500 pwm_cfg->old_duty_pcts =
3501 devm_kzalloc(&pdev->dev,
3502 sizeof(int) * lut_max_size,
3503 GFP_KERNEL);
3504 if (!pwm_cfg->old_duty_pcts) {
3505 dev_err(&pdev->dev, "Unable to allocate memory\n");
3506 rc = -ENOMEM;
3507 goto bad_lpg_params;
3508 }
3509
3510 temp_cfg = devm_kzalloc(&pdev->dev,
3511 pwm_cfg->duty_cycles->num_duty_pcts *
3512 sizeof(u8), GFP_KERNEL);
3513 if (!temp_cfg) {
3514 dev_err(&pdev->dev, "Failed to allocate memory for duty pcts\n");
3515 rc = -ENOMEM;
3516 goto bad_lpg_params;
3517 }
3518
3519 memcpy(temp_cfg, prop->value,
3520 pwm_cfg->duty_cycles->num_duty_pcts);
3521
3522 for (i = 0; i < pwm_cfg->duty_cycles->num_duty_pcts; i++)
3523 pwm_cfg->duty_cycles->duty_pcts[i] =
3524 (int) temp_cfg[i];
3525
3526 rc = of_property_read_u32(node, "qcom,start-idx", &val);
3527 if (!rc) {
3528 pwm_cfg->lut_params.start_idx = val;
3529 pwm_cfg->duty_cycles->start_idx = val;
3530 } else
3531 goto bad_lpg_params;
3532
3533 pwm_cfg->lut_params.lut_pause_hi = 0;
3534 rc = of_property_read_u32(node, "qcom,pause-hi", &val);
3535 if (!rc)
3536 pwm_cfg->lut_params.lut_pause_hi = val;
3537 else if (rc != -EINVAL)
3538 goto bad_lpg_params;
3539
3540 pwm_cfg->lut_params.lut_pause_lo = 0;
3541 rc = of_property_read_u32(node, "qcom,pause-lo", &val);
3542 if (!rc)
3543 pwm_cfg->lut_params.lut_pause_lo = val;
3544 else if (rc != -EINVAL)
3545 goto bad_lpg_params;
3546
3547 pwm_cfg->lut_params.ramp_step_ms =
3548 QPNP_LUT_RAMP_STEP_DEFAULT;
3549 rc = of_property_read_u32(node, "qcom,ramp-step-ms", &val);
3550 if (!rc)
3551 pwm_cfg->lut_params.ramp_step_ms = val;
3552 else if (rc != -EINVAL)
3553 goto bad_lpg_params;
3554
3555 pwm_cfg->lut_params.flags = QPNP_LED_PWM_FLAGS;
3556 rc = of_property_read_u32(node, "qcom,lut-flags", &val);
3557 if (!rc)
3558 pwm_cfg->lut_params.flags = (u8) val;
3559 else if (rc != -EINVAL)
3560 goto bad_lpg_params;
3561
3562 pwm_cfg->lut_params.idx_len =
3563 pwm_cfg->duty_cycles->num_duty_pcts;
3564 }
3565 return 0;
3566
3567bad_lpg_params:
3568 pwm_cfg->use_blink = false;
3569 if (pwm_cfg->mode == PWM_MODE) {
3570 dev_err(&pdev->dev, "LPG parameters not set for blink mode, defaulting to PWM mode\n");
3571 return 0;
3572 }
3573 return rc;
3574};
3575
3576static int qpnp_led_get_mode(const char *mode)
3577{
3578 if (strcmp(mode, "manual") == 0)
3579 return MANUAL_MODE;
3580 else if (strcmp(mode, "pwm") == 0)
3581 return PWM_MODE;
3582 else if (strcmp(mode, "lpg") == 0)
3583 return LPG_MODE;
3584 else
3585 return -EINVAL;
3586};
3587
3588static int qpnp_get_config_kpdbl(struct qpnp_led_data *led,
3589 struct device_node *node)
3590{
3591 int rc;
3592 u32 val;
3593 u8 led_mode;
3594 const char *mode;
3595
3596 led->kpdbl_cfg = devm_kzalloc(&led->pdev->dev,
3597 sizeof(struct kpdbl_config_data), GFP_KERNEL);
3598 if (!led->kpdbl_cfg)
3599 return -ENOMEM;
3600
3601 rc = of_property_read_string(node, "qcom,mode", &mode);
3602 if (!rc) {
3603 led_mode = qpnp_led_get_mode(mode);
3604 if ((led_mode == MANUAL_MODE) || (led_mode == -EINVAL)) {
3605 dev_err(&led->pdev->dev, "Selected mode not supported for kpdbl.\n");
3606 return -EINVAL;
3607 }
3608 led->kpdbl_cfg->pwm_cfg = devm_kzalloc(&led->pdev->dev,
3609 sizeof(struct pwm_config_data),
3610 GFP_KERNEL);
3611 if (!led->kpdbl_cfg->pwm_cfg)
3612 return -ENOMEM;
3613
3614 led->kpdbl_cfg->pwm_cfg->mode = led_mode;
3615 led->kpdbl_cfg->pwm_cfg->default_mode = led_mode;
3616 } else {
3617 return rc;
3618 }
3619
3620 rc = qpnp_get_config_pwm(led->kpdbl_cfg->pwm_cfg, led->pdev, node);
Fenglin Wu325e6de2017-03-16 13:40:26 +08003621 if (rc < 0) {
3622 if (led->kpdbl_cfg->pwm_cfg->pwm_dev)
3623 pwm_put(led->kpdbl_cfg->pwm_cfg->pwm_dev);
David Collins8885f792017-01-26 14:36:34 -08003624 return rc;
Fenglin Wu325e6de2017-03-16 13:40:26 +08003625 }
David Collins8885f792017-01-26 14:36:34 -08003626
3627 rc = of_property_read_u32(node, "qcom,row-id", &val);
3628 if (!rc)
3629 led->kpdbl_cfg->row_id = val;
3630 else
3631 return rc;
3632
3633 led->kpdbl_cfg->row_src_vbst =
3634 of_property_read_bool(node, "qcom,row-src-vbst");
3635
3636 led->kpdbl_cfg->row_src_en =
3637 of_property_read_bool(node, "qcom,row-src-en");
3638
3639 led->kpdbl_cfg->always_on =
3640 of_property_read_bool(node, "qcom,always-on");
3641
3642 return 0;
3643}
3644
3645static int qpnp_get_config_rgb(struct qpnp_led_data *led,
3646 struct device_node *node)
3647{
3648 int rc;
3649 u8 led_mode;
3650 const char *mode;
3651
3652 led->rgb_cfg = devm_kzalloc(&led->pdev->dev,
3653 sizeof(struct rgb_config_data), GFP_KERNEL);
3654 if (!led->rgb_cfg)
3655 return -ENOMEM;
3656
3657 if (led->id == QPNP_ID_RGB_RED)
3658 led->rgb_cfg->enable = RGB_LED_ENABLE_RED;
3659 else if (led->id == QPNP_ID_RGB_GREEN)
3660 led->rgb_cfg->enable = RGB_LED_ENABLE_GREEN;
3661 else if (led->id == QPNP_ID_RGB_BLUE)
3662 led->rgb_cfg->enable = RGB_LED_ENABLE_BLUE;
3663 else
3664 return -EINVAL;
3665
3666 rc = of_property_read_string(node, "qcom,mode", &mode);
3667 if (!rc) {
3668 led_mode = qpnp_led_get_mode(mode);
3669 if ((led_mode == MANUAL_MODE) || (led_mode == -EINVAL)) {
3670 dev_err(&led->pdev->dev, "Selected mode not supported for rgb\n");
3671 return -EINVAL;
3672 }
3673 led->rgb_cfg->pwm_cfg = devm_kzalloc(&led->pdev->dev,
3674 sizeof(struct pwm_config_data),
3675 GFP_KERNEL);
3676 if (!led->rgb_cfg->pwm_cfg) {
3677 dev_err(&led->pdev->dev,
3678 "Unable to allocate memory\n");
3679 return -ENOMEM;
3680 }
3681 led->rgb_cfg->pwm_cfg->mode = led_mode;
3682 led->rgb_cfg->pwm_cfg->default_mode = led_mode;
3683 } else {
3684 return rc;
3685 }
3686
3687 rc = qpnp_get_config_pwm(led->rgb_cfg->pwm_cfg, led->pdev, node);
Fenglin Wu325e6de2017-03-16 13:40:26 +08003688 if (rc < 0) {
3689 if (led->rgb_cfg->pwm_cfg->pwm_dev)
3690 pwm_put(led->rgb_cfg->pwm_cfg->pwm_dev);
David Collins8885f792017-01-26 14:36:34 -08003691 return rc;
Fenglin Wu325e6de2017-03-16 13:40:26 +08003692 }
David Collins8885f792017-01-26 14:36:34 -08003693
3694 return 0;
3695}
3696
3697static int qpnp_get_config_mpp(struct qpnp_led_data *led,
3698 struct device_node *node)
3699{
3700 int rc;
3701 u32 val;
3702 u8 led_mode;
3703 const char *mode;
3704
3705 led->mpp_cfg = devm_kzalloc(&led->pdev->dev,
3706 sizeof(struct mpp_config_data), GFP_KERNEL);
3707 if (!led->mpp_cfg)
3708 return -ENOMEM;
3709
3710 if (of_find_property(of_get_parent(node), "mpp-power-supply", NULL)) {
3711 led->mpp_cfg->mpp_reg =
3712 regulator_get(&led->pdev->dev,
3713 "mpp-power");
3714 if (IS_ERR(led->mpp_cfg->mpp_reg)) {
3715 rc = PTR_ERR(led->mpp_cfg->mpp_reg);
3716 dev_err(&led->pdev->dev,
3717 "MPP regulator get failed(%d)\n", rc);
3718 return rc;
3719 }
3720 }
3721
3722 if (led->mpp_cfg->mpp_reg) {
3723 rc = of_property_read_u32(of_get_parent(node),
3724 "qcom,mpp-power-max-voltage", &val);
3725 if (!rc)
3726 led->mpp_cfg->max_uV = val;
3727 else
3728 goto err_config_mpp;
3729
3730 rc = of_property_read_u32(of_get_parent(node),
3731 "qcom,mpp-power-min-voltage", &val);
3732 if (!rc)
3733 led->mpp_cfg->min_uV = val;
3734 else
3735 goto err_config_mpp;
3736 } else {
3737 rc = of_property_read_u32(of_get_parent(node),
3738 "qcom,mpp-power-max-voltage", &val);
3739 if (!rc)
3740 dev_warn(&led->pdev->dev, "No regulator specified\n");
3741
3742 rc = of_property_read_u32(of_get_parent(node),
3743 "qcom,mpp-power-min-voltage", &val);
3744 if (!rc)
3745 dev_warn(&led->pdev->dev, "No regulator specified\n");
3746 }
3747
3748 led->mpp_cfg->current_setting = LED_MPP_CURRENT_MIN;
3749 rc = of_property_read_u32(node, "qcom,current-setting", &val);
3750 if (!rc) {
3751 if (led->mpp_cfg->current_setting < LED_MPP_CURRENT_MIN)
3752 led->mpp_cfg->current_setting = LED_MPP_CURRENT_MIN;
3753 else if (led->mpp_cfg->current_setting > LED_MPP_CURRENT_MAX)
3754 led->mpp_cfg->current_setting = LED_MPP_CURRENT_MAX;
3755 else
3756 led->mpp_cfg->current_setting = (u8) val;
3757 } else if (rc != -EINVAL)
3758 goto err_config_mpp;
3759
3760 led->mpp_cfg->source_sel = LED_MPP_SOURCE_SEL_DEFAULT;
3761 rc = of_property_read_u32(node, "qcom,source-sel", &val);
3762 if (!rc)
3763 led->mpp_cfg->source_sel = (u8) val;
3764 else if (rc != -EINVAL)
3765 goto err_config_mpp;
3766
3767 led->mpp_cfg->mode_ctrl = LED_MPP_MODE_SINK;
3768 rc = of_property_read_u32(node, "qcom,mode-ctrl", &val);
3769 if (!rc)
3770 led->mpp_cfg->mode_ctrl = (u8) val;
3771 else if (rc != -EINVAL)
3772 goto err_config_mpp;
3773
3774 led->mpp_cfg->vin_ctrl = LED_MPP_VIN_CTRL_DEFAULT;
3775 rc = of_property_read_u32(node, "qcom,vin-ctrl", &val);
3776 if (!rc)
3777 led->mpp_cfg->vin_ctrl = (u8) val;
3778 else if (rc != -EINVAL)
3779 goto err_config_mpp;
3780
3781 led->mpp_cfg->min_brightness = 0;
3782 rc = of_property_read_u32(node, "qcom,min-brightness", &val);
3783 if (!rc)
3784 led->mpp_cfg->min_brightness = (u8) val;
3785 else if (rc != -EINVAL)
3786 goto err_config_mpp;
3787
3788 rc = of_property_read_string(node, "qcom,mode", &mode);
3789 if (!rc) {
3790 led_mode = qpnp_led_get_mode(mode);
3791 led->mpp_cfg->pwm_mode = led_mode;
3792 if (led_mode == MANUAL_MODE)
3793 return MANUAL_MODE;
3794 else if (led_mode == -EINVAL) {
3795 dev_err(&led->pdev->dev, "Selected mode not supported for mpp\n");
3796 rc = -EINVAL;
3797 goto err_config_mpp;
3798 }
3799 led->mpp_cfg->pwm_cfg = devm_kzalloc(&led->pdev->dev,
3800 sizeof(struct pwm_config_data),
3801 GFP_KERNEL);
3802 if (!led->mpp_cfg->pwm_cfg) {
3803 dev_err(&led->pdev->dev,
3804 "Unable to allocate memory\n");
3805 rc = -ENOMEM;
3806 goto err_config_mpp;
3807 }
3808 led->mpp_cfg->pwm_cfg->mode = led_mode;
3809 led->mpp_cfg->pwm_cfg->default_mode = led_mode;
3810 } else {
3811 return rc;
3812 }
3813
3814 rc = qpnp_get_config_pwm(led->mpp_cfg->pwm_cfg, led->pdev, node);
Fenglin Wu325e6de2017-03-16 13:40:26 +08003815 if (rc < 0) {
3816 if (led->mpp_cfg->pwm_cfg && led->mpp_cfg->pwm_cfg->pwm_dev)
3817 pwm_put(led->mpp_cfg->pwm_cfg->pwm_dev);
David Collins8885f792017-01-26 14:36:34 -08003818 goto err_config_mpp;
Fenglin Wu325e6de2017-03-16 13:40:26 +08003819 }
David Collins8885f792017-01-26 14:36:34 -08003820
3821 return 0;
3822
3823err_config_mpp:
3824 if (led->mpp_cfg->mpp_reg)
3825 regulator_put(led->mpp_cfg->mpp_reg);
3826 return rc;
3827}
3828
3829static int qpnp_get_config_gpio(struct qpnp_led_data *led,
3830 struct device_node *node)
3831{
3832 int rc;
3833 u32 val;
3834
3835 led->gpio_cfg = devm_kzalloc(&led->pdev->dev,
3836 sizeof(struct gpio_config_data), GFP_KERNEL);
3837 if (!led->gpio_cfg)
3838 return -ENOMEM;
3839
3840 led->gpio_cfg->source_sel = LED_GPIO_SOURCE_SEL_DEFAULT;
3841 rc = of_property_read_u32(node, "qcom,source-sel", &val);
3842 if (!rc)
3843 led->gpio_cfg->source_sel = (u8) val;
3844 else if (rc != -EINVAL)
3845 goto err_config_gpio;
3846
3847 led->gpio_cfg->mode_ctrl = LED_GPIO_MODE_OUTPUT;
3848 rc = of_property_read_u32(node, "qcom,mode-ctrl", &val);
3849 if (!rc)
3850 led->gpio_cfg->mode_ctrl = (u8) val;
3851 else if (rc != -EINVAL)
3852 goto err_config_gpio;
3853
3854 led->gpio_cfg->vin_ctrl = LED_GPIO_VIN_CTRL_DEFAULT;
3855 rc = of_property_read_u32(node, "qcom,vin-ctrl", &val);
3856 if (!rc)
3857 led->gpio_cfg->vin_ctrl = (u8) val;
3858 else if (rc != -EINVAL)
3859 goto err_config_gpio;
3860
3861 return 0;
3862
3863err_config_gpio:
3864 return rc;
3865}
3866
3867static int qpnp_leds_probe(struct platform_device *pdev)
3868{
3869 struct qpnp_led_data *led, *led_array;
3870 unsigned int base;
3871 struct device_node *node, *temp;
3872 int rc, i, num_leds = 0, parsed_leds = 0;
3873 const char *led_label;
3874 bool regulator_probe = false;
3875
3876 node = pdev->dev.of_node;
3877 if (node == NULL)
3878 return -ENODEV;
3879
3880 temp = NULL;
3881 while ((temp = of_get_next_child(node, temp)))
3882 num_leds++;
3883
3884 if (!num_leds)
3885 return -ECHILD;
3886
3887 led_array = devm_kcalloc(&pdev->dev, num_leds, sizeof(*led_array),
3888 GFP_KERNEL);
3889 if (!led_array)
3890 return -ENOMEM;
3891
3892 for_each_child_of_node(node, temp) {
3893 led = &led_array[parsed_leds];
3894 led->num_leds = num_leds;
3895 led->regmap = dev_get_regmap(pdev->dev.parent, NULL);
3896 if (!led->regmap) {
3897 dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
3898 return -EINVAL;
3899 }
3900 led->pdev = pdev;
3901
3902 rc = of_property_read_u32(pdev->dev.of_node, "reg", &base);
3903 if (rc < 0) {
3904 dev_err(&pdev->dev,
3905 "Couldn't find reg in node = %s rc = %d\n",
3906 pdev->dev.of_node->full_name, rc);
3907 goto fail_id_check;
3908 }
3909 led->base = base;
3910
3911 rc = of_property_read_string(temp, "label", &led_label);
3912 if (rc < 0) {
3913 dev_err(&led->pdev->dev,
3914 "Failure reading label, rc = %d\n", rc);
3915 goto fail_id_check;
3916 }
3917
3918 rc = of_property_read_string(temp, "linux,name",
3919 &led->cdev.name);
3920 if (rc < 0) {
3921 dev_err(&led->pdev->dev,
3922 "Failure reading led name, rc = %d\n", rc);
3923 goto fail_id_check;
3924 }
3925
3926 rc = of_property_read_u32(temp, "qcom,max-current",
3927 &led->max_current);
3928 if (rc < 0) {
3929 dev_err(&led->pdev->dev,
3930 "Failure reading max_current, rc = %d\n", rc);
3931 goto fail_id_check;
3932 }
3933
3934 rc = of_property_read_u32(temp, "qcom,id", &led->id);
3935 if (rc < 0) {
3936 dev_err(&led->pdev->dev,
3937 "Failure reading led id, rc = %d\n", rc);
3938 goto fail_id_check;
3939 }
3940
3941 rc = qpnp_get_common_configs(led, temp);
3942 if (rc) {
3943 dev_err(&led->pdev->dev, "Failure reading common led configuration, rc = %d\n",
3944 rc);
3945 goto fail_id_check;
3946 }
3947
3948 led->cdev.brightness_set = qpnp_led_set;
3949 led->cdev.brightness_get = qpnp_led_get;
3950
3951 if (strcmp(led_label, "wled") == 0) {
3952 rc = qpnp_get_config_wled(led, temp);
3953 if (rc < 0) {
3954 dev_err(&led->pdev->dev,
3955 "Unable to read wled config data\n");
3956 goto fail_id_check;
3957 }
3958 } else if (strcmp(led_label, "flash") == 0) {
3959 if (!of_find_property(node, "flash-boost-supply", NULL))
3960 regulator_probe = true;
3961 rc = qpnp_get_config_flash(led, temp, &regulator_probe);
3962 if (rc < 0) {
3963 dev_err(&led->pdev->dev,
3964 "Unable to read flash config data\n");
3965 goto fail_id_check;
3966 }
3967 } else if (strcmp(led_label, "rgb") == 0) {
3968 rc = qpnp_get_config_rgb(led, temp);
3969 if (rc < 0) {
3970 dev_err(&led->pdev->dev,
3971 "Unable to read rgb config data\n");
3972 goto fail_id_check;
3973 }
3974 } else if (strcmp(led_label, "mpp") == 0) {
3975 rc = qpnp_get_config_mpp(led, temp);
3976 if (rc < 0) {
3977 dev_err(&led->pdev->dev,
3978 "Unable to read mpp config data\n");
3979 goto fail_id_check;
3980 }
3981 } else if (strcmp(led_label, "gpio") == 0) {
3982 rc = qpnp_get_config_gpio(led, temp);
3983 if (rc < 0) {
3984 dev_err(&led->pdev->dev,
3985 "Unable to read gpio config data\n");
3986 goto fail_id_check;
3987 }
3988 } else if (strcmp(led_label, "kpdbl") == 0) {
3989 bitmap_zero(kpdbl_leds_in_use, NUM_KPDBL_LEDS);
3990 is_kpdbl_master_turn_on = false;
3991 rc = qpnp_get_config_kpdbl(led, temp);
3992 if (rc < 0) {
3993 dev_err(&led->pdev->dev,
3994 "Unable to read kpdbl config data\n");
3995 goto fail_id_check;
3996 }
3997 } else {
3998 dev_err(&led->pdev->dev, "No LED matching label\n");
3999 rc = -EINVAL;
4000 goto fail_id_check;
4001 }
4002
4003 if (led->id != QPNP_ID_FLASH1_LED0 &&
4004 led->id != QPNP_ID_FLASH1_LED1)
4005 mutex_init(&led->lock);
4006
4007 led->in_order_command_processing = of_property_read_bool
4008 (temp, "qcom,in-order-command-processing");
4009
4010 if (led->in_order_command_processing) {
4011 /*
4012 * the command order from user space needs to be
4013 * maintained use ordered workqueue to prevent
4014 * concurrency
4015 */
4016 led->workqueue = alloc_ordered_workqueue
4017 ("led_workqueue", 0);
4018 if (!led->workqueue) {
4019 rc = -ENOMEM;
4020 goto fail_id_check;
4021 }
4022 }
4023
4024 INIT_WORK(&led->work, qpnp_led_work);
4025
4026 rc = qpnp_led_initialize(led);
4027 if (rc < 0)
4028 goto fail_id_check;
4029
4030 rc = qpnp_led_set_max_brightness(led);
4031 if (rc < 0)
4032 goto fail_id_check;
4033
4034 rc = led_classdev_register(&pdev->dev, &led->cdev);
4035 if (rc) {
4036 dev_err(&pdev->dev,
4037 "unable to register led %d,rc=%d\n",
4038 led->id, rc);
4039 goto fail_id_check;
4040 }
4041
4042 if (led->id == QPNP_ID_FLASH1_LED0 ||
4043 led->id == QPNP_ID_FLASH1_LED1) {
4044 rc = sysfs_create_group(&led->cdev.dev->kobj,
4045 &led_attr_group);
4046 if (rc)
4047 goto fail_id_check;
4048
4049 }
4050
4051 if (led->id == QPNP_ID_LED_MPP) {
4052 if (!led->mpp_cfg->pwm_cfg)
4053 break;
4054 if (led->mpp_cfg->pwm_cfg->mode == PWM_MODE) {
4055 rc = sysfs_create_group(&led->cdev.dev->kobj,
4056 &pwm_attr_group);
4057 if (rc)
4058 goto fail_id_check;
4059 }
4060 if (led->mpp_cfg->pwm_cfg->use_blink) {
4061 rc = sysfs_create_group(&led->cdev.dev->kobj,
4062 &blink_attr_group);
4063 if (rc)
4064 goto fail_id_check;
4065
4066 rc = sysfs_create_group(&led->cdev.dev->kobj,
4067 &lpg_attr_group);
4068 if (rc)
4069 goto fail_id_check;
4070 } else if (led->mpp_cfg->pwm_cfg->mode == LPG_MODE) {
4071 rc = sysfs_create_group(&led->cdev.dev->kobj,
4072 &lpg_attr_group);
4073 if (rc)
4074 goto fail_id_check;
4075 }
4076 } else if ((led->id == QPNP_ID_RGB_RED) ||
4077 (led->id == QPNP_ID_RGB_GREEN) ||
4078 (led->id == QPNP_ID_RGB_BLUE)) {
4079 if (led->rgb_cfg->pwm_cfg->mode == PWM_MODE) {
4080 rc = sysfs_create_group(&led->cdev.dev->kobj,
4081 &pwm_attr_group);
4082 if (rc)
4083 goto fail_id_check;
4084 }
4085 if (led->rgb_cfg->pwm_cfg->use_blink) {
4086 rc = sysfs_create_group(&led->cdev.dev->kobj,
4087 &blink_attr_group);
4088 if (rc)
4089 goto fail_id_check;
4090
4091 rc = sysfs_create_group(&led->cdev.dev->kobj,
4092 &lpg_attr_group);
4093 if (rc)
4094 goto fail_id_check;
4095 } else if (led->rgb_cfg->pwm_cfg->mode == LPG_MODE) {
4096 rc = sysfs_create_group(&led->cdev.dev->kobj,
4097 &lpg_attr_group);
4098 if (rc)
4099 goto fail_id_check;
4100 }
4101 } else if (led->id == QPNP_ID_KPDBL) {
4102 if (led->kpdbl_cfg->pwm_cfg->mode == PWM_MODE) {
4103 rc = sysfs_create_group(&led->cdev.dev->kobj,
4104 &pwm_attr_group);
4105 if (rc)
4106 goto fail_id_check;
4107 }
4108 if (led->kpdbl_cfg->pwm_cfg->use_blink) {
4109 rc = sysfs_create_group(&led->cdev.dev->kobj,
4110 &blink_attr_group);
4111 if (rc)
4112 goto fail_id_check;
4113
4114 rc = sysfs_create_group(&led->cdev.dev->kobj,
4115 &lpg_attr_group);
4116 if (rc)
4117 goto fail_id_check;
4118 } else if (led->kpdbl_cfg->pwm_cfg->mode == LPG_MODE) {
4119 rc = sysfs_create_group(&led->cdev.dev->kobj,
4120 &lpg_attr_group);
4121 if (rc)
4122 goto fail_id_check;
4123 }
4124 }
4125
4126 /* configure default state */
4127 if (led->default_on) {
4128 led->cdev.brightness = led->cdev.max_brightness;
4129 __qpnp_led_work(led, led->cdev.brightness);
4130 if (led->turn_off_delay_ms > 0)
4131 qpnp_led_turn_off(led);
4132 } else
4133 led->cdev.brightness = LED_OFF;
4134
4135 parsed_leds++;
4136 }
4137 dev_set_drvdata(&pdev->dev, led_array);
4138 return 0;
4139
4140fail_id_check:
4141 for (i = 0; i < parsed_leds; i++) {
4142 if (led_array[i].id != QPNP_ID_FLASH1_LED0 &&
4143 led_array[i].id != QPNP_ID_FLASH1_LED1)
4144 mutex_destroy(&led_array[i].lock);
4145 if (led_array[i].in_order_command_processing)
4146 destroy_workqueue(led_array[i].workqueue);
4147 led_classdev_unregister(&led_array[i].cdev);
4148 }
4149
4150 return rc;
4151}
4152
4153static int qpnp_leds_remove(struct platform_device *pdev)
4154{
4155 struct qpnp_led_data *led_array = dev_get_drvdata(&pdev->dev);
4156 int i, parsed_leds = led_array->num_leds;
4157
4158 for (i = 0; i < parsed_leds; i++) {
4159 cancel_work_sync(&led_array[i].work);
4160 if (led_array[i].id != QPNP_ID_FLASH1_LED0 &&
4161 led_array[i].id != QPNP_ID_FLASH1_LED1)
4162 mutex_destroy(&led_array[i].lock);
4163
4164 if (led_array[i].in_order_command_processing)
4165 destroy_workqueue(led_array[i].workqueue);
4166 led_classdev_unregister(&led_array[i].cdev);
4167 switch (led_array[i].id) {
4168 case QPNP_ID_WLED:
4169 break;
4170 case QPNP_ID_FLASH1_LED0:
4171 case QPNP_ID_FLASH1_LED1:
4172 if (led_array[i].flash_cfg->flash_reg_get)
4173 regulator_put(
4174 led_array[i].flash_cfg->flash_boost_reg);
4175 if (led_array[i].flash_cfg->torch_enable)
4176 if (!led_array[i].flash_cfg->no_smbb_support)
4177 regulator_put(led_array[i].
4178 flash_cfg->torch_boost_reg);
4179 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4180 &led_attr_group);
4181 break;
4182 case QPNP_ID_RGB_RED:
4183 case QPNP_ID_RGB_GREEN:
4184 case QPNP_ID_RGB_BLUE:
4185 if (led_array[i].rgb_cfg->pwm_cfg->mode == PWM_MODE)
4186 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4187 &pwm_attr_group);
4188 if (led_array[i].rgb_cfg->pwm_cfg->use_blink) {
4189 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4190 &blink_attr_group);
4191 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4192 &lpg_attr_group);
4193 } else if (led_array[i].rgb_cfg->pwm_cfg->mode
4194 == LPG_MODE)
4195 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4196 &lpg_attr_group);
4197 break;
4198 case QPNP_ID_LED_MPP:
4199 if (!led_array[i].mpp_cfg->pwm_cfg)
4200 break;
4201 if (led_array[i].mpp_cfg->pwm_cfg->mode == PWM_MODE)
4202 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4203 &pwm_attr_group);
4204 if (led_array[i].mpp_cfg->pwm_cfg->use_blink) {
4205 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4206 &blink_attr_group);
4207 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4208 &lpg_attr_group);
4209 } else if (led_array[i].mpp_cfg->pwm_cfg->mode
4210 == LPG_MODE)
4211 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4212 &lpg_attr_group);
4213 if (led_array[i].mpp_cfg->mpp_reg)
4214 regulator_put(led_array[i].mpp_cfg->mpp_reg);
4215 break;
4216 case QPNP_ID_KPDBL:
4217 if (led_array[i].kpdbl_cfg->pwm_cfg->mode == PWM_MODE)
4218 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4219 &pwm_attr_group);
4220 if (led_array[i].kpdbl_cfg->pwm_cfg->use_blink) {
4221 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4222 &blink_attr_group);
4223 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4224 &lpg_attr_group);
4225 } else if (led_array[i].kpdbl_cfg->pwm_cfg->mode
4226 == LPG_MODE)
4227 sysfs_remove_group(&led_array[i].cdev.dev->kobj,
4228 &lpg_attr_group);
4229 break;
4230 default:
4231 dev_err(&led_array->pdev->dev,
4232 "Invalid LED(%d)\n",
4233 led_array[i].id);
4234 return -EINVAL;
4235 }
4236 }
4237
4238 return 0;
4239}
4240
4241#ifdef CONFIG_OF
4242static const struct of_device_id spmi_match_table[] = {
4243 { .compatible = "qcom,leds-qpnp",},
4244 { },
4245};
4246#else
4247#define spmi_match_table NULL
4248#endif
4249
4250static struct platform_driver qpnp_leds_driver = {
4251 .driver = {
4252 .name = "qcom,leds-qpnp",
4253 .of_match_table = spmi_match_table,
4254 },
4255 .probe = qpnp_leds_probe,
4256 .remove = qpnp_leds_remove,
4257};
4258
4259static int __init qpnp_led_init(void)
4260{
4261 return platform_driver_register(&qpnp_leds_driver);
4262}
4263module_init(qpnp_led_init);
4264
4265static void __exit qpnp_led_exit(void)
4266{
4267 platform_driver_unregister(&qpnp_leds_driver);
4268}
4269module_exit(qpnp_led_exit);
4270
4271MODULE_DESCRIPTION("QPNP LEDs driver");
4272MODULE_LICENSE("GPL v2");
4273MODULE_ALIAS("leds:leds-qpnp");
4274