Blame view

drivers/leds/leds-lm3530.c 12.7 KB
0376148f3   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
2
3
4
5
  /*
   * Copyright (C) 2011 ST-Ericsson SA.
   * Copyright (C) 2009 Motorola, Inc.
   *
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
6
7
8
9
10
11
12
13
14
15
16
17
18
   * Simple driver for National Semiconductor LM3530 Backlight driver chip
   *
   * Author: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>
   * based on leds-lm3530.c by Dan Murphy <D.Murphy@motorola.com>
   */
  
  #include <linux/i2c.h>
  #include <linux/leds.h>
  #include <linux/slab.h>
  #include <linux/platform_device.h>
  #include <linux/input.h>
  #include <linux/led-lm3530.h>
  #include <linux/types.h>
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
19
  #include <linux/regulator/consumer.h>
54f4dedb5   Paul Gortmaker   drivers/leds: Add...
20
  #include <linux/module.h>
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
21
22
23
24
25
26
27
  
  #define LM3530_LED_DEV "lcd-backlight"
  #define LM3530_NAME "lm3530-led"
  
  #define LM3530_GEN_CONFIG		0x10
  #define LM3530_ALS_CONFIG		0x20
  #define LM3530_BRT_RAMP_RATE		0x30
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
28
29
30
31
32
33
34
35
36
37
38
  #define LM3530_ALS_IMP_SELECT		0x41
  #define LM3530_BRT_CTRL_REG		0xA0
  #define LM3530_ALS_ZB0_REG		0x60
  #define LM3530_ALS_ZB1_REG		0x61
  #define LM3530_ALS_ZB2_REG		0x62
  #define LM3530_ALS_ZB3_REG		0x63
  #define LM3530_ALS_Z0T_REG		0x70
  #define LM3530_ALS_Z1T_REG		0x71
  #define LM3530_ALS_Z2T_REG		0x72
  #define LM3530_ALS_Z3T_REG		0x73
  #define LM3530_ALS_Z4T_REG		0x74
8544d0e3f   Kim, Milo   leds-lm3530: remo...
39
  #define LM3530_REG_MAX			14
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  
  /* General Control Register */
  #define LM3530_EN_I2C_SHIFT		(0)
  #define LM3530_RAMP_LAW_SHIFT		(1)
  #define LM3530_MAX_CURR_SHIFT		(2)
  #define LM3530_EN_PWM_SHIFT		(5)
  #define LM3530_PWM_POL_SHIFT		(6)
  #define LM3530_EN_PWM_SIMPLE_SHIFT	(7)
  
  #define LM3530_ENABLE_I2C		(1 << LM3530_EN_I2C_SHIFT)
  #define LM3530_ENABLE_PWM		(1 << LM3530_EN_PWM_SHIFT)
  #define LM3530_POL_LOW			(1 << LM3530_PWM_POL_SHIFT)
  #define LM3530_ENABLE_PWM_SIMPLE	(1 << LM3530_EN_PWM_SIMPLE_SHIFT)
  
  /* ALS Config Register Options */
  #define LM3530_ALS_AVG_TIME_SHIFT	(0)
  #define LM3530_EN_ALS_SHIFT		(3)
  #define LM3530_ALS_SEL_SHIFT		(5)
  
  #define LM3530_ENABLE_ALS		(3 << LM3530_EN_ALS_SHIFT)
  
  /* Brightness Ramp Rate Register */
  #define LM3530_BRT_RAMP_FALL_SHIFT	(0)
  #define LM3530_BRT_RAMP_RISE_SHIFT	(3)
  
  /* ALS Resistor Select */
  #define LM3530_ALS1_IMP_SHIFT		(0)
  #define LM3530_ALS2_IMP_SHIFT		(4)
  
  /* Zone Boundary Register defaults */
40b1445b1   Shreshtha Kumar Sahu   arch/arm/mach-ux5...
70
71
72
  #define LM3530_ALS_ZB_MAX		(4)
  #define LM3530_ALS_WINDOW_mV		(1000)
  #define LM3530_ALS_OFFSET_mV		(4)
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
73
74
  
  /* Zone Target Register defaults */
