blob: ea0d8768b6329e221f839c96ae22fbd6896bd93a [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. 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 * Qualcomm PM8XXX Pulse Width Modulation (PWM) driver
14 *
15 * The HW module is also called LPG (Light Pulse Generator).
16 */
17
18#define pr_fmt(fmt) "%s: " fmt, __func__
19
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/err.h>
24#include <linux/debugfs.h>
25#include <linux/mfd/pm8xxx/core.h>
26#include <linux/mfd/pm8xxx/pwm.h>
27
28#define PM8XXX_LPG_BANKS 8
29#define PM8XXX_PWM_CHANNELS PM8XXX_LPG_BANKS
30
31#define PM8XXX_LPG_CTL_REGS 7
32
33/* PM8XXX PWM */
34#define SSBI_REG_ADDR_LPG_CTL_BASE 0x13C
35#define SSBI_REG_ADDR_LPG_CTL(n) (SSBI_REG_ADDR_LPG_CTL_BASE + (n))
36#define SSBI_REG_ADDR_LPG_BANK_SEL 0x143
37#define SSBI_REG_ADDR_LPG_BANK_EN 0x144
38#define SSBI_REG_ADDR_LPG_LUT_CFG0 0x145
39#define SSBI_REG_ADDR_LPG_LUT_CFG1 0x146
40
41/* Control 0 */
42#define PM8XXX_PWM_1KHZ_COUNT_MASK 0xF0
43#define PM8XXX_PWM_1KHZ_COUNT_SHIFT 4
44
45#define PM8XXX_PWM_1KHZ_COUNT_MAX 15
46
47#define PM8XXX_PWM_OUTPUT_EN 0x08
48#define PM8XXX_PWM_PWM_EN 0x04
49#define PM8XXX_PWM_RAMP_GEN_EN 0x02
50#define PM8XXX_PWM_RAMP_START 0x01
51
52#define PM8XXX_PWM_PWM_START (PM8XXX_PWM_OUTPUT_EN \
53 | PM8XXX_PWM_PWM_EN)
54#define PM8XXX_PWM_RAMP_GEN_START (PM8XXX_PWM_RAMP_GEN_EN \
55 | PM8XXX_PWM_RAMP_START)
56
57/* Control 1 */
58#define PM8XXX_PWM_REVERSE_EN 0x80
59#define PM8XXX_PWM_BYPASS_LUT 0x40
60#define PM8XXX_PWM_HIGH_INDEX_MASK 0x3F
61
62/* Control 2 */
63#define PM8XXX_PWM_LOOP_EN 0x80
64#define PM8XXX_PWM_RAMP_UP 0x40
65#define PM8XXX_PWM_LOW_INDEX_MASK 0x3F
66
67/* Control 3 */
68#define PM8XXX_PWM_VALUE_BIT7_0 0xFF
69#define PM8XXX_PWM_VALUE_BIT5_0 0x3F
70
71/* Control 4 */
72#define PM8XXX_PWM_VALUE_BIT8 0x80
73
74#define PM8XXX_PWM_CLK_SEL_MASK 0x60
75#define PM8XXX_PWM_CLK_SEL_SHIFT 5
76
77#define PM8XXX_PWM_CLK_SEL_NO 0
78#define PM8XXX_PWM_CLK_SEL_1KHZ 1
79#define PM8XXX_PWM_CLK_SEL_32KHZ 2
80#define PM8XXX_PWM_CLK_SEL_19P2MHZ 3
81
82#define PM8XXX_PWM_PREDIVIDE_MASK 0x18
83#define PM8XXX_PWM_PREDIVIDE_SHIFT 3
84
85#define PM8XXX_PWM_PREDIVIDE_2 0
86#define PM8XXX_PWM_PREDIVIDE_3 1
87#define PM8XXX_PWM_PREDIVIDE_5 2
88#define PM8XXX_PWM_PREDIVIDE_6 3
89
90#define PM8XXX_PWM_M_MASK 0x07
91#define PM8XXX_PWM_M_MIN 0
92#define PM8XXX_PWM_M_MAX 7
93
94/* Control 5 */
95#define PM8XXX_PWM_PAUSE_COUNT_HI_MASK 0xFC
96#define PM8XXX_PWM_PAUSE_COUNT_HI_SHIFT 2
97
98#define PM8XXX_PWM_PAUSE_ENABLE_HIGH 0x02
99#define PM8XXX_PWM_SIZE_9_BIT 0x01
100
101/* Control 6 */
102#define PM8XXX_PWM_PAUSE_COUNT_LO_MASK 0xFC
103#define PM8XXX_PWM_PAUSE_COUNT_LO_SHIFT 2
104
105#define PM8XXX_PWM_PAUSE_ENABLE_LOW 0x02
106#define PM8XXX_PWM_RESERVED 0x01
107
108#define PM8XXX_PWM_PAUSE_COUNT_MAX 56 /* < 2^6 = 64 */
109
110/* LUT_CFG1 */
111#define PM8XXX_PWM_LUT_READ 0x40
112
113/*
114 * PWM Frequency = Clock Frequency / (N * T)
115 * or
116 * PWM Period = Clock Period * (N * T)
117 * where
118 * N = 2^9 or 2^6 for 9-bit or 6-bit PWM size
119 * T = Pre-divide * 2^m, where m = 0..7 (exponent)
120 *
121 * This is the formula to figure out m for the best pre-divide and clock:
122 * (PWM Period / N) / 2^m = (Pre-divide * Clock Period)
123 */
124#define NUM_CLOCKS 3
125
126#define NSEC_1000HZ (NSEC_PER_SEC / 1000)
127#define NSEC_32768HZ (NSEC_PER_SEC / 32768)
128#define NSEC_19P2MHZ (NSEC_PER_SEC / 19200000)
129
130#define CLK_PERIOD_MIN NSEC_19P2MHZ
131#define CLK_PERIOD_MAX NSEC_1000HZ
132
133#define NUM_PRE_DIVIDE 3 /* No default support for pre-divide = 6 */
134
135#define PRE_DIVIDE_0 2
136#define PRE_DIVIDE_1 3
137#define PRE_DIVIDE_2 5
138
139#define PRE_DIVIDE_MIN PRE_DIVIDE_0
140#define PRE_DIVIDE_MAX PRE_DIVIDE_2
141
142static unsigned int pt_t[NUM_PRE_DIVIDE][NUM_CLOCKS] = {
143 { PRE_DIVIDE_0 * NSEC_1000HZ,
144 PRE_DIVIDE_0 * NSEC_32768HZ,
145 PRE_DIVIDE_0 * NSEC_19P2MHZ,
146 },
147 { PRE_DIVIDE_1 * NSEC_1000HZ,
148 PRE_DIVIDE_1 * NSEC_32768HZ,
149 PRE_DIVIDE_1 * NSEC_19P2MHZ,
150 },
151 { PRE_DIVIDE_2 * NSEC_1000HZ,
152 PRE_DIVIDE_2 * NSEC_32768HZ,
153 PRE_DIVIDE_2 * NSEC_19P2MHZ,
154 },
155};
156
157#define MIN_MPT ((PRE_DIVIDE_MIN * CLK_PERIOD_MIN) << PM8XXX_PWM_M_MIN)
158#define MAX_MPT ((PRE_DIVIDE_MAX * CLK_PERIOD_MAX) << PM8XXX_PWM_M_MAX)
159
160/* Private data */
161struct pm8xxx_pwm_chip;
162
163struct pwm_device {
164 int pwm_id; /* = bank/channel id */
165 int in_use;
166 const char *label;
167 int pwm_period;
168 int pwm_duty;
169 u8 pwm_ctl[PM8XXX_LPG_CTL_REGS];
170 int irq;
171 struct pm8xxx_pwm_chip *chip;
172};
173
174struct pm8xxx_pwm_chip {
175 struct pwm_device pwm_dev[PM8XXX_PWM_CHANNELS];
176 u8 bank_mask;
177 struct mutex pwm_mutex;
178 struct device *dev;
179};
180
181static struct pm8xxx_pwm_chip *pwm_chip;
182
183struct pm8xxx_pwm_config {
184 int pwm_size; /* round up to 6 or 9 for 6/9-bit PWM SIZE */
185 int clk;
186 int pre_div;
187 int pre_div_exp;
188 int pwm_value;
189 int bypass_lut;
190
191 /* LUT parameters when bypass_lut is 0 */
192 int lut_duty_ms;
193 int lut_lo_index;
194 int lut_hi_index;
195 int lut_pause_hi;
196 int lut_pause_lo;
197 int flags;
198};
199
200static const u16 duty_msec[PM8XXX_PWM_1KHZ_COUNT_MAX + 1] = {
201 0, 1, 2, 3, 4, 6, 8, 16, 18, 24, 32, 36, 64, 128, 256, 512
202};
203
204static const u16 pause_count[PM8XXX_PWM_PAUSE_COUNT_MAX + 1] = {
205 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
206 23, 28, 31, 42, 47, 56, 63, 83, 94, 111, 125, 167, 188, 222, 250, 333,
207 375, 500, 667, 750, 800, 900, 1000, 1100,
208 1200, 1300, 1400, 1500, 1600, 1800, 2000, 2500,
209 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6500,
210 7000
211};
212
213/* Internal functions */
214static int pm8xxx_pwm_bank_enable(struct pwm_device *pwm, int enable)
215{
216 int rc;
217 u8 reg;
218 struct pm8xxx_pwm_chip *chip;
219
220 chip = pwm->chip;
221
222 if (enable)
223 reg = chip->bank_mask | (1 << pwm->pwm_id);
224 else
225 reg = chip->bank_mask & ~(1 << pwm->pwm_id);
226
227 rc = pm8xxx_writeb(chip->dev->parent, SSBI_REG_ADDR_LPG_BANK_EN, reg);
228 if (rc) {
229 pr_err("pm8xxx_write(): rc=%d (Enable LPG Bank)\n", rc);
230 return rc;
231 }
232 chip->bank_mask = reg;
233
234 return 0;
235}
236
237static int pm8xxx_pwm_bank_sel(struct pwm_device *pwm)
238{
239 int rc;
240
241 rc = pm8xxx_writeb(pwm->chip->dev->parent, SSBI_REG_ADDR_LPG_BANK_SEL,
242 pwm->pwm_id);
243 if (rc)
244 pr_err("pm8xxx_write(): rc=%d (Select PWM Bank)\n", rc);
245 return rc;
246}
247
248static int pm8xxx_pwm_start(struct pwm_device *pwm, int start, int ramp_start)
249{
250 int rc;
251 u8 reg;
252
253 if (start) {
254 reg = pwm->pwm_ctl[0] | PM8XXX_PWM_PWM_START;
255 if (ramp_start)
256 reg |= PM8XXX_PWM_RAMP_GEN_START;
257 else
258 reg &= ~PM8XXX_PWM_RAMP_GEN_START;
259 } else {
260 reg = pwm->pwm_ctl[0] & ~PM8XXX_PWM_PWM_START;
261 reg &= ~PM8XXX_PWM_RAMP_GEN_START;
262 }
263
264 rc = pm8xxx_writeb(pwm->chip->dev->parent, SSBI_REG_ADDR_LPG_CTL(0),
265 reg);
266 if (rc)
267 pr_err("pm8xxx_write(): rc=%d (Enable PWM Ctl 0)\n", rc);
268 else
269 pwm->pwm_ctl[0] = reg;
270 return rc;
271}
272
273static void pm8xxx_pwm_calc_period(unsigned int period_us,
274 struct pm8xxx_pwm_config *pwm_conf)
275{
276 int n, m, clk, div;
277 int best_m, best_div, best_clk;
278 int last_err, cur_err, better_err, better_m;
279 unsigned int tmp_p, last_p, min_err, period_n;
280
281 /* PWM Period / N */
282 if (period_us < (40 * USEC_PER_SEC)) { /* ~6-bit max */
283 period_n = (period_us * NSEC_PER_USEC) >> 6;
284 n = 6;
285 } else if (period_us < (274 * USEC_PER_SEC)) { /* overflow threshold */
286 period_n = (period_us >> 6) * NSEC_PER_USEC;
287 if (period_n >= MAX_MPT) {
288 n = 9;
289 period_n >>= 3;
290 } else {
291 n = 6;
292 }
293 } else {
294 period_n = (period_us >> 9) * NSEC_PER_USEC;
295 n = 9;
296 }
297
298 min_err = MAX_MPT;
299 best_m = 0;
300 best_clk = 0;
301 best_div = 0;
302 for (clk = 0; clk < NUM_CLOCKS; clk++) {
303 for (div = 0; div < NUM_PRE_DIVIDE; div++) {
304 tmp_p = period_n;
305 last_p = tmp_p;
306 for (m = 0; m <= PM8XXX_PWM_M_MAX; m++) {
307 if (tmp_p <= pt_t[div][clk]) {
308 /* Found local best */
309 if (!m) {
310 better_err = pt_t[div][clk] -
311 tmp_p;
312 better_m = m;
313 } else {
314 last_err = last_p -
315 pt_t[div][clk];
316 cur_err = pt_t[div][clk] -
317 tmp_p;
318
319 if (cur_err < last_err) {
320 better_err = cur_err;
321 better_m = m;
322 } else {
323 better_err = last_err;
324 better_m = m - 1;
325 }
326 }
327
328 if (better_err < min_err) {
329 min_err = better_err;
330 best_m = better_m;
331 best_clk = clk;
332 best_div = div;
333 }
334 break;
335 } else {
336 last_p = tmp_p;
337 tmp_p >>= 1;
338 }
339 }
340 }
341 }
342
Willie Ruan75d9e5b2011-08-25 10:59:17 -0700343 /* Use higher resolution */
344 if (best_m >= 3 && n == 6) {
345 n += 3;
346 best_m -= 3;
347 }
348
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700349 pwm_conf->pwm_size = n;
350 pwm_conf->clk = best_clk;
351 pwm_conf->pre_div = best_div;
352 pwm_conf->pre_div_exp = best_m;
353}
354
355static int pm8xxx_pwm_configure(struct pwm_device *pwm,
356 struct pm8xxx_pwm_config *pwm_conf)
357{
358 int i, rc, len;
359 u8 reg, ramp_enabled = 0;
360
361 reg = (pwm_conf->pwm_size > 6) ? PM8XXX_PWM_SIZE_9_BIT : 0;
362 pwm->pwm_ctl[5] = reg;
363
364 reg = ((pwm_conf->clk + 1) << PM8XXX_PWM_CLK_SEL_SHIFT)
365 & PM8XXX_PWM_CLK_SEL_MASK;
366 reg |= (pwm_conf->pre_div << PM8XXX_PWM_PREDIVIDE_SHIFT)
367 & PM8XXX_PWM_PREDIVIDE_MASK;
368 reg |= pwm_conf->pre_div_exp & PM8XXX_PWM_M_MASK;
369 pwm->pwm_ctl[4] = reg;
370
371 if (pwm_conf->bypass_lut) {
372 pwm->pwm_ctl[0] &= PM8XXX_PWM_PWM_START; /* keep enabled */
373 pwm->pwm_ctl[1] = PM8XXX_PWM_BYPASS_LUT;
374 pwm->pwm_ctl[2] = 0;
375
376 if (pwm_conf->pwm_size > 6) {
377 pwm->pwm_ctl[3] = pwm_conf->pwm_value
378 & PM8XXX_PWM_VALUE_BIT7_0;
379 pwm->pwm_ctl[4] |= (pwm_conf->pwm_value >> 1)
380 & PM8XXX_PWM_VALUE_BIT8;
381 } else {
382 pwm->pwm_ctl[3] = pwm_conf->pwm_value
383 & PM8XXX_PWM_VALUE_BIT5_0;
384 }
385
386 len = 6;
387 } else {
388 int pause_cnt, j;
389
390 /* Linear search for duty time */
391 for (i = 0; i < PM8XXX_PWM_1KHZ_COUNT_MAX; i++) {
392 if (duty_msec[i] >= pwm_conf->lut_duty_ms)
393 break;
394 }
395
396 ramp_enabled = pwm->pwm_ctl[0] & PM8XXX_PWM_RAMP_GEN_START;
397 pwm->pwm_ctl[0] &= PM8XXX_PWM_PWM_START; /* keep enabled */
398 pwm->pwm_ctl[0] |= (i << PM8XXX_PWM_1KHZ_COUNT_SHIFT) &
399 PM8XXX_PWM_1KHZ_COUNT_MASK;
400 pwm->pwm_ctl[1] = pwm_conf->lut_hi_index &
401 PM8XXX_PWM_HIGH_INDEX_MASK;
402 pwm->pwm_ctl[2] = pwm_conf->lut_lo_index &
403 PM8XXX_PWM_LOW_INDEX_MASK;
404
405 if (pwm_conf->flags & PM_PWM_LUT_REVERSE)
406 pwm->pwm_ctl[1] |= PM8XXX_PWM_REVERSE_EN;
407 if (pwm_conf->flags & PM_PWM_LUT_RAMP_UP)
408 pwm->pwm_ctl[2] |= PM8XXX_PWM_RAMP_UP;
409 if (pwm_conf->flags & PM_PWM_LUT_LOOP)
410 pwm->pwm_ctl[2] |= PM8XXX_PWM_LOOP_EN;
411
412 /* Pause time */
413 if (pwm_conf->flags & PM_PWM_LUT_PAUSE_HI_EN) {
414 /* Linear search for pause time */
415 pause_cnt = (pwm_conf->lut_pause_hi + duty_msec[i] / 2)
416 / duty_msec[i];
417 for (j = 0; j < PM8XXX_PWM_PAUSE_COUNT_MAX; j++) {
418 if (pause_count[j] >= pause_cnt)
419 break;
420 }
421 pwm->pwm_ctl[5] |= (j <<
422 PM8XXX_PWM_PAUSE_COUNT_HI_SHIFT) &
423 PM8XXX_PWM_PAUSE_COUNT_HI_MASK;
424 pwm->pwm_ctl[5] |= PM8XXX_PWM_PAUSE_ENABLE_HIGH;
425 }
426
427 if (pwm_conf->flags & PM_PWM_LUT_PAUSE_LO_EN) {
428 /* Linear search for pause time */
429 pause_cnt = (pwm_conf->lut_pause_lo + duty_msec[i] / 2)
430 / duty_msec[i];
431 for (j = 0; j < PM8XXX_PWM_PAUSE_COUNT_MAX; j++) {
432 if (pause_count[j] >= pause_cnt)
433 break;
434 }
435 pwm->pwm_ctl[6] = (j <<
436 PM8XXX_PWM_PAUSE_COUNT_LO_SHIFT) &
437 PM8XXX_PWM_PAUSE_COUNT_LO_MASK;
438 pwm->pwm_ctl[6] |= PM8XXX_PWM_PAUSE_ENABLE_LOW;
439 } else {
440 pwm->pwm_ctl[6] = 0;
441 }
442
443 len = 7;
444 }
445
446 pm8xxx_pwm_bank_sel(pwm);
447
448 for (i = 0; i < len; i++) {
449 rc = pm8xxx_writeb(pwm->chip->dev->parent,
450 SSBI_REG_ADDR_LPG_CTL(i),
451 pwm->pwm_ctl[i]);
452 if (rc) {
453 pr_err("pm8xxx_write(): rc=%d (PWM Ctl[%d])\n", rc, i);
454 break;
455 }
456 }
457
458 if (ramp_enabled) {
459 pwm->pwm_ctl[0] |= ramp_enabled;
460 pm8xxx_writeb(pwm->chip->dev->parent,
461 SSBI_REG_ADDR_LPG_CTL(0),
462 pwm->pwm_ctl[0]);
463 }
464
465 return rc;
466}
467
468/* APIs */
469/**
470 * pwm_request - request a PWM device
471 * @pwm_id: PWM id or channel
472 * @label: the label to identify the user
473 */
474struct pwm_device *pwm_request(int pwm_id, const char *label)
475{
476 struct pwm_device *pwm;
477
478 if (pwm_id > PM8XXX_PWM_CHANNELS || pwm_id < 0) {
479 pr_err("Invalid pwm_id: %d with %s\n",
480 pwm_id, label ? label : ".");
481 return ERR_PTR(-EINVAL);
482 }
483 if (pwm_chip == NULL) {
484 pr_err("No pwm_chip\n");
485 return ERR_PTR(-ENODEV);
486 }
487
488 mutex_lock(&pwm_chip->pwm_mutex);
489 pwm = &pwm_chip->pwm_dev[pwm_id];
490 if (!pwm->in_use) {
491 pwm->in_use = 1;
492 pwm->label = label;
493 } else {
494 pwm = ERR_PTR(-EBUSY);
495 }
496 mutex_unlock(&pwm_chip->pwm_mutex);
497
498 return pwm;
499}
500EXPORT_SYMBOL_GPL(pwm_request);
501
502/**
503 * pwm_free - free a PWM device
504 * @pwm: the PWM device
505 */
506void pwm_free(struct pwm_device *pwm)
507{
508 if (pwm == NULL || IS_ERR(pwm) || pwm->chip == NULL) {
509 pr_err("Invalid pwm handle\n");
510 return;
511 }
512
513 mutex_lock(&pwm->chip->pwm_mutex);
514 if (pwm->in_use) {
515 pm8xxx_pwm_bank_sel(pwm);
516 pm8xxx_pwm_start(pwm, 0, 0);
517
518 pwm->in_use = 0;
519 pwm->label = NULL;
520 }
521 pm8xxx_pwm_bank_enable(pwm, 0);
522 mutex_unlock(&pwm->chip->pwm_mutex);
523}
524EXPORT_SYMBOL_GPL(pwm_free);
525
526/**
527 * pwm_config - change a PWM device configuration
528 * @pwm: the PWM device
529 * @period_us: period in microseconds
530 * @duty_us: duty cycle in microseconds
531 */
532int pwm_config(struct pwm_device *pwm, int duty_us, int period_us)
533{
534 struct pm8xxx_pwm_config pwm_conf;
535 unsigned int max_pwm_value, tmp;
536 int rc;
537
538 if (pwm == NULL || IS_ERR(pwm) ||
539 duty_us > period_us ||
540 (unsigned)period_us > PM8XXX_PWM_PERIOD_MAX ||
541 (unsigned)period_us < PM8XXX_PWM_PERIOD_MIN) {
542 pr_err("Invalid pwm handle or parameters\n");
543 return -EINVAL;
544 }
545 if (pwm->chip == NULL) {
546 pr_err("No pwm_chip\n");
547 return -ENODEV;
548 }
549
550 mutex_lock(&pwm->chip->pwm_mutex);
551
552 if (!pwm->in_use) {
553 pr_err("pwm_id: %d: stale handle?\n", pwm->pwm_id);
554 rc = -EINVAL;
555 goto out_unlock;
556 }
557
558 pm8xxx_pwm_calc_period(period_us, &pwm_conf);
559
560 /* Figure out pwm_value with overflow handling */
561 if ((unsigned)period_us > (1 << pwm_conf.pwm_size)) {
562 tmp = period_us;
563 tmp >>= pwm_conf.pwm_size;
564 pwm_conf.pwm_value = (unsigned)duty_us / tmp;
565 } else {
566 tmp = duty_us;
567 tmp <<= pwm_conf.pwm_size;
568 pwm_conf.pwm_value = tmp / (unsigned)period_us;
569 }
570 max_pwm_value = (1 << pwm_conf.pwm_size) - 1;
571 if (pwm_conf.pwm_value > max_pwm_value)
572 pwm_conf.pwm_value = max_pwm_value;
573
574 pwm_conf.bypass_lut = 1;
575
576 rc = pm8xxx_pwm_configure(pwm, &pwm_conf);
577
578out_unlock:
579 mutex_unlock(&pwm->chip->pwm_mutex);
580 return rc;
581}
582EXPORT_SYMBOL_GPL(pwm_config);
583
584/**
585 * pwm_enable - start a PWM output toggling
586 * @pwm: the PWM device
587 */
588int pwm_enable(struct pwm_device *pwm)
589{
590 int rc;
591
592 if (pwm == NULL || IS_ERR(pwm)) {
593 pr_err("Invalid pwm handle\n");
594 return -EINVAL;
595 }
596 if (pwm->chip == NULL) {
597 pr_err("No pwm_chip\n");
598 return -ENODEV;
599 }
600
601 mutex_lock(&pwm->chip->pwm_mutex);
602 if (!pwm->in_use) {
603 pr_err("pwm_id: %d: stale handle?\n", pwm->pwm_id);
604 rc = -EINVAL;
605 } else {
606 rc = pm8xxx_pwm_bank_enable(pwm, 1);
607
608 pm8xxx_pwm_bank_sel(pwm);
609 pm8xxx_pwm_start(pwm, 1, 0);
610 }
611 mutex_unlock(&pwm->chip->pwm_mutex);
612 return rc;
613}
614EXPORT_SYMBOL_GPL(pwm_enable);
615
616/**
617 * pwm_disable - stop a PWM output toggling
618 * @pwm: the PWM device
619 */
620void pwm_disable(struct pwm_device *pwm)
621{
622 if (pwm == NULL || IS_ERR(pwm) || pwm->chip == NULL) {
623 pr_err("Invalid pwm handle or no pwm_chip\n");
624 return;
625 }
626
627 mutex_lock(&pwm->chip->pwm_mutex);
628 if (pwm->in_use) {
629 pm8xxx_pwm_bank_sel(pwm);
630 pm8xxx_pwm_start(pwm, 0, 0);
631
632 pm8xxx_pwm_bank_enable(pwm, 0);
633 }
634 mutex_unlock(&pwm->chip->pwm_mutex);
635}
636EXPORT_SYMBOL_GPL(pwm_disable);
637
638/**
639 * pm8xxx_pwm_lut_config - change a PWM device configuration to use LUT
640 * @pwm: the PWM device
641 * @period_us: period in microseconds
642 * @duty_pct: arrary of duty cycles in percent, like 20, 50.
643 * @duty_time_ms: time for each duty cycle in milliseconds
644 * @start_idx: start index in lookup table from 0 to MAX-1
645 * @idx_len: number of index
646 * @pause_lo: pause time in milliseconds at low index
647 * @pause_hi: pause time in milliseconds at high index
648 * @flags: control flags
649 */
650int pm8xxx_pwm_lut_config(struct pwm_device *pwm, int period_us,
651 int duty_pct[], int duty_time_ms, int start_idx,
652 int idx_len, int pause_lo, int pause_hi, int flags)
653{
654 struct pm8xxx_pwm_config pwm_conf;
655 unsigned int pwm_value, max_pwm_value;
656 u8 cfg0, cfg1;
657 int i, len;
658 int rc;
659
660 if (pwm == NULL || IS_ERR(pwm) || !idx_len) {
661 pr_err("Invalid pwm handle or idx_len=0\n");
662 return -EINVAL;
663 }
664 if (duty_pct == NULL && !(flags & PM_PWM_LUT_NO_TABLE)) {
665 pr_err("Invalid duty_pct with flag\n");
666 return -EINVAL;
667 }
668 if (pwm->chip == NULL) {
669 pr_err("No pwm_chip\n");
670 return -ENODEV;
671 }
672 if (idx_len >= PM_PWM_LUT_SIZE && start_idx) {
673 pr_err("Wrong LUT size or index\n");
674 return -EINVAL;
675 }
676 if ((start_idx + idx_len) > PM_PWM_LUT_SIZE) {
677 pr_err("Exceed LUT limit\n");
678 return -EINVAL;
679 }
680 if ((unsigned)period_us > PM8XXX_PWM_PERIOD_MAX ||
681 (unsigned)period_us < PM8XXX_PWM_PERIOD_MIN) {
682 pr_err("Period out of range\n");
683 return -EINVAL;
684 }
685
686 mutex_lock(&pwm->chip->pwm_mutex);
687
688 if (!pwm->in_use) {
689 pr_err("pwm_id: %d: stale handle?\n", pwm->pwm_id);
690 rc = -EINVAL;
691 goto out_unlock;
692 }
693
694 pm8xxx_pwm_calc_period(period_us, &pwm_conf);
695
696 len = (idx_len > PM_PWM_LUT_SIZE) ? PM_PWM_LUT_SIZE : idx_len;
697
698 if (flags & PM_PWM_LUT_NO_TABLE)
699 goto after_table_write;
700
701 max_pwm_value = (1 << pwm_conf.pwm_size) - 1;
702 for (i = 0; i < len; i++) {
703 pwm_value = (duty_pct[i] << pwm_conf.pwm_size) / 100;
704 /* Avoid overflow */
705 if (pwm_value > max_pwm_value)
706 pwm_value = max_pwm_value;
707 cfg0 = pwm_value & 0xff;
708 cfg1 = (pwm_value >> 1) & 0x80;
709 cfg1 |= start_idx + i;
710
711 pm8xxx_writeb(pwm->chip->dev->parent,
712 SSBI_REG_ADDR_LPG_LUT_CFG0, cfg0);
713 pm8xxx_writeb(pwm->chip->dev->parent,
714 SSBI_REG_ADDR_LPG_LUT_CFG1, cfg1);
715 }
716
717after_table_write:
718 pwm_conf.lut_duty_ms = duty_time_ms;
719 pwm_conf.lut_lo_index = start_idx;
720 pwm_conf.lut_hi_index = start_idx + len - 1;
721 pwm_conf.lut_pause_lo = pause_lo;
722 pwm_conf.lut_pause_hi = pause_hi;
723 pwm_conf.flags = flags;
724 pwm_conf.bypass_lut = 0;
725
726 rc = pm8xxx_pwm_configure(pwm, &pwm_conf);
727
728out_unlock:
729 mutex_unlock(&pwm->chip->pwm_mutex);
730 return rc;
731}
732EXPORT_SYMBOL_GPL(pm8xxx_pwm_lut_config);
733
734/**
735 * pm8xxx_pwm_lut_enable - control a PWM device to start/stop LUT ramp
736 * @pwm: the PWM device
737 * @start: to start (1), or stop (0)
738 */
739int pm8xxx_pwm_lut_enable(struct pwm_device *pwm, int start)
740{
741 if (pwm == NULL || IS_ERR(pwm)) {
742 pr_err("Invalid pwm handle\n");
743 return -EINVAL;
744 }
745 if (pwm->chip == NULL) {
746 pr_err("No pwm_chip\n");
747 return -ENODEV;
748 }
749
750 mutex_lock(&pwm->chip->pwm_mutex);
751 if (start) {
752 pm8xxx_pwm_bank_enable(pwm, 1);
753
754 pm8xxx_pwm_bank_sel(pwm);
755 pm8xxx_pwm_start(pwm, 1, 1);
756 } else {
757 pm8xxx_pwm_bank_sel(pwm);
758 pm8xxx_pwm_start(pwm, 0, 0);
759
760 pm8xxx_pwm_bank_enable(pwm, 0);
761 }
762 mutex_unlock(&pwm->chip->pwm_mutex);
763 return 0;
764}
765EXPORT_SYMBOL_GPL(pm8xxx_pwm_lut_enable);
766
767#if defined(CONFIG_DEBUG_FS)
768
769struct pm8xxx_pwm_dbg_device;
770
771struct pm8xxx_pwm_user {
772 int pwm_id;
773 struct pwm_device *pwm;
774 int period;
775 int duty_cycle;
776 int enable;
777 struct pm8xxx_pwm_dbg_device *dbgdev;
778};
779
780struct pm8xxx_pwm_dbg_device {
781 struct mutex dbg_mutex;
782 struct device *dev;
783 struct dentry *dent;
784
785 struct pm8xxx_pwm_user user[PM8XXX_PWM_CHANNELS];
786};
787
788static struct pm8xxx_pwm_dbg_device *pmic_dbg_device;
789
790static int dbg_pwm_check_period(int period)
791{
792 if (period < PM8XXX_PWM_PERIOD_MIN || period > PM8XXX_PWM_PERIOD_MAX) {
793 pr_err("period is invalid: %d\n", period);
794 return -EINVAL;
795 }
796 return 0;
797}
798
799static int dbg_pwm_check_duty_cycle(int duty_cycle, const char *func_name)
800{
801 if (duty_cycle <= 0 || duty_cycle > 100) {
802 pr_err("%s: duty_cycle is invalid: %d\n",
803 func_name, duty_cycle);
804 return -EINVAL;
805 }
806 return 0;
807}
808
809static void dbg_pwm_check_handle(struct pm8xxx_pwm_user *puser)
810{
811 struct pwm_device *tmp;
812
813 if (puser->pwm == NULL) {
814 tmp = pwm_request(puser->pwm_id, "pwm-dbg");
815 if (PTR_ERR(puser->pwm)) {
816 pr_err("pwm_request: err=%ld\n", PTR_ERR(puser->pwm));
817 puser->pwm = NULL;
Willie Ruan10976ea2011-08-25 11:01:15 -0700818 } else {
819 pr_debug("[id=%d] pwm_request ok\n", puser->pwm_id);
820 puser->pwm = tmp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700821 }
822 }
823}
824
825static int dbg_pwm_enable_set(void *data, u64 val)
826{
827 struct pm8xxx_pwm_user *puser = data;
828 struct pm8xxx_pwm_dbg_device *dbgdev = puser->dbgdev;
829 int rc;
830
831 mutex_lock(&dbgdev->dbg_mutex);
832 rc = dbg_pwm_check_duty_cycle(puser->duty_cycle, __func__);
833 if (!rc) {
834 puser->enable = val;
835 dbg_pwm_check_handle(puser);
836 if (puser->pwm) {
837 if (puser->enable)
838 pwm_enable(puser->pwm);
839 else
840 pwm_disable(puser->pwm);
841 }
842 }
843 mutex_unlock(&dbgdev->dbg_mutex);
844 return 0;
845}
846
847static int dbg_pwm_enable_get(void *data, u64 *val)
848{
849 struct pm8xxx_pwm_user *puser = data;
850 struct pm8xxx_pwm_dbg_device *dbgdev = puser->dbgdev;
851
852 mutex_lock(&dbgdev->dbg_mutex);
853 *val = puser->enable;
854 mutex_unlock(&dbgdev->dbg_mutex);
855 return 0;
856}
857
858DEFINE_SIMPLE_ATTRIBUTE(dbg_pwm_enable_fops,
859 dbg_pwm_enable_get, dbg_pwm_enable_set,
860 "%lld\n");
861
862static int dbg_pwm_duty_cycle_set(void *data, u64 val)
863{
864 struct pm8xxx_pwm_user *puser = data;
865 struct pm8xxx_pwm_dbg_device *dbgdev = puser->dbgdev;
866 int rc;
867
868 mutex_lock(&dbgdev->dbg_mutex);
869 rc = dbg_pwm_check_duty_cycle(val, __func__);
870 if (!rc) {
871 puser->duty_cycle = val;
872 dbg_pwm_check_handle(puser);
873 if (puser->pwm) {
874 int duty_us;
875
Willie Ruan10976ea2011-08-25 11:01:15 -0700876 duty_us = puser->duty_cycle * puser->period / 100;
877 pwm_config(puser->pwm, duty_us, puser->period);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700878 }
879 }
880 mutex_unlock(&dbgdev->dbg_mutex);
881 return 0;
882}
883
884static int dbg_pwm_duty_cycle_get(void *data, u64 *val)
885{
886 struct pm8xxx_pwm_user *puser = data;
887 struct pm8xxx_pwm_dbg_device *dbgdev = puser->dbgdev;
888
889 mutex_lock(&dbgdev->dbg_mutex);
890 *val = puser->duty_cycle;
891 mutex_unlock(&dbgdev->dbg_mutex);
892 return 0;
893}
894
895DEFINE_SIMPLE_ATTRIBUTE(dbg_pwm_duty_cycle_fops,
896 dbg_pwm_duty_cycle_get, dbg_pwm_duty_cycle_set,
897 "%lld\n");
898
899static int dbg_pwm_period_set(void *data, u64 val)
900{
901 struct pm8xxx_pwm_user *puser = data;
902 struct pm8xxx_pwm_dbg_device *dbgdev = puser->dbgdev;
903 int rc;
904
905 mutex_lock(&dbgdev->dbg_mutex);
906 rc = dbg_pwm_check_period(val);
907 if (!rc)
908 puser->period = val;
909 mutex_unlock(&dbgdev->dbg_mutex);
910 return 0;
911}
912
913static int dbg_pwm_period_get(void *data, u64 *val)
914{
915 struct pm8xxx_pwm_user *puser = data;
916 struct pm8xxx_pwm_dbg_device *dbgdev = puser->dbgdev;
917
918 mutex_lock(&dbgdev->dbg_mutex);
919 *val = puser->period;
920 mutex_unlock(&dbgdev->dbg_mutex);
921 return 0;
922}
923
924DEFINE_SIMPLE_ATTRIBUTE(dbg_pwm_period_fops,
925 dbg_pwm_period_get, dbg_pwm_period_set, "%lld\n");
926
927static int __devinit pm8xxx_pwm_dbg_probe(struct device *dev)
928{
929 struct pm8xxx_pwm_dbg_device *dbgdev;
930 struct dentry *dent;
931 struct dentry *temp;
932 struct pm8xxx_pwm_user *puser;
933 int i;
934
935 if (dev == NULL) {
936 pr_err("no parent data passed in.\n");
937 return -EINVAL;
938 }
939
940 dbgdev = kzalloc(sizeof *dbgdev, GFP_KERNEL);
941 if (dbgdev == NULL) {
942 pr_err("kzalloc() failed.\n");
943 return -ENOMEM;
944 }
945
946 mutex_init(&dbgdev->dbg_mutex);
947
948 dbgdev->dev = dev;
949
950 dent = debugfs_create_dir("pm8xxx-pwm-dbg", NULL);
951 if (dent == NULL || IS_ERR(dent)) {
952 pr_err("ERR debugfs_create_dir: dent=%p\n", dent);
953 return -ENOMEM;
954 }
955
956 dbgdev->dent = dent;
957
958 for (i = 0; i < PM8XXX_PWM_CHANNELS; i++) {
959 char pwm_ch[] = "0";
960
961 pwm_ch[0] = '0' + i;
962 dent = debugfs_create_dir(pwm_ch, dbgdev->dent);
963 if (dent == NULL || IS_ERR(dent)) {
964 pr_err("ERR: pwm=%d: dir: dent=%p\n", i, dent);
965 goto debug_error;
966 }
967
968 puser = &dbgdev->user[i];
969 puser->dbgdev = dbgdev;
970 puser->pwm_id = i;
971 temp = debugfs_create_file("period", S_IRUGO | S_IWUSR,
972 dent, puser, &dbg_pwm_period_fops);
973 if (temp == NULL || IS_ERR(temp)) {
974 pr_err("ERR: pwm=%d: period: dent=%p\n", i, dent);
975 goto debug_error;
976 }
977
978 temp = debugfs_create_file("duty-cycle", S_IRUGO | S_IWUSR,
979 dent, puser, &dbg_pwm_duty_cycle_fops);
980 if (temp == NULL || IS_ERR(temp)) {
981 pr_err("ERR: pwm=%d: duty-cycle: dent=%p\n", i, dent);
982 goto debug_error;
983 }
984
985 temp = debugfs_create_file("enable", S_IRUGO | S_IWUSR,
986 dent, puser, &dbg_pwm_enable_fops);
987 if (temp == NULL || IS_ERR(temp)) {
988 pr_err("ERR: pwm=%d: enable: dent=%p\n", i, dent);
989 goto debug_error;
990 }
991 }
992
993 pmic_dbg_device = dbgdev;
994
995 return 0;
996
997debug_error:
998 debugfs_remove_recursive(dbgdev->dent);
999 return -ENOMEM;
1000}
1001
1002static int __devexit pm8xxx_pwm_dbg_remove(void)
1003{
1004 if (pmic_dbg_device) {
1005 debugfs_remove_recursive(pmic_dbg_device->dent);
1006 kfree(pmic_dbg_device);
1007 }
1008 return 0;
1009}
1010
1011#else
1012
1013static int __devinit pm8xxx_pwm_dbg_probe(struct device *dev)
1014{
1015 return 0;
1016}
1017
1018static int __devexit pm8xxx_pwm_dbg_remove(void)
1019{
1020 return 0;
1021}
1022
1023#endif
1024
1025static int __devinit pm8xxx_pwm_probe(struct platform_device *pdev)
1026{
1027 struct pm8xxx_pwm_chip *chip;
1028 int i;
1029
1030 chip = kzalloc(sizeof *chip, GFP_KERNEL);
1031 if (chip == NULL) {
1032 pr_err("kzalloc() failed.\n");
1033 return -ENOMEM;
1034 }
1035
1036 for (i = 0; i < PM8XXX_PWM_CHANNELS; i++) {
1037 chip->pwm_dev[i].pwm_id = i;
1038 chip->pwm_dev[i].chip = chip;
1039 }
1040
1041 mutex_init(&chip->pwm_mutex);
1042
1043 chip->dev = &pdev->dev;
1044 pwm_chip = chip;
1045 platform_set_drvdata(pdev, chip);
1046
1047 if (pm8xxx_pwm_dbg_probe(&pdev->dev) < 0)
1048 pr_err("could not set up debugfs\n");
1049
1050 pr_notice("OK\n");
1051 return 0;
1052}
1053
1054static int __devexit pm8xxx_pwm_remove(struct platform_device *pdev)
1055{
1056 struct pm8xxx_pwm_chip *chip = dev_get_drvdata(pdev->dev.parent);
1057
1058 pm8xxx_pwm_dbg_remove();
1059 mutex_destroy(&chip->pwm_mutex);
1060 platform_set_drvdata(pdev, NULL);
1061 kfree(chip);
1062 return 0;
1063}
1064
1065static struct platform_driver pm8xxx_pwm_driver = {
1066 .probe = pm8xxx_pwm_probe,
1067 .remove = __devexit_p(pm8xxx_pwm_remove),
1068 .driver = {
1069 .name = PM8XXX_PWM_DEV_NAME,
1070 .owner = THIS_MODULE,
1071 },
1072};
1073
1074static int __init pm8xxx_pwm_init(void)
1075{
1076 return platform_driver_register(&pm8xxx_pwm_driver);
1077}
1078
1079static void __exit pm8xxx_pwm_exit(void)
1080{
1081 platform_driver_unregister(&pm8xxx_pwm_driver);
1082}
1083
1084subsys_initcall(pm8xxx_pwm_init);
1085module_exit(pm8xxx_pwm_exit);
1086
1087MODULE_LICENSE("GPL v2");
1088MODULE_DESCRIPTION("PM8XXX PWM driver");
1089MODULE_VERSION("1.0");
1090MODULE_ALIAS("platform:" PM8XXX_PWM_DEV_NAME);