Blame view

drivers/regulator/pwm-regulator.c 10.6 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
aa66cc663   Chris Zhong   regulator: pwm-re...
2
3
4
5
6
7
  /*
   * Regulator driver for PWM Regulators
   *
   * Copyright (C) 2014 - STMicroelectronics Inc.
   *
   * Author: Lee Jones <lee.jones@linaro.org>
aa66cc663   Chris Zhong   regulator: pwm-re...
8
9
10
11
12
13
14
15
16
17
18
   */
  
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/err.h>
  #include <linux/regulator/driver.h>
  #include <linux/regulator/machine.h>
  #include <linux/regulator/of_regulator.h>
  #include <linux/of.h>
  #include <linux/of_device.h>
  #include <linux/pwm.h>
27bfa8893   Alexandre Courbot   regulator: pwm: S...
19
  #include <linux/gpio/consumer.h>
aa66cc663   Chris Zhong   regulator: pwm-re...
20

ea398e287   Boris Brezillon   regulator: pwm: S...
21
22
23
24
25
  struct pwm_continuous_reg_data {
  	unsigned int min_uV_dutycycle;
  	unsigned int max_uV_dutycycle;
  	unsigned int dutycycle_unit;
  };
aa66cc663   Chris Zhong   regulator: pwm-re...
26
  struct pwm_regulator_data {
4773be185   Lee Jones   regulator: pwm-re...
27
  	/*  Shared */
aa66cc663   Chris Zhong   regulator: pwm-re...
28
  	struct pwm_device *pwm;
4773be185   Lee Jones   regulator: pwm-re...
29
30
31
  
  	/* Voltage table */
  	struct pwm_voltages *duty_cycle_table;
f907a0a94   Laxman Dewangan   regulator: pwm: A...
32

ea398e287   Boris Brezillon   regulator: pwm: S...
33
34
  	/* Continuous mode info */
  	struct pwm_continuous_reg_data continuous;
f907a0a94   Laxman Dewangan   regulator: pwm: A...
35
36
  	/* regulator descriptor */
  	struct regulator_desc desc;
aa66cc663   Chris Zhong   regulator: pwm-re...
37
  	int state;
4773be185   Lee Jones   regulator: pwm-re...
38

27bfa8893   Alexandre Courbot   regulator: pwm: S...
39
40
  	/* Enable GPIO */
  	struct gpio_desc *enb_gpio;
aa66cc663   Chris Zhong   regulator: pwm-re...
41
42
43
44
45
46
  };
  
  struct pwm_voltages {
  	unsigned int uV;
  	unsigned int dutycycle;
  };
4e773e739   Lee Jones   regulator: pwm-re...
47
  /*
4773be185   Lee Jones   regulator: pwm-re...
48
49
   * Voltage table call-backs
   */
87248991a   Boris Brezillon   regulator: pwm: P...
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  static void pwm_regulator_init_state(struct regulator_dev *rdev)
  {
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
  	struct pwm_state pwm_state;
  	unsigned int dutycycle;
  	int i;
  
  	pwm_get_state(drvdata->pwm, &pwm_state);
  	dutycycle = pwm_get_relative_duty_cycle(&pwm_state, 100);
  
  	for (i = 0; i < rdev->desc->n_voltages; i++) {
  		if (dutycycle == drvdata->duty_cycle_table[i].dutycycle) {
  			drvdata->state = i;
  			return;
  		}
  	}
  }
ab101e354   Lee Jones   regulator: pwm-re...
67
  static int pwm_regulator_get_voltage_sel(struct regulator_dev *rdev)
aa66cc663   Chris Zhong   regulator: pwm-re...
68
  {
ab101e354   Lee Jones   regulator: pwm-re...
69
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
aa66cc663   Chris Zhong   regulator: pwm-re...
70

87248991a   Boris Brezillon   regulator: pwm: P...
71
72
  	if (drvdata->state < 0)
  		pwm_regulator_init_state(rdev);
aa66cc663   Chris Zhong   regulator: pwm-re...
73
74
  	return drvdata->state;
  }