40b1445b1   Shreshtha Kumar Sahu   arch/arm/mach-ux5...
75
76
  #define LM3530_DEF_ZT_0			(0x7F)
  #define LM3530_DEF_ZT_1			(0x66)
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
77
  #define LM3530_DEF_ZT_2			(0x4C)
40b1445b1   Shreshtha Kumar Sahu   arch/arm/mach-ux5...
78
79
  #define LM3530_DEF_ZT_3			(0x33)
  #define LM3530_DEF_ZT_4			(0x19)
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
80

bbe645320   Kim, Milo   leds-lm3530: set ...
81
82
  /* 7 bits are used for the brightness : LM3530_BRT_CTRL_REG */
  #define MAX_BRIGHTNESS			(127)
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  struct lm3530_mode_map {
  	const char *mode;
  	enum lm3530_mode mode_val;
  };
  
  static struct lm3530_mode_map mode_map[] = {
  	{ "man", LM3530_BL_MODE_MANUAL },
  	{ "als", LM3530_BL_MODE_ALS },
  	{ "pwm", LM3530_BL_MODE_PWM },
  };
  
  /**
   * struct lm3530_data
   * @led_dev: led class device
   * @client: i2c client
   * @pdata: LM3530 platform data
   * @mode: mode of operation - manual, ALS, PWM
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
100
101
102
   * @regulator: regulator
   * @brighness: previous brightness value
   * @enable: regulator is enabled
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
103
104
105
106
107
108
   */
  struct lm3530_data {
  	struct led_classdev led_dev;
  	struct i2c_client *client;
  	struct lm3530_platform_data *pdata;
  	enum lm3530_mode mode;
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
109
110
111
  	struct regulator *regulator;
  	enum led_brightness brightness;
  	bool enable;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
112
  };
6335f8fa9   Kim, Milo   drivers/leds/leds...
113
114
115
116
117
118
119
120
121
122
123
  /*
   * struct lm3530_als_data
   * @config  : value of ALS configuration register
   * @imp_sel : value of ALS resistor select register
   * @zone    : values of ALS ZB(Zone Boundary) registers
   */
  struct lm3530_als_data {
  	u8 config;
  	u8 imp_sel;
  	u8 zones[LM3530_ALS_ZB_MAX];
  };
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
124
125
126
127
  static const u8 lm3530_reg[LM3530_REG_MAX] = {
  	LM3530_GEN_CONFIG,
  	LM3530_ALS_CONFIG,
  	LM3530_BRT_RAMP_RATE,
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  	LM3530_ALS_IMP_SELECT,
  	LM3530_BRT_CTRL_REG,
  	LM3530_ALS_ZB0_REG,
  	LM3530_ALS_ZB1_REG,
  	LM3530_ALS_ZB2_REG,
  	LM3530_ALS_ZB3_REG,
  	LM3530_ALS_Z0T_REG,
  	LM3530_ALS_Z1T_REG,
  	LM3530_ALS_Z2T_REG,
  	LM3530_ALS_Z3T_REG,
  	LM3530_ALS_Z4T_REG,
  };
  
  static int lm3530_get_mode_from_str(const char *str)
  {
  	int i;
  
  	for (i = 0; i < ARRAY_SIZE(mode_map); i++)
  		if (sysfs_streq(str, mode_map[i].mode))
  			return mode_map[i].mode_val;
e0e021600   Sachin Kamat   leds-lm3530: Fix ...
148
  	return -EINVAL;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
149
  }