ab101e354   Lee Jones   regulator: pwm-re...
75
  static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
aa66cc663   Chris Zhong   regulator: pwm-re...
76
77
  					 unsigned selector)
  {
ab101e354   Lee Jones   regulator: pwm-re...
78
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
3f4eb39be   Boris Brezillon   regulator: pwm: S...
79
  	struct pwm_state pstate;
aa66cc663   Chris Zhong   regulator: pwm-re...
80
  	int ret;
3f4eb39be   Boris Brezillon   regulator: pwm: S...
81
82
83
  	pwm_init_state(drvdata->pwm, &pstate);
  	pwm_set_relative_duty_cycle(&pstate,
  			drvdata->duty_cycle_table[selector].dutycycle, 100);
aa66cc663   Chris Zhong   regulator: pwm-re...
84

3f4eb39be   Boris Brezillon   regulator: pwm: S...
85
  	ret = pwm_apply_state(drvdata->pwm, &pstate);
aa66cc663   Chris Zhong   regulator: pwm-re...
86
  	if (ret) {
5bf59bd5e   Laxman Dewangan   regulator: pwm: P...
87
88
  		dev_err(&rdev->dev, "Failed to configure PWM: %d
  ", ret);
aa66cc663   Chris Zhong   regulator: pwm-re...
89
90
91
92
  		return ret;
  	}
  
  	drvdata->state = selector;
aa66cc663   Chris Zhong   regulator: pwm-re...
93
94
  	return 0;
  }
ab101e354   Lee Jones   regulator: pwm-re...
95
  static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
aa66cc663   Chris Zhong   regulator: pwm-re...
96
97
  				      unsigned selector)
  {
ab101e354   Lee Jones   regulator: pwm-re...
98
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
aa66cc663   Chris Zhong   regulator: pwm-re...
99

ab101e354   Lee Jones   regulator: pwm-re...
100
  	if (selector >= rdev->desc->n_voltages)
aa66cc663   Chris Zhong   regulator: pwm-re...
101
102
103
104
  		return -EINVAL;
  
  	return drvdata->duty_cycle_table[selector].uV;
  }
4773be185   Lee Jones   regulator: pwm-re...
105

1de7d8024   Boris Brezillon   regulator: pwm: i...
106
107
108
  static int pwm_regulator_enable(struct regulator_dev *dev)
  {
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
a4aae5afc   Fabio Estevam   regulator: pwm-re...
109
  	gpiod_set_value_cansleep(drvdata->enb_gpio, 1);
27bfa8893   Alexandre Courbot   regulator: pwm: S...
110

1de7d8024   Boris Brezillon   regulator: pwm: i...
111
112
113
114
115
116
117
118
  	return pwm_enable(drvdata->pwm);
  }
  
  static int pwm_regulator_disable(struct regulator_dev *dev)
  {
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
  
  	pwm_disable(drvdata->pwm);
a4aae5afc   Fabio Estevam   regulator: pwm-re...
119
  	gpiod_set_value_cansleep(drvdata->enb_gpio, 0);
27bfa8893   Alexandre Courbot   regulator: pwm: S...
120

1de7d8024   Boris Brezillon   regulator: pwm: i...
121
122
123
124
125
126
  	return 0;
  }
  
  static int pwm_regulator_is_enabled(struct regulator_dev *dev)
  {
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
27bfa8893   Alexandre Courbot   regulator: pwm: S...
127
128
  	if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio))
  		return false;
1de7d8024   Boris Brezillon   regulator: pwm: i...
129
130
  	return pwm_is_enabled(drvdata->pwm);
  }
4773be185   Lee Jones   regulator: pwm-re...
131
132
133
  static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
  {
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
ea398e287   Boris Brezillon   regulator: pwm: S...
134
135
136
  	unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle;
  	unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle;
  	unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
d9070fdbe   Boris Brezillon   regulator: pwm: R...
137
  	int min_uV = rdev->constraints->min_uV;
ea398e287   Boris Brezillon   regulator: pwm: S...
138
139
  	int max_uV = rdev->constraints->max_uV;
  	int diff_uV = max_uV - min_uV;
d9070fdbe   Boris Brezillon   regulator: pwm: R...
140
  	struct pwm_state pstate;
ea398e287   Boris Brezillon   regulator: pwm: S...
141
142
  	unsigned int diff_duty;
  	unsigned int voltage;
4773be185   Lee Jones   regulator: pwm-re...
143

d9070fdbe   Boris Brezillon   regulator: pwm: R...
144
  	pwm_get_state(drvdata->pwm, &pstate);
ea398e287   Boris Brezillon   regulator: pwm: S...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  	voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit);
  
  	/*
  	 * The dutycycle for min_uV might be greater than the one for max_uV.
  	 * This is happening when the user needs an inversed polarity, but the
  	 * PWM device does not support inversing it in hardware.
  	 */
  	if (max_uV_duty < min_uV_duty) {
  		voltage = min_uV_duty - voltage;
  		diff_duty = min_uV_duty - max_uV_duty;
  	} else {
  		voltage = voltage - min_uV_duty;
  		diff_duty = max_uV_duty - min_uV_duty;
  	}
  
  	voltage = DIV_ROUND_CLOSEST_ULL((u64)voltage * diff_uV, diff_duty);
  
  	return voltage + min_uV;
4773be185   Lee Jones   regulator: pwm-re...
163
164
165
  }
  
  static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
ea398e287   Boris Brezillon   regulator: pwm: S...
166
167
  				     int req_min_uV, int req_max_uV,
  				     unsigned int *selector)