6335f8fa9   Kim, Milo   drivers/leds/leds...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  static void lm3530_als_configure(struct lm3530_platform_data *pdata,
  				struct lm3530_als_data *als)
  {
  	int i;
  	u32 als_vmin, als_vmax, als_vstep;
  
  	if (pdata->als_vmax == 0) {
  		pdata->als_vmin = 0;
  		pdata->als_vmax = LM3530_ALS_WINDOW_mV;
  	}
  
  	als_vmin = pdata->als_vmin;
  	als_vmax = pdata->als_vmax;
  
  	if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV)
  		pdata->als_vmax = als_vmax = als_vmin + LM3530_ALS_WINDOW_mV;
  
  	/* n zone boundary makes n+1 zones */
  	als_vstep = (als_vmax - als_vmin) / (LM3530_ALS_ZB_MAX + 1);
  
  	for (i = 0; i < LM3530_ALS_ZB_MAX; i++)
  		als->zones[i] = (((als_vmin + LM3530_ALS_OFFSET_mV) +
  			als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
  
  	als->config =
  		(pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
  		(LM3530_ENABLE_ALS) |
  		(pdata->als_input_mode << LM3530_ALS_SEL_SHIFT);
  
  	als->imp_sel =
  		(pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
  		(pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
  }
5e3b7c6b1   Axel Lin   leds: lm3530: Ens...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  static int lm3530_led_enable(struct lm3530_data *drvdata)
  {
  	int ret;
  
  	if (drvdata->enable)
  		return 0;
  
  	ret = regulator_enable(drvdata->regulator);
  	if (ret) {
  		dev_err(drvdata->led_dev.dev, "Failed to enable vin:%d
  ", ret);
  		return ret;
  	}
  
  	drvdata->enable = true;
  	return 0;
  }
  
  static void lm3530_led_disable(struct lm3530_data *drvdata)
  {
  	int ret;
  
  	if (!drvdata->enable)
  		return;
  
  	ret = regulator_disable(drvdata->regulator);
  	if (ret) {
  		dev_err(drvdata->led_dev.dev, "Failed to disable vin:%d
  ",
  			ret);
  		return;
  	}
  
  	drvdata->enable = false;
  }
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
218
219
220
221
222
  static int lm3530_init_registers(struct lm3530_data *drvdata)
  {
  	int ret = 0;
  	int i;
  	u8 gen_config;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
223
  	u8 brt_ramp;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
224
225
  	u8 brightness;
  	u8 reg_val[LM3530_REG_MAX];
99ad98d25   Kim, Milo   leds-lm3530: repl...
226
  	struct lm3530_platform_data *pdata = drvdata->pdata;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
227
  	struct i2c_client *client = drvdata->client;
99ad98d25   Kim, Milo   leds-lm3530: repl...
228
  	struct lm3530_pwm_data *pwm = &pdata->pwm_data;
6335f8fa9   Kim, Milo   drivers/leds/leds...
229
230
231
  	struct lm3530_als_data als;
  
  	memset(&als, 0, sizeof(struct lm3530_als_data));
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
232

99ad98d25   Kim, Milo   leds-lm3530: repl...
233
234
  	gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
  			((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
235

cea694ca3   Axel Lin   drivers/leds/leds...
236
237
  	switch (drvdata->mode) {
  	case LM3530_BL_MODE_MANUAL:
6335f8fa9   Kim, Milo   drivers/leds/leds...
238
239
  		gen_config |= LM3530_ENABLE_I2C;
  		break;
cea694ca3   Axel Lin   drivers/leds/leds...
240
241
  	case LM3530_BL_MODE_ALS:
  		gen_config |= LM3530_ENABLE_I2C;
6335f8fa9   Kim, Milo   drivers/leds/leds...
242
  		lm3530_als_configure(pdata, &als);
cea694ca3   Axel Lin   drivers/leds/leds...
243
244
245
246
247
248
  		break;
  	case LM3530_BL_MODE_PWM:
  		gen_config |= LM3530_ENABLE_PWM | LM3530_ENABLE_PWM_SIMPLE |
  			      (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT);
  		break;
  	}
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
249

99ad98d25   Kim, Milo   leds-lm3530: repl...
250
251
  	brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
  			(pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
252

9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
253
254
255
  	if (drvdata->brightness)
  		brightness = drvdata->brightness;
  	else
99ad98d25   Kim, Milo   leds-lm3530: repl...
256
  		brightness = drvdata->brightness = pdata->brt_val;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
257

bbe645320   Kim, Milo   leds-lm3530: set ...
258
259
  	if (brightness > drvdata->led_dev.max_brightness)
  		brightness = drvdata->led_dev.max_brightness;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
260
  	reg_val[0] = gen_config;	/* LM3530_GEN_CONFIG */
6335f8fa9   Kim, Milo   drivers/leds/leds...
261
  	reg_val[1] = als.config;	/* LM3530_ALS_CONFIG */
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
262
  	reg_val[2] = brt_ramp;		/* LM3530_BRT_RAMP_RATE */
6335f8fa9   Kim, Milo   drivers/leds/leds...
263
  	reg_val[3] = als.imp_sel;	/* LM3530_ALS_IMP_SELECT */
8544d0e3f   Kim, Milo   leds-lm3530: remo...
264
  	reg_val[4] = brightness;	/* LM3530_BRT_CTRL_REG */
6335f8fa9   Kim, Milo   drivers/leds/leds...
265
266
267
268
  	reg_val[5] = als.zones[0];	/* LM3530_ALS_ZB0_REG */
  	reg_val[6] = als.zones[1];	/* LM3530_ALS_ZB1_REG */
  	reg_val[7] = als.zones[2];	/* LM3530_ALS_ZB2_REG */
  	reg_val[8] = als.zones[3];	/* LM3530_ALS_ZB3_REG */
8544d0e3f   Kim, Milo   leds-lm3530: remo...
269
270
271
272
273
  	reg_val[9] = LM3530_DEF_ZT_0;	/* LM3530_ALS_Z0T_REG */
  	reg_val[10] = LM3530_DEF_ZT_1;	/* LM3530_ALS_Z1T_REG */
  	reg_val[11] = LM3530_DEF_ZT_2;	/* LM3530_ALS_Z2T_REG */
  	reg_val[12] = LM3530_DEF_ZT_3;	/* LM3530_ALS_Z3T_REG */
  	reg_val[13] = LM3530_DEF_ZT_4;	/* LM3530_ALS_Z4T_REG */
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
274

5e3b7c6b1   Axel Lin   leds: lm3530: Ens...
275
276
277
  	ret = lm3530_led_enable(drvdata);
  	if (ret)
  		return ret;
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
278

b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
279
  	for (i = 0; i < LM3530_REG_MAX; i++) {
bb982009d   Kim, Milo   leds-lm3530: supp...
280
281
282
283
284
285
286
287
  		/* do not update brightness register when pwm mode */
  		if (lm3530_reg[i] == LM3530_BRT_CTRL_REG &&
  		    drvdata->mode == LM3530_BL_MODE_PWM) {
  			if (pwm->pwm_set_intensity)
  				pwm->pwm_set_intensity(reg_val[i],
  					drvdata->led_dev.max_brightness);
  			continue;
  		}
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  		ret = i2c_smbus_write_byte_data(client,
  				lm3530_reg[i], reg_val[i]);
  		if (ret)
  			break;
  	}
  
  	return ret;
  }
  
  static void lm3530_brightness_set(struct led_classdev *led_cdev,
  				     enum led_brightness brt_val)
  {
  	int err;
  	struct lm3530_data *drvdata =
  	    container_of(led_cdev, struct lm3530_data, led_dev);
bb982009d   Kim, Milo   leds-lm3530: supp...
303
304
305
  	struct lm3530_platform_data *pdata = drvdata->pdata;
  	struct lm3530_pwm_data *pwm = &pdata->pwm_data;
  	u8 max_brightness = led_cdev->max_brightness;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
306
307
308
  
  	switch (drvdata->mode) {
  	case LM3530_BL_MODE_MANUAL:
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
309
310
311
312
313
314
315
316
317
  		if (!drvdata->enable) {
  			err = lm3530_init_registers(drvdata);
  			if (err) {
  				dev_err(&drvdata->client->dev,
  					"Register Init failed: %d
  ", err);
  				break;
  			}
  		}
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
318
319
  		/* set the brightness in brightness control register*/
  		err = i2c_smbus_write_byte_data(drvdata->client,
bbe645320   Kim, Milo   leds-lm3530: set ...
320
  				LM3530_BRT_CTRL_REG, brt_val);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
321
322
323
324
  		if (err)
  			dev_err(&drvdata->client->dev,
  				"Unable to set brightness: %d
  ", err);
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
325
  		else
bbe645320   Kim, Milo   leds-lm3530: set ...
326
  			drvdata->brightness = brt_val;
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
327

5e3b7c6b1   Axel Lin   leds: lm3530: Ens...
328
329
  		if (brt_val == 0)
  			lm3530_led_disable(drvdata);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
330
331
332
333
  		break;
  	case LM3530_BL_MODE_ALS:
  		break;
  	case LM3530_BL_MODE_PWM:
bb982009d   Kim, Milo   leds-lm3530: supp...
334
335
  		if (pwm->pwm_set_intensity)
  			pwm->pwm_set_intensity(brt_val, max_brightness);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
336
337
338
339
340
  		break;
  	default:
  		break;
  	}
  }
40b1445b1   Shreshtha Kumar Sahu   arch/arm/mach-ux5...
341
342
343
  static ssize_t lm3530_mode_get(struct device *dev,
  		struct device_attribute *attr, char *buf)
  {
e13d97865   Kim, Milo   leds-lm3530: repl...
344
345
  	struct led_classdev *led_cdev = dev_get_drvdata(dev);
  	struct lm3530_data *drvdata;
40b1445b1   Shreshtha Kumar Sahu   arch/arm/mach-ux5...
346
  	int i, len = 0;
e13d97865   Kim, Milo   leds-lm3530: repl...
347
  	drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
40b1445b1   Shreshtha Kumar Sahu   arch/arm/mach-ux5...
348
349
350
351
352
353
354
355
356
357
358
  	for (i = 0; i < ARRAY_SIZE(mode_map); i++)
  		if (drvdata->mode == mode_map[i].mode_val)
  			len += sprintf(buf + len, "[%s] ", mode_map[i].mode);
  		else
  			len += sprintf(buf + len, "%s ", mode_map[i].mode);
  
  	len += sprintf(buf + len, "
  ");
  
  	return len;
  }
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
359
360
361
362
  
  static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
  				   *attr, const char *buf, size_t size)
  {
e13d97865   Kim, Milo   leds-lm3530: repl...
363
364
  	struct led_classdev *led_cdev = dev_get_drvdata(dev);
  	struct lm3530_data *drvdata;
bb982009d   Kim, Milo   leds-lm3530: supp...
365
366
  	struct lm3530_pwm_data *pwm;
  	u8 max_brightness;
e13d97865   Kim, Milo   leds-lm3530: repl...
367
  	int mode, err;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
368

e13d97865   Kim, Milo   leds-lm3530: repl...
369
  	drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
bb982009d   Kim, Milo   leds-lm3530: supp...
370
371
  	pwm = &drvdata->pdata->pwm_data;
  	max_brightness = led_cdev->max_brightness;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
372
373
374
375
  	mode = lm3530_get_mode_from_str(buf);
  	if (mode < 0) {
  		dev_err(dev, "Invalid mode
  ");
e0e021600   Sachin Kamat   leds-lm3530: Fix ...
376
  		return mode;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
377
  	}
bb982009d   Kim, Milo   leds-lm3530: supp...
378
379
380
381
382
  	drvdata->mode = mode;
  
  	/* set pwm to low if unnecessary */
  	if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity)
  		pwm->pwm_set_intensity(0, max_brightness);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
383
384
385
386
387
388
389
390
391
392
  
  	err = lm3530_init_registers(drvdata);
  	if (err) {
  		dev_err(dev, "Setting %s Mode failed :%d
  ", buf, err);
  		return err;
  	}
  
  	return sizeof(drvdata->mode);
  }
40b1445b1   Shreshtha Kumar Sahu   arch/arm/mach-ux5...
393
  static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
394

74c850394   Johan Hovold   leds: lm3550: fix...
395
396
397
398
399
  static struct attribute *lm3530_attrs[] = {
  	&dev_attr_mode.attr,
  	NULL
  };
  ATTRIBUTE_GROUPS(lm3530);
98ea1ea20   Bill Pemberton   leds: remove use ...
400
  static int lm3530_probe(struct i2c_client *client,
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
401
402
  			   const struct i2c_device_id *id)
  {
87aae1ea8   Jingoo Han   leds: use dev_get...
403
  	struct lm3530_platform_data *pdata = dev_get_platdata(&client->dev);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
404
405
406
407
408
409
  	struct lm3530_data *drvdata;
  	int err = 0;
  
  	if (pdata == NULL) {
  		dev_err(&client->dev, "platform data required
  ");
0b873f3d5   Bryan Wu   leds: convert LM3...
410
  		return -ENODEV;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
411
412
413
414
415
416
  	}
  
  	/* BL mode */
  	if (pdata->mode > LM3530_BL_MODE_PWM) {
  		dev_err(&client->dev, "Illegal Mode request
  ");
0b873f3d5   Bryan Wu   leds: convert LM3...
417
  		return -EINVAL;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
418
419
420
421
422
  	}
  
  	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  		dev_err(&client->dev, "I2C_FUNC_I2C not supported
  ");
0b873f3d5   Bryan Wu   leds: convert LM3...
423
  		return -EIO;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
424
  	}
0b873f3d5   Bryan Wu   leds: convert LM3...
425
426
427
428
  	drvdata = devm_kzalloc(&client->dev, sizeof(struct lm3530_data),
  				GFP_KERNEL);
  	if (drvdata == NULL)
  		return -ENOMEM;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
429
430
431
432
  
  	drvdata->mode = pdata->mode;
  	drvdata->client = client;
  	drvdata->pdata = pdata;
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
433
434
  	drvdata->brightness = LED_OFF;
  	drvdata->enable = false;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
435
436
  	drvdata->led_dev.name = LM3530_LED_DEV;
  	drvdata->led_dev.brightness_set = lm3530_brightness_set;
bbe645320   Kim, Milo   leds-lm3530: set ...
437
  	drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
74c850394   Johan Hovold   leds: lm3550: fix...
438
  	drvdata->led_dev.groups = lm3530_groups;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
439
440
  
  	i2c_set_clientdata(client, drvdata);
a47df97c9   Sachin Kamat   leds-lm3530: Use ...
441
  	drvdata->regulator = devm_regulator_get(&client->dev, "vin");
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
442
443
444
445
446
  	if (IS_ERR(drvdata->regulator)) {
  		dev_err(&client->dev, "regulator get failed
  ");
  		err = PTR_ERR(drvdata->regulator);
  		drvdata->regulator = NULL;
0b873f3d5   Bryan Wu   leds: convert LM3...
447
  		return err;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
448
  	}
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
449
450
451
452
453
454
  	if (drvdata->pdata->brt_val) {
  		err = lm3530_init_registers(drvdata);
  		if (err < 0) {
  			dev_err(&client->dev,
  				"Register Init failed: %d
  ", err);
e0e021600   Sachin Kamat   leds-lm3530: Fix ...
455
  			return err;
9b2da53f7   Shreshtha Kumar Sahu   drivers/leds/leds...
456
457
458
  		}
  	}
  	err = led_classdev_register(&client->dev, &drvdata->led_dev);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
459
460
461
  	if (err < 0) {
  		dev_err(&client->dev, "Register led class failed: %d
  ", err);
e0e021600   Sachin Kamat   leds-lm3530: Fix ...
462
  		return err;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
463
  	}
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
464
  	return 0;
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
465
  }
678e8a6be   Bill Pemberton   leds: remove use ...
466
  static int lm3530_remove(struct i2c_client *client)
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
467
468
  {
  	struct lm3530_data *drvdata = i2c_get_clientdata(client);
5e3b7c6b1   Axel Lin   leds: lm3530: Ens...
469
  	lm3530_led_disable(drvdata);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
470
  	led_classdev_unregister(&drvdata->led_dev);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
471
472
473
474
475
476
477
  	return 0;
  }
  
  static const struct i2c_device_id lm3530_id[] = {
  	{LM3530_NAME, 0},
  	{}
  };
d5f33d45e   Axel Lin   drivers/leds/leds...
478
  MODULE_DEVICE_TABLE(i2c, lm3530_id);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
479
480
481
  
  static struct i2c_driver lm3530_i2c_driver = {
  	.probe = lm3530_probe,
df07cf812   Bill Pemberton   leds: remove use ...
482
  	.remove = lm3530_remove,
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
483
484
485
  	.id_table = lm3530_id,
  	.driver = {
  		.name = LM3530_NAME,
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
486
487
  	},
  };
09a0d183e   Axel Lin   leds: convert led...
488
  module_i2c_driver(lm3530_i2c_driver);
b1e6b7068   Shreshtha Kumar Sahu   leds: add driver ...
489
490
491
492
  
  MODULE_DESCRIPTION("Back Light driver for LM3530");
  MODULE_LICENSE("GPL v2");
  MODULE_AUTHOR("Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>");