4773be185   Lee Jones   regulator: pwm-re...
168
169
  {
  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
ea398e287   Boris Brezillon   regulator: pwm: S...
170
171
172
  	unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle;
  	unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle;
  	unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
ea398e287   Boris Brezillon   regulator: pwm: S...
173
174
175
  	int min_uV = rdev->constraints->min_uV;
  	int max_uV = rdev->constraints->max_uV;
  	int diff_uV = max_uV - min_uV;
3f4eb39be   Boris Brezillon   regulator: pwm: S...
176
  	struct pwm_state pstate;
ea398e287   Boris Brezillon   regulator: pwm: S...
177
178
  	unsigned int diff_duty;
  	unsigned int dutycycle;
4773be185   Lee Jones   regulator: pwm-re...
179
  	int ret;
3f4eb39be   Boris Brezillon   regulator: pwm: S...
180
  	pwm_init_state(drvdata->pwm, &pstate);
fd786fb02   Laxman Dewangan   regulator: pwm: T...
181

ea398e287   Boris Brezillon   regulator: pwm: S...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  	/*
  	 * The dutycycle for min_uV might be greater than the one for max_uV.
  	 * This is happening when the user needs an inversed polarity, but the
  	 * PWM device does not support inversing it in hardware.
  	 */
  	if (max_uV_duty < min_uV_duty)
  		diff_duty = min_uV_duty - max_uV_duty;
  	else
  		diff_duty = max_uV_duty - min_uV_duty;
  
  	dutycycle = DIV_ROUND_CLOSEST_ULL((u64)(req_min_uV - min_uV) *
  					  diff_duty,
  					  diff_uV);
  
  	if (max_uV_duty < min_uV_duty)
  		dutycycle = min_uV_duty - dutycycle;
  	else
  		dutycycle = min_uV_duty + dutycycle;
  
  	pwm_set_relative_duty_cycle(&pstate, dutycycle, duty_unit);
4773be185   Lee Jones   regulator: pwm-re...
202

3f4eb39be   Boris Brezillon   regulator: pwm: S...
203
  	ret = pwm_apply_state(drvdata->pwm, &pstate);
4773be185   Lee Jones   regulator: pwm-re...
204
  	if (ret) {
5bf59bd5e   Laxman Dewangan   regulator: pwm: P...
205
206
  		dev_err(&rdev->dev, "Failed to configure PWM: %d
  ", ret);
4773be185   Lee Jones   regulator: pwm-re...
207
208
  		return ret;
  	}
4773be185   Lee Jones   regulator: pwm-re...
209
210
  	return 0;
  }
638aef7a7   Axel Lin   regulator: pwm: N...
211
  static const struct regulator_ops pwm_regulator_voltage_table_ops = {
aa66cc663   Chris Zhong   regulator: pwm-re...
212
213
214
215
  	.set_voltage_sel = pwm_regulator_set_voltage_sel,
  	.get_voltage_sel = pwm_regulator_get_voltage_sel,
  	.list_voltage    = pwm_regulator_list_voltage,
  	.map_voltage     = regulator_map_voltage_iterate,
1de7d8024   Boris Brezillon   regulator: pwm: i...
216
217
218
  	.enable          = pwm_regulator_enable,
  	.disable         = pwm_regulator_disable,
  	.is_enabled      = pwm_regulator_is_enabled,
aa66cc663   Chris Zhong   regulator: pwm-re...
219
  };
638aef7a7   Axel Lin   regulator: pwm: N...
220
  static const struct regulator_ops pwm_regulator_voltage_continuous_ops = {
4773be185   Lee Jones   regulator: pwm-re...
221
222
  	.get_voltage = pwm_regulator_get_voltage,
  	.set_voltage = pwm_regulator_set_voltage,
1de7d8024   Boris Brezillon   regulator: pwm: i...
223
224
225
  	.enable          = pwm_regulator_enable,
  	.disable         = pwm_regulator_disable,
  	.is_enabled      = pwm_regulator_is_enabled,
4773be185   Lee Jones   regulator: pwm-re...
226
  };
638aef7a7   Axel Lin   regulator: pwm: N...
227
  static const struct regulator_desc pwm_regulator_desc = {
aa66cc663   Chris Zhong   regulator: pwm-re...
228
  	.name		= "pwm-regulator",
aa66cc663   Chris Zhong   regulator: pwm-re...
229
230
231
232
  	.type		= REGULATOR_VOLTAGE,
  	.owner		= THIS_MODULE,
  	.supply_name    = "pwm",
  };
f9178dad6   Lee Jones   regulator: pwm-re...
233
234
235
236
237
  static int pwm_regulator_init_table(struct platform_device *pdev,
  				    struct pwm_regulator_data *drvdata)
  {
  	struct device_node *np = pdev->dev.of_node;
  	struct pwm_voltages *duty_cycle_table;
60cb65ebf   Lee Jones   regulator: pwm-re...
238
  	unsigned int length = 0;
f9178dad6   Lee Jones   regulator: pwm-re...
239
240
241
242
243
244
  	int ret;
  
  	of_find_property(np, "voltage-table", &length);
  
  	if ((length < sizeof(*duty_cycle_table)) ||
  	    (length % sizeof(*duty_cycle_table))) {
5bf59bd5e   Laxman Dewangan   regulator: pwm: P...
245
246
  		dev_err(&pdev->dev, "voltage-table length(%d) is invalid
  ",
f9178dad6   Lee Jones   regulator: pwm-re...
247
248
249
250
251
252
253
254
255
256
257
258
  			length);
  		return -EINVAL;
  	}
  
  	duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
  	if (!duty_cycle_table)
  		return -ENOMEM;
  
  	ret = of_property_read_u32_array(np, "voltage-table",
  					 (u32 *)duty_cycle_table,
  					 length / sizeof(u32));
  	if (ret) {
5bf59bd5e   Laxman Dewangan   regulator: pwm: P...
259
260
  		dev_err(&pdev->dev, "Failed to read voltage-table: %d
  ", ret);
f9178dad6   Lee Jones   regulator: pwm-re...
261
262
  		return ret;
  	}
59ae97a7a   Vincent Whitchurch   regulator: pwm: F...
263
  	drvdata->state			= -ENOTRECOVERABLE;
f9178dad6   Lee Jones   regulator: pwm-re...
264
  	drvdata->duty_cycle_table	= duty_cycle_table;
638aef7a7   Axel Lin   regulator: pwm: N...
265
  	drvdata->desc.ops = &pwm_regulator_voltage_table_ops;
f907a0a94   Laxman Dewangan   regulator: pwm: A...
266
  	drvdata->desc.n_voltages	= length / sizeof(*duty_cycle_table);
f9178dad6   Lee Jones   regulator: pwm-re...
267
268
269
  
  	return 0;
  }
4773be185   Lee Jones   regulator: pwm-re...
270
271
272
  static int pwm_regulator_init_continuous(struct platform_device *pdev,
  					 struct pwm_regulator_data *drvdata)
  {
ea398e287   Boris Brezillon   regulator: pwm: S...
273
274
  	u32 dutycycle_range[2] = { 0, 100 };
  	u32 dutycycle_unit = 100;
638aef7a7   Axel Lin   regulator: pwm: N...
275
  	drvdata->desc.ops = &pwm_regulator_voltage_continuous_ops;
f907a0a94   Laxman Dewangan   regulator: pwm: A...
276
  	drvdata->desc.continuous_voltage_range = true;
4773be185   Lee Jones   regulator: pwm-re...
277

ea398e287   Boris Brezillon   regulator: pwm: S...
278
279
280
281
282
283
284
285
286
287
288
289
290
  	of_property_read_u32_array(pdev->dev.of_node,
  				   "pwm-dutycycle-range",
  				   dutycycle_range, 2);
  	of_property_read_u32(pdev->dev.of_node, "pwm-dutycycle-unit",
  			     &dutycycle_unit);
  
  	if (dutycycle_range[0] > dutycycle_unit ||
  	    dutycycle_range[1] > dutycycle_unit)
  		return -EINVAL;
  
  	drvdata->continuous.dutycycle_unit = dutycycle_unit;
  	drvdata->continuous.min_uV_dutycycle = dutycycle_range[0];
  	drvdata->continuous.max_uV_dutycycle = dutycycle_range[1];
4773be185   Lee Jones   regulator: pwm-re...
291
292
  	return 0;
  }
aa66cc663   Chris Zhong   regulator: pwm-re...
293
294
  static int pwm_regulator_probe(struct platform_device *pdev)
  {
5ad2cb14f   Lee Jones   regulator: pwm-re...
295
  	const struct regulator_init_data *init_data;
aa66cc663   Chris Zhong   regulator: pwm-re...
296
  	struct pwm_regulator_data *drvdata;
aa66cc663   Chris Zhong   regulator: pwm-re...
297
298
299
  	struct regulator_dev *regulator;
  	struct regulator_config config = { };
  	struct device_node *np = pdev->dev.of_node;
27bfa8893   Alexandre Courbot   regulator: pwm: S...
300
  	enum gpiod_flags gpio_flags;
f9178dad6   Lee Jones   regulator: pwm-re...
301
  	int ret;
aa66cc663   Chris Zhong   regulator: pwm-re...
302
303
304
305
306
307
308
309
310
311
  
  	if (!np) {
  		dev_err(&pdev->dev, "Device Tree node missing
  ");
  		return -EINVAL;
  	}
  
  	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
  	if (!drvdata)
  		return -ENOMEM;
f907a0a94   Laxman Dewangan   regulator: pwm: A...
312
  	memcpy(&drvdata->desc, &pwm_regulator_desc, sizeof(drvdata->desc));
4773be185   Lee Jones   regulator: pwm-re...
313
  	if (of_find_property(np, "voltage-table", NULL))
f9178dad6   Lee Jones   regulator: pwm-re...
314
  		ret = pwm_regulator_init_table(pdev, drvdata);
4773be185   Lee Jones   regulator: pwm-re...
315
316
317
318
  	else
  		ret = pwm_regulator_init_continuous(pdev, drvdata);
  	if (ret)
  		return ret;
aa66cc663   Chris Zhong   regulator: pwm-re...
319

5ad2cb14f   Lee Jones   regulator: pwm-re...
320
  	init_data = of_get_regulator_init_data(&pdev->dev, np,
f907a0a94   Laxman Dewangan   regulator: pwm: A...
321
  					       &drvdata->desc);
5ad2cb14f   Lee Jones   regulator: pwm-re...
322
  	if (!init_data)
aa66cc663   Chris Zhong   regulator: pwm-re...
323
324
325
326
327
  		return -ENOMEM;
  
  	config.of_node = np;
  	config.dev = &pdev->dev;
  	config.driver_data = drvdata;
5ad2cb14f   Lee Jones   regulator: pwm-re...
328
  	config.init_data = init_data;
aa66cc663   Chris Zhong   regulator: pwm-re...
329
330
331
  
  	drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
  	if (IS_ERR(drvdata->pwm)) {
5bf59bd5e   Laxman Dewangan   regulator: pwm: P...
332
  		ret = PTR_ERR(drvdata->pwm);
0cd71b9a4   Jon Hunter   regulator: pwm: D...
333
334
335
336
337
338
339
  		if (ret == -EPROBE_DEFER)
  			dev_dbg(&pdev->dev,
  				"Failed to get PWM, deferring probe
  ");
  		else
  			dev_err(&pdev->dev, "Failed to get PWM: %d
  ", ret);
5bf59bd5e   Laxman Dewangan   regulator: pwm: P...
340
  		return ret;
aa66cc663   Chris Zhong   regulator: pwm-re...
341
  	}
27bfa8893   Alexandre Courbot   regulator: pwm: S...
342
343
344
345
346
347
348
349
350
351
352
353
  	if (init_data->constraints.boot_on || init_data->constraints.always_on)
  		gpio_flags = GPIOD_OUT_HIGH;
  	else
  		gpio_flags = GPIOD_OUT_LOW;
  	drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
  						    gpio_flags);
  	if (IS_ERR(drvdata->enb_gpio)) {
  		ret = PTR_ERR(drvdata->enb_gpio);
  		dev_err(&pdev->dev, "Failed to get enable GPIO: %d
  ", ret);
  		return ret;
  	}
fd4f99c4c   Boris Brezillon   regulator: pwm: A...
354
355
356
  	ret = pwm_adjust_config(drvdata->pwm);
  	if (ret)
  		return ret;
8c12ad8e9   Boris Brezillon   regulator: pwm: U...
357

aa66cc663   Chris Zhong   regulator: pwm-re...
358
  	regulator = devm_regulator_register(&pdev->dev,
f907a0a94   Laxman Dewangan   regulator: pwm: A...
359
  					    &drvdata->desc, &config);
aa66cc663   Chris Zhong   regulator: pwm-re...
360
  	if (IS_ERR(regulator)) {
5bf59bd5e   Laxman Dewangan   regulator: pwm: P...
361
362
363
364
365
  		ret = PTR_ERR(regulator);
  		dev_err(&pdev->dev, "Failed to register regulator %s: %d
  ",
  			drvdata->desc.name, ret);
  		return ret;
aa66cc663   Chris Zhong   regulator: pwm-re...
366
367
368
369
  	}
  
  	return 0;
  }
dc8c5ea35   Jisheng Zhang   regulator: pwm: F...
370
  static const struct of_device_id __maybe_unused pwm_of_match[] = {
aa66cc663   Chris Zhong   regulator: pwm-re...
371
372
373
374
375
376
377
378
  	{ .compatible = "pwm-regulator" },
  	{ },
  };
  MODULE_DEVICE_TABLE(of, pwm_of_match);
  
  static struct platform_driver pwm_regulator_driver = {
  	.driver = {
  		.name		= "pwm-regulator",
aa66cc663   Chris Zhong   regulator: pwm-re...
379
380
381
382
383
384
385
386
387
388
389
  		.of_match_table = of_match_ptr(pwm_of_match),
  	},
  	.probe = pwm_regulator_probe,
  };
  
  module_platform_driver(pwm_regulator_driver);
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>");
  MODULE_DESCRIPTION("PWM Regulator Driver");
  MODULE_ALIAS("platform:pwm-regulator");