Commit 8e00593557c3c5a7bc6f636412a1cadcf4624232

Authored by Uwe Kleine-König
Committed by Samuel Ortiz
1 parent b4e017e332

mfd: Add mc13892 support to mc13xxx

mc13892 is the companion PMIC for Freescale's i.MX51.  It's similar enough
to mc13782 to support it in a single driver.

This patch introduces enough compatibility cruft to keep all users of the
superseded mc13783 driver unchanged.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 6 changed files with 1113 additions and 882 deletions Side-by-side Diff

... ... @@ -409,11 +409,16 @@
409 409 so that function-specific drivers can bind to them.
410 410  
411 411 config MFD_MC13783
412   - tristate "Support Freescale MC13783"
  412 + tristate
  413 +
  414 +config MFD_MC13XXX
  415 + tristate "Support Freescale MC13783 and MC13892"
413 416 depends on SPI_MASTER
414 417 select MFD_CORE
  418 + select MFD_MC13783
415 419 help
416   - Support for the Freescale (Atlas) MC13783 PMIC and audio CODEC.
  420 + Support for the Freescale (Atlas) PMIC and audio CODECs
  421 + MC13783 and MC13892.
417 422 This driver provides common support for accessing the device,
418 423 additional drivers must be enabled in order to use the
419 424 functionality of the device.
drivers/mfd/Makefile
... ... @@ -39,7 +39,7 @@
39 39 obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o
40 40 obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
41 41  
42   -obj-$(CONFIG_MFD_MC13783) += mc13783-core.o
  42 +obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
43 43  
44 44 obj-$(CONFIG_MFD_CORE) += mfd-core.o
45 45  
drivers/mfd/mc13783-core.c
1   -/*
2   - * Copyright 2009 Pengutronix
3   - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4   - *
5   - * loosely based on an earlier driver that has
6   - * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
7   - *
8   - * This program is free software; you can redistribute it and/or modify it under
9   - * the terms of the GNU General Public License version 2 as published by the
10   - * Free Software Foundation.
11   - */
12   -#include <linux/slab.h>
13   -#include <linux/module.h>
14   -#include <linux/platform_device.h>
15   -#include <linux/mutex.h>
16   -#include <linux/interrupt.h>
17   -#include <linux/spi/spi.h>
18   -#include <linux/mfd/core.h>
19   -#include <linux/mfd/mc13783.h>
20   -
21   -struct mc13783 {
22   - struct spi_device *spidev;
23   - struct mutex lock;
24   - int irq;
25   - int adcflags;
26   -
27   - irq_handler_t irqhandler[MC13783_NUM_IRQ];
28   - void *irqdata[MC13783_NUM_IRQ];
29   -};
30   -
31   -#define MC13783_REG_REVISION 7
32   -#define MC13783_REG_ADC_0 43
33   -#define MC13783_REG_ADC_1 44
34   -#define MC13783_REG_ADC_2 45
35   -
36   -#define MC13783_IRQSTAT0 0
37   -#define MC13783_IRQSTAT0_ADCDONEI (1 << 0)
38   -#define MC13783_IRQSTAT0_ADCBISDONEI (1 << 1)
39   -#define MC13783_IRQSTAT0_TSI (1 << 2)
40   -#define MC13783_IRQSTAT0_WHIGHI (1 << 3)
41   -#define MC13783_IRQSTAT0_WLOWI (1 << 4)
42   -#define MC13783_IRQSTAT0_CHGDETI (1 << 6)
43   -#define MC13783_IRQSTAT0_CHGOVI (1 << 7)
44   -#define MC13783_IRQSTAT0_CHGREVI (1 << 8)
45   -#define MC13783_IRQSTAT0_CHGSHORTI (1 << 9)
46   -#define MC13783_IRQSTAT0_CCCVI (1 << 10)
47   -#define MC13783_IRQSTAT0_CHGCURRI (1 << 11)
48   -#define MC13783_IRQSTAT0_BPONI (1 << 12)
49   -#define MC13783_IRQSTAT0_LOBATLI (1 << 13)
50   -#define MC13783_IRQSTAT0_LOBATHI (1 << 14)
51   -#define MC13783_IRQSTAT0_UDPI (1 << 15)
52   -#define MC13783_IRQSTAT0_USBI (1 << 16)
53   -#define MC13783_IRQSTAT0_IDI (1 << 19)
54   -#define MC13783_IRQSTAT0_SE1I (1 << 21)
55   -#define MC13783_IRQSTAT0_CKDETI (1 << 22)
56   -#define MC13783_IRQSTAT0_UDMI (1 << 23)
57   -
58   -#define MC13783_IRQMASK0 1
59   -#define MC13783_IRQMASK0_ADCDONEM MC13783_IRQSTAT0_ADCDONEI
60   -#define MC13783_IRQMASK0_ADCBISDONEM MC13783_IRQSTAT0_ADCBISDONEI
61   -#define MC13783_IRQMASK0_TSM MC13783_IRQSTAT0_TSI
62   -#define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI
63   -#define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI
64   -#define MC13783_IRQMASK0_CHGDETM MC13783_IRQSTAT0_CHGDETI
65   -#define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI
66   -#define MC13783_IRQMASK0_CHGREVM MC13783_IRQSTAT0_CHGREVI
67   -#define MC13783_IRQMASK0_CHGSHORTM MC13783_IRQSTAT0_CHGSHORTI
68   -#define MC13783_IRQMASK0_CCCVM MC13783_IRQSTAT0_CCCVI
69   -#define MC13783_IRQMASK0_CHGCURRM MC13783_IRQSTAT0_CHGCURRI
70   -#define MC13783_IRQMASK0_BPONM MC13783_IRQSTAT0_BPONI
71   -#define MC13783_IRQMASK0_LOBATLM MC13783_IRQSTAT0_LOBATLI
72   -#define MC13783_IRQMASK0_LOBATHM MC13783_IRQSTAT0_LOBATHI
73   -#define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI
74   -#define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI
75   -#define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI
76   -#define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I
77   -#define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI
78   -#define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI
79   -
80   -#define MC13783_IRQSTAT1 3
81   -#define MC13783_IRQSTAT1_1HZI (1 << 0)
82   -#define MC13783_IRQSTAT1_TODAI (1 << 1)
83   -#define MC13783_IRQSTAT1_ONOFD1I (1 << 3)
84   -#define MC13783_IRQSTAT1_ONOFD2I (1 << 4)
85   -#define MC13783_IRQSTAT1_ONOFD3I (1 << 5)
86   -#define MC13783_IRQSTAT1_SYSRSTI (1 << 6)
87   -#define MC13783_IRQSTAT1_RTCRSTI (1 << 7)
88   -#define MC13783_IRQSTAT1_PCI (1 << 8)
89   -#define MC13783_IRQSTAT1_WARMI (1 << 9)
90   -#define MC13783_IRQSTAT1_MEMHLDI (1 << 10)
91   -#define MC13783_IRQSTAT1_PWRRDYI (1 << 11)
92   -#define MC13783_IRQSTAT1_THWARNLI (1 << 12)
93   -#define MC13783_IRQSTAT1_THWARNHI (1 << 13)
94   -#define MC13783_IRQSTAT1_CLKI (1 << 14)
95   -#define MC13783_IRQSTAT1_SEMAFI (1 << 15)
96   -#define MC13783_IRQSTAT1_MC2BI (1 << 17)
97   -#define MC13783_IRQSTAT1_HSDETI (1 << 18)
98   -#define MC13783_IRQSTAT1_HSLI (1 << 19)
99   -#define MC13783_IRQSTAT1_ALSPTHI (1 << 20)
100   -#define MC13783_IRQSTAT1_AHSSHORTI (1 << 21)
101   -
102   -#define MC13783_IRQMASK1 4
103   -#define MC13783_IRQMASK1_1HZM MC13783_IRQSTAT1_1HZI
104   -#define MC13783_IRQMASK1_TODAM MC13783_IRQSTAT1_TODAI
105   -#define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I
106   -#define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I
107   -#define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I
108   -#define MC13783_IRQMASK1_SYSRSTM MC13783_IRQSTAT1_SYSRSTI
109   -#define MC13783_IRQMASK1_RTCRSTM MC13783_IRQSTAT1_RTCRSTI
110   -#define MC13783_IRQMASK1_PCM MC13783_IRQSTAT1_PCI
111   -#define MC13783_IRQMASK1_WARMM MC13783_IRQSTAT1_WARMI
112   -#define MC13783_IRQMASK1_MEMHLDM MC13783_IRQSTAT1_MEMHLDI
113   -#define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI
114   -#define MC13783_IRQMASK1_THWARNLM MC13783_IRQSTAT1_THWARNLI
115   -#define MC13783_IRQMASK1_THWARNHM MC13783_IRQSTAT1_THWARNHI
116   -#define MC13783_IRQMASK1_CLKM MC13783_IRQSTAT1_CLKI
117   -#define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI
118   -#define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI
119   -#define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI
120   -#define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI
121   -#define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI
122   -#define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI
123   -
124   -#define MC13783_ADC1 44
125   -#define MC13783_ADC1_ADEN (1 << 0)
126   -#define MC13783_ADC1_RAND (1 << 1)
127   -#define MC13783_ADC1_ADSEL (1 << 3)
128   -#define MC13783_ADC1_ASC (1 << 20)
129   -#define MC13783_ADC1_ADTRIGIGN (1 << 21)
130   -
131   -#define MC13783_NUMREGS 0x3f
132   -
133   -void mc13783_lock(struct mc13783 *mc13783)
134   -{
135   - if (!mutex_trylock(&mc13783->lock)) {
136   - dev_dbg(&mc13783->spidev->dev, "wait for %s from %pf\n",
137   - __func__, __builtin_return_address(0));
138   -
139   - mutex_lock(&mc13783->lock);
140   - }
141   - dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
142   - __func__, __builtin_return_address(0));
143   -}
144   -EXPORT_SYMBOL(mc13783_lock);
145   -
146   -void mc13783_unlock(struct mc13783 *mc13783)
147   -{
148   - dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
149   - __func__, __builtin_return_address(0));
150   - mutex_unlock(&mc13783->lock);
151   -}
152   -EXPORT_SYMBOL(mc13783_unlock);
153   -
154   -#define MC13783_REGOFFSET_SHIFT 25
155   -int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val)
156   -{
157   - struct spi_transfer t;
158   - struct spi_message m;
159   - int ret;
160   -
161   - BUG_ON(!mutex_is_locked(&mc13783->lock));
162   -
163   - if (offset > MC13783_NUMREGS)
164   - return -EINVAL;
165   -
166   - *val = offset << MC13783_REGOFFSET_SHIFT;
167   -
168   - memset(&t, 0, sizeof(t));
169   -
170   - t.tx_buf = val;
171   - t.rx_buf = val;
172   - t.len = sizeof(u32);
173   -
174   - spi_message_init(&m);
175   - spi_message_add_tail(&t, &m);
176   -
177   - ret = spi_sync(mc13783->spidev, &m);
178   -
179   - /* error in message.status implies error return from spi_sync */
180   - BUG_ON(!ret && m.status);
181   -
182   - if (ret)
183   - return ret;
184   -
185   - *val &= 0xffffff;
186   -
187   - dev_vdbg(&mc13783->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val);
188   -
189   - return 0;
190   -}
191   -EXPORT_SYMBOL(mc13783_reg_read);
192   -
193   -int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val)
194   -{
195   - u32 buf;
196   - struct spi_transfer t;
197   - struct spi_message m;
198   - int ret;
199   -
200   - BUG_ON(!mutex_is_locked(&mc13783->lock));
201   -
202   - dev_vdbg(&mc13783->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val);
203   -
204   - if (offset > MC13783_NUMREGS || val > 0xffffff)
205   - return -EINVAL;
206   -
207   - buf = 1 << 31 | offset << MC13783_REGOFFSET_SHIFT | val;
208   -
209   - memset(&t, 0, sizeof(t));
210   -
211   - t.tx_buf = &buf;
212   - t.rx_buf = &buf;
213   - t.len = sizeof(u32);
214   -
215   - spi_message_init(&m);
216   - spi_message_add_tail(&t, &m);
217   -
218   - ret = spi_sync(mc13783->spidev, &m);
219   -
220   - BUG_ON(!ret && m.status);
221   -
222   - if (ret)
223   - return ret;
224   -
225   - return 0;
226   -}
227   -EXPORT_SYMBOL(mc13783_reg_write);
228   -
229   -int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
230   - u32 mask, u32 val)
231   -{
232   - int ret;
233   - u32 valread;
234   -
235   - BUG_ON(val & ~mask);
236   -
237   - ret = mc13783_reg_read(mc13783, offset, &valread);
238   - if (ret)
239   - return ret;
240   -
241   - valread = (valread & ~mask) | val;
242   -
243   - return mc13783_reg_write(mc13783, offset, valread);
244   -}
245   -EXPORT_SYMBOL(mc13783_reg_rmw);
246   -
247   -int mc13783_get_flags(struct mc13783 *mc13783)
248   -{
249   - struct mc13783_platform_data *pdata =
250   - dev_get_platdata(&mc13783->spidev->dev);
251   -
252   - return pdata->flags;
253   -}
254   -EXPORT_SYMBOL(mc13783_get_flags);
255   -
256   -int mc13783_irq_mask(struct mc13783 *mc13783, int irq)
257   -{
258   - int ret;
259   - unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
260   - u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
261   - u32 mask;
262   -
263   - if (irq < 0 || irq >= MC13783_NUM_IRQ)
264   - return -EINVAL;
265   -
266   - ret = mc13783_reg_read(mc13783, offmask, &mask);
267   - if (ret)
268   - return ret;
269   -
270   - if (mask & irqbit)
271   - /* already masked */
272   - return 0;
273   -
274   - return mc13783_reg_write(mc13783, offmask, mask | irqbit);
275   -}
276   -EXPORT_SYMBOL(mc13783_irq_mask);
277   -
278   -int mc13783_irq_unmask(struct mc13783 *mc13783, int irq)
279   -{
280   - int ret;
281   - unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
282   - u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
283   - u32 mask;
284   -
285   - if (irq < 0 || irq >= MC13783_NUM_IRQ)
286   - return -EINVAL;
287   -
288   - ret = mc13783_reg_read(mc13783, offmask, &mask);
289   - if (ret)
290   - return ret;
291   -
292   - if (!(mask & irqbit))
293   - /* already unmasked */
294   - return 0;
295   -
296   - return mc13783_reg_write(mc13783, offmask, mask & ~irqbit);
297   -}
298   -EXPORT_SYMBOL(mc13783_irq_unmask);
299   -
300   -int mc13783_irq_status(struct mc13783 *mc13783, int irq,
301   - int *enabled, int *pending)
302   -{
303   - int ret;
304   - unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
305   - unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
306   - u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
307   -
308   - if (irq < 0 || irq >= MC13783_NUM_IRQ)
309   - return -EINVAL;
310   -
311   - if (enabled) {
312   - u32 mask;
313   -
314   - ret = mc13783_reg_read(mc13783, offmask, &mask);
315   - if (ret)
316   - return ret;
317   -
318   - *enabled = mask & irqbit;
319   - }
320   -
321   - if (pending) {
322   - u32 stat;
323   -
324   - ret = mc13783_reg_read(mc13783, offstat, &stat);
325   - if (ret)
326   - return ret;
327   -
328   - *pending = stat & irqbit;
329   - }
330   -
331   - return 0;
332   -}
333   -EXPORT_SYMBOL(mc13783_irq_status);
334   -
335   -int mc13783_irq_ack(struct mc13783 *mc13783, int irq)
336   -{
337   - unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
338   - unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
339   -
340   - BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
341   -
342   - return mc13783_reg_write(mc13783, offstat, val);
343   -}
344   -EXPORT_SYMBOL(mc13783_irq_ack);
345   -
346   -int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
347   - irq_handler_t handler, const char *name, void *dev)
348   -{
349   - BUG_ON(!mutex_is_locked(&mc13783->lock));
350   - BUG_ON(!handler);
351   -
352   - if (irq < 0 || irq >= MC13783_NUM_IRQ)
353   - return -EINVAL;
354   -
355   - if (mc13783->irqhandler[irq])
356   - return -EBUSY;
357   -
358   - mc13783->irqhandler[irq] = handler;
359   - mc13783->irqdata[irq] = dev;
360   -
361   - return 0;
362   -}
363   -EXPORT_SYMBOL(mc13783_irq_request_nounmask);
364   -
365   -int mc13783_irq_request(struct mc13783 *mc13783, int irq,
366   - irq_handler_t handler, const char *name, void *dev)
367   -{
368   - int ret;
369   -
370   - ret = mc13783_irq_request_nounmask(mc13783, irq, handler, name, dev);
371   - if (ret)
372   - return ret;
373   -
374   - ret = mc13783_irq_unmask(mc13783, irq);
375   - if (ret) {
376   - mc13783->irqhandler[irq] = NULL;
377   - mc13783->irqdata[irq] = NULL;
378   - return ret;
379   - }
380   -
381   - return 0;
382   -}
383   -EXPORT_SYMBOL(mc13783_irq_request);
384   -
385   -int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
386   -{
387   - int ret;
388   - BUG_ON(!mutex_is_locked(&mc13783->lock));
389   -
390   - if (irq < 0 || irq >= MC13783_NUM_IRQ || !mc13783->irqhandler[irq] ||
391   - mc13783->irqdata[irq] != dev)
392   - return -EINVAL;
393   -
394   - ret = mc13783_irq_mask(mc13783, irq);
395   - if (ret)
396   - return ret;
397   -
398   - mc13783->irqhandler[irq] = NULL;
399   - mc13783->irqdata[irq] = NULL;
400   -
401   - return 0;
402   -}
403   -EXPORT_SYMBOL(mc13783_irq_free);
404   -
405   -static inline irqreturn_t mc13783_irqhandler(struct mc13783 *mc13783, int irq)
406   -{
407   - return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]);
408   -}
409   -
410   -/*
411   - * returns: number of handled irqs or negative error
412   - * locking: holds mc13783->lock
413   - */
414   -static int mc13783_irq_handle(struct mc13783 *mc13783,
415   - unsigned int offstat, unsigned int offmask, int baseirq)
416   -{
417   - u32 stat, mask;
418   - int ret = mc13783_reg_read(mc13783, offstat, &stat);
419   - int num_handled = 0;
420   -
421   - if (ret)
422   - return ret;
423   -
424   - ret = mc13783_reg_read(mc13783, offmask, &mask);
425   - if (ret)
426   - return ret;
427   -
428   - while (stat & ~mask) {
429   - int irq = __ffs(stat & ~mask);
430   -
431   - stat &= ~(1 << irq);
432   -
433   - if (likely(mc13783->irqhandler[baseirq + irq])) {
434   - irqreturn_t handled;
435   -
436   - handled = mc13783_irqhandler(mc13783, baseirq + irq);
437   - if (handled == IRQ_HANDLED)
438   - num_handled++;
439   - } else {
440   - dev_err(&mc13783->spidev->dev,
441   - "BUG: irq %u but no handler\n",
442   - baseirq + irq);
443   -
444   - mask |= 1 << irq;
445   -
446   - ret = mc13783_reg_write(mc13783, offmask, mask);
447   - }
448   - }
449   -
450   - return num_handled;
451   -}
452   -
453   -static irqreturn_t mc13783_irq_thread(int irq, void *data)
454   -{
455   - struct mc13783 *mc13783 = data;
456   - irqreturn_t ret;
457   - int handled = 0;
458   -
459   - mc13783_lock(mc13783);
460   -
461   - ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT0,
462   - MC13783_IRQMASK0, MC13783_IRQ_ADCDONE);
463   - if (ret > 0)
464   - handled = 1;
465   -
466   - ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT1,
467   - MC13783_IRQMASK1, MC13783_IRQ_1HZ);
468   - if (ret > 0)
469   - handled = 1;
470   -
471   - mc13783_unlock(mc13783);
472   -
473   - return IRQ_RETVAL(handled);
474   -}
475   -
476   -#define MC13783_ADC1_CHAN0_SHIFT 5
477   -#define MC13783_ADC1_CHAN1_SHIFT 8
478   -
479   -struct mc13783_adcdone_data {
480   - struct mc13783 *mc13783;
481   - struct completion done;
482   -};
483   -
484   -static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
485   -{
486   - struct mc13783_adcdone_data *adcdone_data = data;
487   -
488   - mc13783_irq_ack(adcdone_data->mc13783, irq);
489   -
490   - complete_all(&adcdone_data->done);
491   -
492   - return IRQ_HANDLED;
493   -}
494   -
495   -#define MC13783_ADC_WORKING (1 << 0)
496   -
497   -int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
498   - unsigned int channel, unsigned int *sample)
499   -{
500   - u32 adc0, adc1, old_adc0;
501   - int i, ret;
502   - struct mc13783_adcdone_data adcdone_data = {
503   - .mc13783 = mc13783,
504   - };
505   - init_completion(&adcdone_data.done);
506   -
507   - dev_dbg(&mc13783->spidev->dev, "%s\n", __func__);
508   -
509   - mc13783_lock(mc13783);
510   -
511   - if (mc13783->adcflags & MC13783_ADC_WORKING) {
512   - ret = -EBUSY;
513   - goto out;
514   - }
515   -
516   - mc13783->adcflags |= MC13783_ADC_WORKING;
517   -
518   - mc13783_reg_read(mc13783, MC13783_ADC0, &old_adc0);
519   -
520   - adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
521   - adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC;
522   -
523   - if (channel > 7)
524   - adc1 |= MC13783_ADC1_ADSEL;
525   -
526   - switch (mode) {
527   - case MC13783_ADC_MODE_TS:
528   - adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_TSMOD0 |
529   - MC13783_ADC0_TSMOD1;
530   - adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
531   - break;
532   -
533   - case MC13783_ADC_MODE_SINGLE_CHAN:
534   - adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
535   - adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
536   - adc1 |= MC13783_ADC1_RAND;
537   - break;
538   -
539   - case MC13783_ADC_MODE_MULT_CHAN:
540   - adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
541   - adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
542   - break;
543   -
544   - default:
545   - mc13783_unlock(mc13783);
546   - return -EINVAL;
547   - }
548   -
549   - dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__);
550   - mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE,
551   - mc13783_handler_adcdone, __func__, &adcdone_data);
552   - mc13783_irq_ack(mc13783, MC13783_IRQ_ADCDONE);
553   -
554   - mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0);
555   - mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1);
556   -
557   - mc13783_unlock(mc13783);
558   -
559   - ret = wait_for_completion_interruptible_timeout(&adcdone_data.done, HZ);
560   -
561   - if (!ret)
562   - ret = -ETIMEDOUT;
563   -
564   - mc13783_lock(mc13783);
565   -
566   - mc13783_irq_free(mc13783, MC13783_IRQ_ADCDONE, &adcdone_data);
567   -
568   - if (ret > 0)
569   - for (i = 0; i < 4; ++i) {
570   - ret = mc13783_reg_read(mc13783,
571   - MC13783_REG_ADC_2, &sample[i]);
572   - if (ret)
573   - break;
574   - }
575   -
576   - if (mode == MC13783_ADC_MODE_TS)
577   - /* restore TSMOD */
578   - mc13783_reg_write(mc13783, MC13783_REG_ADC_0, old_adc0);
579   -
580   - mc13783->adcflags &= ~MC13783_ADC_WORKING;
581   -out:
582   - mc13783_unlock(mc13783);
583   -
584   - return ret;
585   -}
586   -EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
587   -
588   -static int mc13783_add_subdevice_pdata(struct mc13783 *mc13783,
589   - const char *name, void *pdata, size_t pdata_size)
590   -{
591   - struct mfd_cell cell = {
592   - .name = name,
593   - .platform_data = pdata,
594   - .data_size = pdata_size,
595   - };
596   -
597   - return mfd_add_devices(&mc13783->spidev->dev, -1, &cell, 1, NULL, 0);
598   -}
599   -
600   -static int mc13783_add_subdevice(struct mc13783 *mc13783, const char *name)
601   -{
602   - return mc13783_add_subdevice_pdata(mc13783, name, NULL, 0);
603   -}
604   -
605   -static int mc13783_check_revision(struct mc13783 *mc13783)
606   -{
607   - u32 rev_id, rev1, rev2, finid, icid;
608   -
609   - mc13783_reg_read(mc13783, MC13783_REG_REVISION, &rev_id);
610   -
611   - rev1 = (rev_id & 0x018) >> 3;
612   - rev2 = (rev_id & 0x007);
613   - icid = (rev_id & 0x01C0) >> 6;
614   - finid = (rev_id & 0x01E00) >> 9;
615   -
616   - /* Ver 0.2 is actually 3.2a. Report as 3.2 */
617   - if ((rev1 == 0) && (rev2 == 2))
618   - rev1 = 3;
619   -
620   - if (rev1 == 0 || icid != 2) {
621   - dev_err(&mc13783->spidev->dev, "No MC13783 detected.\n");
622   - return -ENODEV;
623   - }
624   -
625   - dev_info(&mc13783->spidev->dev,
626   - "MC13783 Rev %d.%d FinVer %x detected\n",
627   - rev1, rev2, finid);
628   -
629   - return 0;
630   -}
631   -
632   -static int mc13783_probe(struct spi_device *spi)
633   -{
634   - struct mc13783 *mc13783;
635   - struct mc13783_platform_data *pdata = dev_get_platdata(&spi->dev);
636   - int ret;
637   -
638   - mc13783 = kzalloc(sizeof(*mc13783), GFP_KERNEL);
639   - if (!mc13783)
640   - return -ENOMEM;
641   -
642   - dev_set_drvdata(&spi->dev, mc13783);
643   - spi->mode = SPI_MODE_0 | SPI_CS_HIGH;
644   - spi->bits_per_word = 32;
645   - spi_setup(spi);
646   -
647   - mc13783->spidev = spi;
648   -
649   - mutex_init(&mc13783->lock);
650   - mc13783_lock(mc13783);
651   -
652   - ret = mc13783_check_revision(mc13783);
653   - if (ret)
654   - goto err_revision;
655   -
656   - /* mask all irqs */
657   - ret = mc13783_reg_write(mc13783, MC13783_IRQMASK0, 0x00ffffff);
658   - if (ret)
659   - goto err_mask;
660   -
661   - ret = mc13783_reg_write(mc13783, MC13783_IRQMASK1, 0x00ffffff);
662   - if (ret)
663   - goto err_mask;
664   -
665   - ret = request_threaded_irq(spi->irq, NULL, mc13783_irq_thread,
666   - IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13783", mc13783);
667   -
668   - if (ret) {
669   -err_mask:
670   -err_revision:
671   - mutex_unlock(&mc13783->lock);
672   - dev_set_drvdata(&spi->dev, NULL);
673   - kfree(mc13783);
674   - return ret;
675   - }
676   -
677   - mc13783_unlock(mc13783);
678   -
679   - if (pdata->flags & MC13783_USE_ADC)
680   - mc13783_add_subdevice(mc13783, "mc13783-adc");
681   -
682   - if (pdata->flags & MC13783_USE_CODEC)
683   - mc13783_add_subdevice(mc13783, "mc13783-codec");
684   -
685   - if (pdata->flags & MC13783_USE_REGULATOR) {
686   - struct mc13783_regulator_platform_data regulator_pdata = {
687   - .num_regulators = pdata->num_regulators,
688   - .regulators = pdata->regulators,
689   - };
690   -
691   - mc13783_add_subdevice_pdata(mc13783, "mc13783-regulator",
692   - &regulator_pdata, sizeof(regulator_pdata));
693   - }
694   -
695   - if (pdata->flags & MC13783_USE_RTC)
696   - mc13783_add_subdevice(mc13783, "mc13783-rtc");
697   -
698   - if (pdata->flags & MC13783_USE_TOUCHSCREEN)
699   - mc13783_add_subdevice(mc13783, "mc13783-ts");
700   -
701   - if (pdata->flags & MC13783_USE_LED)
702   - mc13783_add_subdevice_pdata(mc13783, "mc13783-led",
703   - pdata->leds, sizeof(*pdata->leds));
704   -
705   - return 0;
706   -}
707   -
708   -static int __devexit mc13783_remove(struct spi_device *spi)
709   -{
710   - struct mc13783 *mc13783 = dev_get_drvdata(&spi->dev);
711   -
712   - free_irq(mc13783->spidev->irq, mc13783);
713   -
714   - mfd_remove_devices(&spi->dev);
715   -
716   - return 0;
717   -}
718   -
719   -static struct spi_driver mc13783_driver = {
720   - .driver = {
721   - .name = "mc13783",
722   - .bus = &spi_bus_type,
723   - .owner = THIS_MODULE,
724   - },
725   - .probe = mc13783_probe,
726   - .remove = __devexit_p(mc13783_remove),
727   -};
728   -
729   -static int __init mc13783_init(void)
730   -{
731   - return spi_register_driver(&mc13783_driver);
732   -}
733   -subsys_initcall(mc13783_init);
734   -
735   -static void __exit mc13783_exit(void)
736   -{
737   - spi_unregister_driver(&mc13783_driver);
738   -}
739   -module_exit(mc13783_exit);
740   -
741   -MODULE_DESCRIPTION("Core driver for Freescale MC13783 PMIC");
742   -MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
743   -MODULE_LICENSE("GPL v2");
drivers/mfd/mc13xxx-core.c
  1 +/*
  2 + * Copyright 2009-2010 Pengutronix
  3 + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
  4 + *
  5 + * loosely based on an earlier driver that has
  6 + * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify it under
  9 + * the terms of the GNU General Public License version 2 as published by the
  10 + * Free Software Foundation.
  11 + */
  12 +#define DEBUG
  13 +#define VERBOSE_DEBUG
  14 +
  15 +#include <linux/slab.h>
  16 +#include <linux/module.h>
  17 +#include <linux/platform_device.h>
  18 +#include <linux/mutex.h>
  19 +#include <linux/interrupt.h>
  20 +#include <linux/spi/spi.h>
  21 +#include <linux/mfd/core.h>
  22 +#include <linux/mfd/mc13xxx.h>
  23 +
  24 +struct mc13xxx {
  25 + struct spi_device *spidev;
  26 + struct mutex lock;
  27 + int irq;
  28 +
  29 + irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
  30 + void *irqdata[MC13XXX_NUM_IRQ];
  31 +};
  32 +
  33 +struct mc13783 {
  34 + struct mc13xxx mc13xxx;
  35 +
  36 + int adcflags;
  37 +};
  38 +
  39 +struct mc13xxx *mc13783_to_mc13xxx(struct mc13783 *mc13783)
  40 +{
  41 + return &mc13783->mc13xxx;
  42 +}
  43 +EXPORT_SYMBOL(mc13783_to_mc13xxx);
  44 +
  45 +#define MC13XXX_IRQSTAT0 0
  46 +#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0)
  47 +#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1)
  48 +#define MC13XXX_IRQSTAT0_TSI (1 << 2)
  49 +#define MC13783_IRQSTAT0_WHIGHI (1 << 3)
  50 +#define MC13783_IRQSTAT0_WLOWI (1 << 4)
  51 +#define MC13XXX_IRQSTAT0_CHGDETI (1 << 6)
  52 +#define MC13783_IRQSTAT0_CHGOVI (1 << 7)
  53 +#define MC13XXX_IRQSTAT0_CHGREVI (1 << 8)
  54 +#define MC13XXX_IRQSTAT0_CHGSHORTI (1 << 9)
  55 +#define MC13XXX_IRQSTAT0_CCCVI (1 << 10)
  56 +#define MC13XXX_IRQSTAT0_CHGCURRI (1 << 11)
  57 +#define MC13XXX_IRQSTAT0_BPONI (1 << 12)
  58 +#define MC13XXX_IRQSTAT0_LOBATLI (1 << 13)
  59 +#define MC13XXX_IRQSTAT0_LOBATHI (1 << 14)
  60 +#define MC13783_IRQSTAT0_UDPI (1 << 15)
  61 +#define MC13783_IRQSTAT0_USBI (1 << 16)
  62 +#define MC13783_IRQSTAT0_IDI (1 << 19)
  63 +#define MC13783_IRQSTAT0_SE1I (1 << 21)
  64 +#define MC13783_IRQSTAT0_CKDETI (1 << 22)
  65 +#define MC13783_IRQSTAT0_UDMI (1 << 23)
  66 +
  67 +#define MC13XXX_IRQMASK0 1
  68 +#define MC13XXX_IRQMASK0_ADCDONEM MC13XXX_IRQSTAT0_ADCDONEI
  69 +#define MC13XXX_IRQMASK0_ADCBISDONEM MC13XXX_IRQSTAT0_ADCBISDONEI
  70 +#define MC13XXX_IRQMASK0_TSM MC13XXX_IRQSTAT0_TSI
  71 +#define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI
  72 +#define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI
  73 +#define MC13XXX_IRQMASK0_CHGDETM MC13XXX_IRQSTAT0_CHGDETI
  74 +#define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI
  75 +#define MC13XXX_IRQMASK0_CHGREVM MC13XXX_IRQSTAT0_CHGREVI
  76 +#define MC13XXX_IRQMASK0_CHGSHORTM MC13XXX_IRQSTAT0_CHGSHORTI
  77 +#define MC13XXX_IRQMASK0_CCCVM MC13XXX_IRQSTAT0_CCCVI
  78 +#define MC13XXX_IRQMASK0_CHGCURRM MC13XXX_IRQSTAT0_CHGCURRI
  79 +#define MC13XXX_IRQMASK0_BPONM MC13XXX_IRQSTAT0_BPONI
  80 +#define MC13XXX_IRQMASK0_LOBATLM MC13XXX_IRQSTAT0_LOBATLI
  81 +#define MC13XXX_IRQMASK0_LOBATHM MC13XXX_IRQSTAT0_LOBATHI
  82 +#define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI
  83 +#define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI
  84 +#define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI
  85 +#define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I
  86 +#define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI
  87 +#define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI
  88 +
  89 +#define MC13XXX_IRQSTAT1 3
  90 +#define MC13XXX_IRQSTAT1_1HZI (1 << 0)
  91 +#define MC13XXX_IRQSTAT1_TODAI (1 << 1)
  92 +#define MC13783_IRQSTAT1_ONOFD1I (1 << 3)
  93 +#define MC13783_IRQSTAT1_ONOFD2I (1 << 4)
  94 +#define MC13783_IRQSTAT1_ONOFD3I (1 << 5)
  95 +#define MC13XXX_IRQSTAT1_SYSRSTI (1 << 6)
  96 +#define MC13XXX_IRQSTAT1_RTCRSTI (1 << 7)
  97 +#define MC13XXX_IRQSTAT1_PCI (1 << 8)
  98 +#define MC13XXX_IRQSTAT1_WARMI (1 << 9)
  99 +#define MC13XXX_IRQSTAT1_MEMHLDI (1 << 10)
  100 +#define MC13783_IRQSTAT1_PWRRDYI (1 << 11)
  101 +#define MC13XXX_IRQSTAT1_THWARNLI (1 << 12)
  102 +#define MC13XXX_IRQSTAT1_THWARNHI (1 << 13)
  103 +#define MC13XXX_IRQSTAT1_CLKI (1 << 14)
  104 +#define MC13783_IRQSTAT1_SEMAFI (1 << 15)
  105 +#define MC13783_IRQSTAT1_MC2BI (1 << 17)
  106 +#define MC13783_IRQSTAT1_HSDETI (1 << 18)
  107 +#define MC13783_IRQSTAT1_HSLI (1 << 19)
  108 +#define MC13783_IRQSTAT1_ALSPTHI (1 << 20)
  109 +#define MC13783_IRQSTAT1_AHSSHORTI (1 << 21)
  110 +
  111 +#define MC13XXX_IRQMASK1 4
  112 +#define MC13XXX_IRQMASK1_1HZM MC13XXX_IRQSTAT1_1HZI
  113 +#define MC13XXX_IRQMASK1_TODAM MC13XXX_IRQSTAT1_TODAI
  114 +#define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I
  115 +#define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I
  116 +#define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I
  117 +#define MC13XXX_IRQMASK1_SYSRSTM MC13XXX_IRQSTAT1_SYSRSTI
  118 +#define MC13XXX_IRQMASK1_RTCRSTM MC13XXX_IRQSTAT1_RTCRSTI
  119 +#define MC13XXX_IRQMASK1_PCM MC13XXX_IRQSTAT1_PCI
  120 +#define MC13XXX_IRQMASK1_WARMM MC13XXX_IRQSTAT1_WARMI
  121 +#define MC13XXX_IRQMASK1_MEMHLDM MC13XXX_IRQSTAT1_MEMHLDI
  122 +#define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI
  123 +#define MC13XXX_IRQMASK1_THWARNLM MC13XXX_IRQSTAT1_THWARNLI
  124 +#define MC13XXX_IRQMASK1_THWARNHM MC13XXX_IRQSTAT1_THWARNHI
  125 +#define MC13XXX_IRQMASK1_CLKM MC13XXX_IRQSTAT1_CLKI
  126 +#define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI
  127 +#define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI
  128 +#define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI
  129 +#define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI
  130 +#define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI
  131 +#define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI
  132 +
  133 +#define MC13XXX_REVISION 7
  134 +#define MC13XXX_REVISION_REVMETAL (0x07 << 0)
  135 +#define MC13XXX_REVISION_REVFULL (0x03 << 3)
  136 +#define MC13XXX_REVISION_ICID (0x07 << 6)
  137 +#define MC13XXX_REVISION_FIN (0x03 << 9)
  138 +#define MC13XXX_REVISION_FAB (0x03 << 11)
  139 +#define MC13XXX_REVISION_ICIDCODE (0x3f << 13)
  140 +
  141 +#define MC13783_ADC1 44
  142 +#define MC13783_ADC1_ADEN (1 << 0)
  143 +#define MC13783_ADC1_RAND (1 << 1)
  144 +#define MC13783_ADC1_ADSEL (1 << 3)
  145 +#define MC13783_ADC1_ASC (1 << 20)
  146 +#define MC13783_ADC1_ADTRIGIGN (1 << 21)
  147 +
  148 +#define MC13783_ADC2 45
  149 +
  150 +#define MC13XXX_NUMREGS 0x3f
  151 +
  152 +void mc13xxx_lock(struct mc13xxx *mc13xxx)
  153 +{
  154 + if (!mutex_trylock(&mc13xxx->lock)) {
  155 + dev_dbg(&mc13xxx->spidev->dev, "wait for %s from %pf\n",
  156 + __func__, __builtin_return_address(0));
  157 +
  158 + mutex_lock(&mc13xxx->lock);
  159 + }
  160 + dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n",
  161 + __func__, __builtin_return_address(0));
  162 +}
  163 +EXPORT_SYMBOL(mc13xxx_lock);
  164 +
  165 +void mc13xxx_unlock(struct mc13xxx *mc13xxx)
  166 +{
  167 + dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n",
  168 + __func__, __builtin_return_address(0));
  169 + mutex_unlock(&mc13xxx->lock);
  170 +}
  171 +EXPORT_SYMBOL(mc13xxx_unlock);
  172 +
  173 +#define MC13XXX_REGOFFSET_SHIFT 25
  174 +int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val)
  175 +{
  176 + struct spi_transfer t;
  177 + struct spi_message m;
  178 + int ret;
  179 +
  180 + BUG_ON(!mutex_is_locked(&mc13xxx->lock));
  181 +
  182 + if (offset > MC13XXX_NUMREGS)
  183 + return -EINVAL;
  184 +
  185 + *val = offset << MC13XXX_REGOFFSET_SHIFT;
  186 +
  187 + memset(&t, 0, sizeof(t));
  188 +
  189 + t.tx_buf = val;
  190 + t.rx_buf = val;
  191 + t.len = sizeof(u32);
  192 +
  193 + spi_message_init(&m);
  194 + spi_message_add_tail(&t, &m);
  195 +
  196 + ret = spi_sync(mc13xxx->spidev, &m);
  197 +
  198 + /* error in message.status implies error return from spi_sync */
  199 + BUG_ON(!ret && m.status);
  200 +
  201 + if (ret)
  202 + return ret;
  203 +
  204 + *val &= 0xffffff;
  205 +
  206 + dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val);
  207 +
  208 + return 0;
  209 +}
  210 +EXPORT_SYMBOL(mc13xxx_reg_read);
  211 +
  212 +int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val)
  213 +{
  214 + u32 buf;
  215 + struct spi_transfer t;
  216 + struct spi_message m;
  217 + int ret;
  218 +
  219 + BUG_ON(!mutex_is_locked(&mc13xxx->lock));
  220 +
  221 + dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val);
  222 +
  223 + if (offset > MC13XXX_NUMREGS || val > 0xffffff)
  224 + return -EINVAL;
  225 +
  226 + buf = 1 << 31 | offset << MC13XXX_REGOFFSET_SHIFT | val;
  227 +
  228 + memset(&t, 0, sizeof(t));
  229 +
  230 + t.tx_buf = &buf;
  231 + t.rx_buf = &buf;
  232 + t.len = sizeof(u32);
  233 +
  234 + spi_message_init(&m);
  235 + spi_message_add_tail(&t, &m);
  236 +
  237 + ret = spi_sync(mc13xxx->spidev, &m);
  238 +
  239 + BUG_ON(!ret && m.status);
  240 +
  241 + if (ret)
  242 + return ret;
  243 +
  244 + return 0;
  245 +}
  246 +EXPORT_SYMBOL(mc13xxx_reg_write);
  247 +
  248 +int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset,
  249 + u32 mask, u32 val)
  250 +{
  251 + int ret;
  252 + u32 valread;
  253 +
  254 + BUG_ON(val & ~mask);
  255 +
  256 + ret = mc13xxx_reg_read(mc13xxx, offset, &valread);
  257 + if (ret)
  258 + return ret;
  259 +
  260 + valread = (valread & ~mask) | val;
  261 +
  262 + return mc13xxx_reg_write(mc13xxx, offset, valread);
  263 +}
  264 +EXPORT_SYMBOL(mc13xxx_reg_rmw);
  265 +
  266 +int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq)
  267 +{
  268 + int ret;
  269 + unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1;
  270 + u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
  271 + u32 mask;
  272 +
  273 + if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
  274 + return -EINVAL;
  275 +
  276 + ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
  277 + if (ret)
  278 + return ret;
  279 +
  280 + if (mask & irqbit)
  281 + /* already masked */
  282 + return 0;
  283 +
  284 + return mc13xxx_reg_write(mc13xxx, offmask, mask | irqbit);
  285 +}
  286 +EXPORT_SYMBOL(mc13xxx_irq_mask);
  287 +
  288 +int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq)
  289 +{
  290 + int ret;
  291 + unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1;
  292 + u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
  293 + u32 mask;
  294 +
  295 + if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
  296 + return -EINVAL;
  297 +
  298 + ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
  299 + if (ret)
  300 + return ret;
  301 +
  302 + if (!(mask & irqbit))
  303 + /* already unmasked */
  304 + return 0;
  305 +
  306 + return mc13xxx_reg_write(mc13xxx, offmask, mask & ~irqbit);
  307 +}
  308 +EXPORT_SYMBOL(mc13xxx_irq_unmask);
  309 +
  310 +int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq,
  311 + int *enabled, int *pending)
  312 +{
  313 + int ret;
  314 + unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1;
  315 + unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1;
  316 + u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
  317 +
  318 + if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
  319 + return -EINVAL;
  320 +
  321 + if (enabled) {
  322 + u32 mask;
  323 +
  324 + ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
  325 + if (ret)
  326 + return ret;
  327 +
  328 + *enabled = mask & irqbit;
  329 + }
  330 +
  331 + if (pending) {
  332 + u32 stat;
  333 +
  334 + ret = mc13xxx_reg_read(mc13xxx, offstat, &stat);
  335 + if (ret)
  336 + return ret;
  337 +
  338 + *pending = stat & irqbit;
  339 + }
  340 +
  341 + return 0;
  342 +}
  343 +EXPORT_SYMBOL(mc13xxx_irq_status);
  344 +
  345 +int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq)
  346 +{
  347 + unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1;
  348 + unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
  349 +
  350 + BUG_ON(irq < 0 || irq >= MC13XXX_NUM_IRQ);
  351 +
  352 + return mc13xxx_reg_write(mc13xxx, offstat, val);
  353 +}
  354 +EXPORT_SYMBOL(mc13xxx_irq_ack);
  355 +
  356 +int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq,
  357 + irq_handler_t handler, const char *name, void *dev)
  358 +{
  359 + BUG_ON(!mutex_is_locked(&mc13xxx->lock));
  360 + BUG_ON(!handler);
  361 +
  362 + if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
  363 + return -EINVAL;
  364 +
  365 + if (mc13xxx->irqhandler[irq])
  366 + return -EBUSY;
  367 +
  368 + mc13xxx->irqhandler[irq] = handler;
  369 + mc13xxx->irqdata[irq] = dev;
  370 +
  371 + return 0;
  372 +}
  373 +EXPORT_SYMBOL(mc13xxx_irq_request_nounmask);
  374 +
  375 +int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
  376 + irq_handler_t handler, const char *name, void *dev)
  377 +{
  378 + int ret;
  379 +
  380 + ret = mc13xxx_irq_request_nounmask(mc13xxx, irq, handler, name, dev);
  381 + if (ret)
  382 + return ret;
  383 +
  384 + ret = mc13xxx_irq_unmask(mc13xxx, irq);
  385 + if (ret) {
  386 + mc13xxx->irqhandler[irq] = NULL;
  387 + mc13xxx->irqdata[irq] = NULL;
  388 + return ret;
  389 + }
  390 +
  391 + return 0;
  392 +}
  393 +EXPORT_SYMBOL(mc13xxx_irq_request);
  394 +
  395 +int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev)
  396 +{
  397 + int ret;
  398 + BUG_ON(!mutex_is_locked(&mc13xxx->lock));
  399 +
  400 + if (irq < 0 || irq >= MC13XXX_NUM_IRQ || !mc13xxx->irqhandler[irq] ||
  401 + mc13xxx->irqdata[irq] != dev)
  402 + return -EINVAL;
  403 +
  404 + ret = mc13xxx_irq_mask(mc13xxx, irq);
  405 + if (ret)
  406 + return ret;
  407 +
  408 + mc13xxx->irqhandler[irq] = NULL;
  409 + mc13xxx->irqdata[irq] = NULL;
  410 +
  411 + return 0;
  412 +}
  413 +EXPORT_SYMBOL(mc13xxx_irq_free);
  414 +
  415 +static inline irqreturn_t mc13xxx_irqhandler(struct mc13xxx *mc13xxx, int irq)
  416 +{
  417 + return mc13xxx->irqhandler[irq](irq, mc13xxx->irqdata[irq]);
  418 +}
  419 +
  420 +/*
  421 + * returns: number of handled irqs or negative error
  422 + * locking: holds mc13xxx->lock
  423 + */
  424 +static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx,
  425 + unsigned int offstat, unsigned int offmask, int baseirq)
  426 +{
  427 + u32 stat, mask;
  428 + int ret = mc13xxx_reg_read(mc13xxx, offstat, &stat);
  429 + int num_handled = 0;
  430 +
  431 + if (ret)
  432 + return ret;
  433 +
  434 + ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
  435 + if (ret)
  436 + return ret;
  437 +
  438 + while (stat & ~mask) {
  439 + int irq = __ffs(stat & ~mask);
  440 +
  441 + stat &= ~(1 << irq);
  442 +
  443 + if (likely(mc13xxx->irqhandler[baseirq + irq])) {
  444 + irqreturn_t handled;
  445 +
  446 + handled = mc13xxx_irqhandler(mc13xxx, baseirq + irq);
  447 + if (handled == IRQ_HANDLED)
  448 + num_handled++;
  449 + } else {
  450 + dev_err(&mc13xxx->spidev->dev,
  451 + "BUG: irq %u but no handler\n",
  452 + baseirq + irq);
  453 +
  454 + mask |= 1 << irq;
  455 +
  456 + ret = mc13xxx_reg_write(mc13xxx, offmask, mask);
  457 + }
  458 + }
  459 +
  460 + return num_handled;
  461 +}
  462 +
  463 +static irqreturn_t mc13xxx_irq_thread(int irq, void *data)
  464 +{
  465 + struct mc13xxx *mc13xxx = data;
  466 + irqreturn_t ret;
  467 + int handled = 0;
  468 +
  469 + mc13xxx_lock(mc13xxx);
  470 +
  471 + ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT0,
  472 + MC13XXX_IRQMASK0, 0);
  473 + if (ret > 0)
  474 + handled = 1;
  475 +
  476 + ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT1,
  477 + MC13XXX_IRQMASK1, 24);
  478 + if (ret > 0)
  479 + handled = 1;
  480 +
  481 + mc13xxx_unlock(mc13xxx);
  482 +
  483 + return IRQ_RETVAL(handled);
  484 +}
  485 +
  486 +enum mc13xxx_id {
  487 + MC13XXX_ID_MC13783,
  488 + MC13XXX_ID_MC13892,
  489 + MC13XXX_ID_INVALID,
  490 +};
  491 +
  492 +const char *mc13xxx_chipname[] = {
  493 + [MC13XXX_ID_MC13783] = "mc13783",
  494 + [MC13XXX_ID_MC13892] = "mc13892",
  495 +};
  496 +
  497 +#define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask))
  498 +static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id)
  499 +{
  500 + u32 icid;
  501 + u32 revision;
  502 + const char *name;
  503 + int ret;
  504 +
  505 + ret = mc13xxx_reg_read(mc13xxx, 46, &icid);
  506 + if (ret)
  507 + return ret;
  508 +
  509 + icid = (icid >> 6) & 0x7;
  510 +
  511 + switch (icid) {
  512 + case 2:
  513 + *id = MC13XXX_ID_MC13783;
  514 + name = "mc13783";
  515 + break;
  516 + case 7:
  517 + *id = MC13XXX_ID_MC13892;
  518 + name = "mc13892";
  519 + break;
  520 + default:
  521 + *id = MC13XXX_ID_INVALID;
  522 + break;
  523 + }
  524 +
  525 + if (*id == MC13XXX_ID_MC13783 || *id == MC13XXX_ID_MC13892) {
  526 + ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision);
  527 + if (ret)
  528 + return ret;
  529 +
  530 + dev_info(&mc13xxx->spidev->dev, "%s: rev: %d.%d, "
  531 + "fin: %d, fab: %d, icid: %d/%d\n",
  532 + mc13xxx_chipname[*id],
  533 + maskval(revision, MC13XXX_REVISION_REVFULL),
  534 + maskval(revision, MC13XXX_REVISION_REVMETAL),
  535 + maskval(revision, MC13XXX_REVISION_FIN),
  536 + maskval(revision, MC13XXX_REVISION_FAB),
  537 + maskval(revision, MC13XXX_REVISION_ICID),
  538 + maskval(revision, MC13XXX_REVISION_ICIDCODE));
  539 + }
  540 +
  541 + if (*id != MC13XXX_ID_INVALID) {
  542 + const struct spi_device_id *devid =
  543 + spi_get_device_id(mc13xxx->spidev);
  544 + if (!devid || devid->driver_data != *id)
  545 + dev_warn(&mc13xxx->spidev->dev, "device id doesn't "
  546 + "match auto detection!\n");
  547 + }
  548 +
  549 + return 0;
  550 +}
  551 +
  552 +static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx)
  553 +{
  554 + const struct spi_device_id *devid =
  555 + spi_get_device_id(mc13xxx->spidev);
  556 +
  557 + if (!devid)
  558 + return NULL;
  559 +
  560 + return mc13xxx_chipname[devid->driver_data];
  561 +}
  562 +
  563 +#include <linux/mfd/mc13783.h>
  564 +
  565 +int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
  566 +{
  567 + struct mc13xxx_platform_data *pdata =
  568 + dev_get_platdata(&mc13xxx->spidev->dev);
  569 +
  570 + return pdata->flags;
  571 +}
  572 +EXPORT_SYMBOL(mc13xxx_get_flags);
  573 +
  574 +#define MC13783_ADC1_CHAN0_SHIFT 5
  575 +#define MC13783_ADC1_CHAN1_SHIFT 8
  576 +
  577 +struct mc13xxx_adcdone_data {
  578 + struct mc13xxx *mc13xxx;
  579 + struct completion done;
  580 +};
  581 +
  582 +static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
  583 +{
  584 + struct mc13xxx_adcdone_data *adcdone_data = data;
  585 +
  586 + mc13xxx_irq_ack(adcdone_data->mc13xxx, irq);
  587 +
  588 + complete_all(&adcdone_data->done);
  589 +
  590 + return IRQ_HANDLED;
  591 +}
  592 +
  593 +#define MC13783_ADC_WORKING (1 << 0)
  594 +
  595 +int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
  596 + unsigned int channel, unsigned int *sample)
  597 +{
  598 + struct mc13xxx *mc13xxx = &mc13783->mc13xxx;
  599 + u32 adc0, adc1, old_adc0;
  600 + int i, ret;
  601 + struct mc13xxx_adcdone_data adcdone_data = {
  602 + .mc13xxx = mc13xxx,
  603 + };
  604 + init_completion(&adcdone_data.done);
  605 +
  606 + dev_dbg(&mc13xxx->spidev->dev, "%s\n", __func__);
  607 +
  608 + mc13xxx_lock(mc13xxx);
  609 +
  610 + if (mc13783->adcflags & MC13783_ADC_WORKING) {
  611 + ret = -EBUSY;
  612 + goto out;
  613 + }
  614 +
  615 + mc13783->adcflags |= MC13783_ADC_WORKING;
  616 +
  617 + mc13xxx_reg_read(mc13xxx, MC13783_ADC0, &old_adc0);
  618 +
  619 + adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
  620 + adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC;
  621 +
  622 + if (channel > 7)
  623 + adc1 |= MC13783_ADC1_ADSEL;
  624 +
  625 + switch (mode) {
  626 + case MC13783_ADC_MODE_TS:
  627 + adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_TSMOD0 |
  628 + MC13783_ADC0_TSMOD1;
  629 + adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
  630 + break;
  631 +
  632 + case MC13783_ADC_MODE_SINGLE_CHAN:
  633 + adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
  634 + adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
  635 + adc1 |= MC13783_ADC1_RAND;
  636 + break;
  637 +
  638 + case MC13783_ADC_MODE_MULT_CHAN:
  639 + adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
  640 + adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
  641 + break;
  642 +
  643 + default:
  644 + mc13783_unlock(mc13783);
  645 + return -EINVAL;
  646 + }
  647 +
  648 + dev_dbg(&mc13783->mc13xxx.spidev->dev, "%s: request irq\n", __func__);
  649 + mc13xxx_irq_request(mc13xxx, MC13783_IRQ_ADCDONE,
  650 + mc13783_handler_adcdone, __func__, &adcdone_data);
  651 + mc13xxx_irq_ack(mc13xxx, MC13783_IRQ_ADCDONE);
  652 +
  653 + mc13xxx_reg_write(mc13xxx, MC13783_ADC0, adc0);
  654 + mc13xxx_reg_write(mc13xxx, MC13783_ADC1, adc1);
  655 +
  656 + mc13xxx_unlock(mc13xxx);
  657 +
  658 + ret = wait_for_completion_interruptible_timeout(&adcdone_data.done, HZ);
  659 +
  660 + if (!ret)
  661 + ret = -ETIMEDOUT;
  662 +
  663 + mc13xxx_lock(mc13xxx);
  664 +
  665 + mc13xxx_irq_free(mc13xxx, MC13783_IRQ_ADCDONE, &adcdone_data);
  666 +
  667 + if (ret > 0)
  668 + for (i = 0; i < 4; ++i) {
  669 + ret = mc13xxx_reg_read(mc13xxx,
  670 + MC13783_ADC2, &sample[i]);
  671 + if (ret)
  672 + break;
  673 + }
  674 +
  675 + if (mode == MC13783_ADC_MODE_TS)
  676 + /* restore TSMOD */
  677 + mc13xxx_reg_write(mc13xxx, MC13783_ADC0, old_adc0);
  678 +
  679 + mc13783->adcflags &= ~MC13783_ADC_WORKING;
  680 +out:
  681 + mc13xxx_unlock(mc13xxx);
  682 +
  683 + return ret;
  684 +}
  685 +EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
  686 +
  687 +static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
  688 + const char *format, void *pdata, size_t pdata_size)
  689 +{
  690 + char buf[30];
  691 + const char *name = mc13xxx_get_chipname(mc13xxx);
  692 +
  693 + struct mfd_cell cell = {
  694 + .platform_data = pdata,
  695 + .data_size = pdata_size,
  696 + };
  697 +
  698 + /* there is no asnprintf in the kernel :-( */
  699 + if (snprintf(buf, sizeof(buf), format, name) > sizeof(buf))
  700 + return -E2BIG;
  701 +
  702 + cell.name = kmemdup(buf, strlen(buf) + 1, GFP_KERNEL);
  703 + if (!cell.name)
  704 + return -ENOMEM;
  705 +
  706 + return mfd_add_devices(&mc13xxx->spidev->dev, -1, &cell, 1, NULL, 0);
  707 +}
  708 +
  709 +static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
  710 +{
  711 + return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0);
  712 +}
  713 +
  714 +static int mc13xxx_probe(struct spi_device *spi)
  715 +{
  716 + struct mc13xxx *mc13xxx;
  717 + struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev);
  718 + enum mc13xxx_id id;
  719 + int ret;
  720 +
  721 + mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
  722 + if (!mc13xxx)
  723 + return -ENOMEM;
  724 +
  725 + dev_set_drvdata(&spi->dev, mc13xxx);
  726 + spi->mode = SPI_MODE_0 | SPI_CS_HIGH;
  727 + spi->bits_per_word = 32;
  728 + spi_setup(spi);
  729 +
  730 + mc13xxx->spidev = spi;
  731 +
  732 + mutex_init(&mc13xxx->lock);
  733 + mc13xxx_lock(mc13xxx);
  734 +
  735 + ret = mc13xxx_identify(mc13xxx, &id);
  736 + if (ret || id == MC13XXX_ID_INVALID)
  737 + goto err_revision;
  738 +
  739 + /* mask all irqs */
  740 + ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK0, 0x00ffffff);
  741 + if (ret)
  742 + goto err_mask;
  743 +
  744 + ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK1, 0x00ffffff);
  745 + if (ret)
  746 + goto err_mask;
  747 +
  748 + ret = request_threaded_irq(spi->irq, NULL, mc13xxx_irq_thread,
  749 + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx);
  750 +
  751 + if (ret) {
  752 +err_mask:
  753 +err_revision:
  754 + mutex_unlock(&mc13xxx->lock);
  755 + dev_set_drvdata(&spi->dev, NULL);
  756 + kfree(mc13xxx);
  757 + return ret;
  758 + }
  759 +
  760 + mc13xxx_unlock(mc13xxx);
  761 +
  762 + if (pdata->flags & MC13XXX_USE_ADC)
  763 + mc13xxx_add_subdevice(mc13xxx, "%s-adc");
  764 +
  765 + if (pdata->flags & MC13XXX_USE_CODEC)
  766 + mc13xxx_add_subdevice(mc13xxx, "%s-codec");
  767 +
  768 + if (pdata->flags & MC13XXX_USE_REGULATOR) {
  769 + struct mc13xxx_regulator_platform_data regulator_pdata = {
  770 + .num_regulators = pdata->num_regulators,
  771 + .regulators = pdata->regulators,
  772 + };
  773 +
  774 + mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
  775 + &regulator_pdata, sizeof(regulator_pdata));
  776 + }
  777 +
  778 + if (pdata->flags & MC13XXX_USE_RTC)
  779 + mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
  780 +
  781 + if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
  782 + mc13xxx_add_subdevice(mc13xxx, "%s-ts");
  783 +
  784 + if (pdata->flags & MC13XXX_USE_LED) {
  785 + mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
  786 + pdata->leds, sizeof(*pdata->leds));
  787 + }
  788 +
  789 + return 0;
  790 +}
  791 +
  792 +static int __devexit mc13xxx_remove(struct spi_device *spi)
  793 +{
  794 + struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev);
  795 +
  796 + free_irq(mc13xxx->spidev->irq, mc13xxx);
  797 +
  798 + mfd_remove_devices(&spi->dev);
  799 +
  800 + return 0;
  801 +}
  802 +
  803 +static const struct spi_device_id mc13xxx_device_id[] = {
  804 + {
  805 + .name = "mc13783",
  806 + .driver_data = MC13XXX_ID_MC13783,
  807 + }, {
  808 + .name = "mc13892",
  809 + .driver_data = MC13XXX_ID_MC13892,
  810 + }, {
  811 + /* sentinel */
  812 + }
  813 +};
  814 +
  815 +static struct spi_driver mc13xxx_driver = {
  816 + .id_table = mc13xxx_device_id,
  817 + .driver = {
  818 + .name = "mc13xxx",
  819 + .bus = &spi_bus_type,
  820 + .owner = THIS_MODULE,
  821 + },
  822 + .probe = mc13xxx_probe,
  823 + .remove = __devexit_p(mc13xxx_remove),
  824 +};
  825 +
  826 +static int __init mc13xxx_init(void)
  827 +{
  828 + return spi_register_driver(&mc13xxx_driver);
  829 +}
  830 +subsys_initcall(mc13xxx_init);
  831 +
  832 +static void __exit mc13xxx_exit(void)
  833 +{
  834 + spi_unregister_driver(&mc13xxx_driver);
  835 +}
  836 +module_exit(mc13xxx_exit);
  837 +
  838 +MODULE_DESCRIPTION("Core driver for Freescale MC13XXX PMIC");
  839 +MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
  840 +MODULE_LICENSE("GPL v2");
include/linux/mfd/mc13783.h
1 1 /*
2   - * Copyright 2009 Pengutronix
  2 + * Copyright 2009-2010 Pengutronix
3 3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 4 *
5 5 * This program is free software; you can redistribute it and/or modify it under
6 6  
7 7  
8 8  
9 9  
10 10  
11 11  
... ... @@ -9,32 +9,85 @@
9 9 #ifndef __LINUX_MFD_MC13783_H
10 10 #define __LINUX_MFD_MC13783_H
11 11  
12   -#include <linux/interrupt.h>
  12 +#include <linux/mfd/mc13xxx.h>
13 13  
14 14 struct mc13783;
15 15  
16   -void mc13783_lock(struct mc13783 *mc13783);
17   -void mc13783_unlock(struct mc13783 *mc13783);
  16 +struct mc13xxx *mc13783_to_mc13xxx(struct mc13783 *mc13783);
18 17  
19   -int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val);
20   -int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val);
21   -int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
22   - u32 mask, u32 val);
  18 +static inline void mc13783_lock(struct mc13783 *mc13783)
  19 +{
  20 + mc13xxx_lock(mc13783_to_mc13xxx(mc13783));
  21 +}
23 22  
24   -int mc13783_get_flags(struct mc13783 *mc13783);
  23 +static inline void mc13783_unlock(struct mc13783 *mc13783)
  24 +{
  25 + mc13xxx_unlock(mc13783_to_mc13xxx(mc13783));
  26 +}
25 27  
26   -int mc13783_irq_request(struct mc13783 *mc13783, int irq,
27   - irq_handler_t handler, const char *name, void *dev);
28   -int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
29   - irq_handler_t handler, const char *name, void *dev);
30   -int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev);
  28 +static inline int mc13783_reg_read(struct mc13783 *mc13783,
  29 + unsigned int offset, u32 *val)
  30 +{
  31 + return mc13xxx_reg_read(mc13783_to_mc13xxx(mc13783), offset, val);
  32 +}
31 33  
32   -int mc13783_irq_mask(struct mc13783 *mc13783, int irq);
33   -int mc13783_irq_unmask(struct mc13783 *mc13783, int irq);
34   -int mc13783_irq_status(struct mc13783 *mc13783, int irq,
35   - int *enabled, int *pending);
36   -int mc13783_irq_ack(struct mc13783 *mc13783, int irq);
  34 +static inline int mc13783_reg_write(struct mc13783 *mc13783,
  35 + unsigned int offset, u32 val)
  36 +{
  37 + return mc13xxx_reg_write(mc13783_to_mc13xxx(mc13783), offset, val);
  38 +}
37 39  
  40 +static inline int mc13783_reg_rmw(struct mc13783 *mc13783,
  41 + unsigned int offset, u32 mask, u32 val)
  42 +{
  43 + return mc13xxx_reg_rmw(mc13783_to_mc13xxx(mc13783), offset, mask, val);
  44 +}
  45 +
  46 +static inline int mc13783_get_flags(struct mc13783 *mc13783)
  47 +{
  48 + return mc13xxx_get_flags(mc13783_to_mc13xxx(mc13783));
  49 +}
  50 +
  51 +static inline int mc13783_irq_request(struct mc13783 *mc13783, int irq,
  52 + irq_handler_t handler, const char *name, void *dev)
  53 +{
  54 + return mc13xxx_irq_request(mc13783_to_mc13xxx(mc13783), irq,
  55 + handler, name, dev);
  56 +}
  57 +
  58 +static inline int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
  59 + irq_handler_t handler, const char *name, void *dev)
  60 +{
  61 + return mc13xxx_irq_request_nounmask(mc13783_to_mc13xxx(mc13783), irq,
  62 + handler, name, dev);
  63 +}
  64 +
  65 +static inline int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
  66 +{
  67 + return mc13xxx_irq_free(mc13783_to_mc13xxx(mc13783), irq, dev);
  68 +}
  69 +
  70 +static inline int mc13783_irq_mask(struct mc13783 *mc13783, int irq)
  71 +{
  72 + return mc13xxx_irq_mask(mc13783_to_mc13xxx(mc13783), irq);
  73 +}
  74 +
  75 +static inline int mc13783_irq_unmask(struct mc13783 *mc13783, int irq)
  76 +{
  77 + return mc13xxx_irq_unmask(mc13783_to_mc13xxx(mc13783), irq);
  78 +}
  79 +static inline int mc13783_irq_status(struct mc13783 *mc13783, int irq,
  80 + int *enabled, int *pending)
  81 +{
  82 + return mc13xxx_irq_status(mc13783_to_mc13xxx(mc13783),
  83 + irq, enabled, pending);
  84 +}
  85 +
  86 +static inline int mc13783_irq_ack(struct mc13783 *mc13783, int irq)
  87 +{
  88 + return mc13xxx_irq_ack(mc13783_to_mc13xxx(mc13783), irq);
  89 +}
  90 +
38 91 #define MC13783_ADC0 43
39 92 #define MC13783_ADC0_ADREFEN (1 << 10)
40 93 #define MC13783_ADC0_ADREFMODE (1 << 11)
41 94  
42 95  
... ... @@ -48,97 +101,19 @@
48 101 MC13783_ADC0_TSMOD1 | \
49 102 MC13783_ADC0_TSMOD2)
50 103  
51   -struct mc13783_led_platform_data {
52   -#define MC13783_LED_MD 0
53   -#define MC13783_LED_AD 1
54   -#define MC13783_LED_KP 2
55   -#define MC13783_LED_R1 3
56   -#define MC13783_LED_G1 4
57   -#define MC13783_LED_B1 5
58   -#define MC13783_LED_R2 6
59   -#define MC13783_LED_G2 7
60   -#define MC13783_LED_B2 8
61   -#define MC13783_LED_R3 9
62   -#define MC13783_LED_G3 10
63   -#define MC13783_LED_B3 11
64   -#define MC13783_LED_MAX MC13783_LED_B3
65   - int id;
66   - const char *name;
67   - const char *default_trigger;
  104 +#define mc13783_regulator_init_data mc13xxx_regulator_init_data
  105 +#define mc13783_regulator_platform_data mc13xxx_regulator_platform_data
  106 +#define mc13783_led_platform_data mc13xxx_led_platform_data
  107 +#define mc13783_leds_platform_data mc13xxx_leds_platform_data
68 108  
69   -/* Three or two bits current selection depending on the led */
70   - char max_current;
71   -};
  109 +#define mc13783_platform_data mc13xxx_platform_data
  110 +#define MC13783_USE_TOUCHSCREEN MC13XXX_USE_TOUCHSCREEN
  111 +#define MC13783_USE_CODEC MC13XXX_USE_CODEC
  112 +#define MC13783_USE_ADC MC13XXX_USE_ADC
  113 +#define MC13783_USE_RTC MC13XXX_USE_RTC
  114 +#define MC13783_USE_REGULATOR MC13XXX_USE_REGULATOR
  115 +#define MC13783_USE_LED MC13XXX_USE_LED
72 116  
73   -struct mc13783_leds_platform_data {
74   - int num_leds;
75   - struct mc13783_led_platform_data *led;
76   -
77   -#define MC13783_LED_TRIODE_MD (1 << 0)
78   -#define MC13783_LED_TRIODE_AD (1 << 1)
79   -#define MC13783_LED_TRIODE_KP (1 << 2)
80   -#define MC13783_LED_BOOST_EN (1 << 3)
81   -#define MC13783_LED_TC1HALF (1 << 4)
82   -#define MC13783_LED_SLEWLIMTC (1 << 5)
83   -#define MC13783_LED_SLEWLIMBL (1 << 6)
84   -#define MC13783_LED_TRIODE_TC1 (1 << 7)
85   -#define MC13783_LED_TRIODE_TC2 (1 << 8)
86   -#define MC13783_LED_TRIODE_TC3 (1 << 9)
87   - int flags;
88   -
89   -#define MC13783_LED_AB_DISABLED 0
90   -#define MC13783_LED_AB_MD1 1
91   -#define MC13783_LED_AB_MD12 2
92   -#define MC13783_LED_AB_MD123 3
93   -#define MC13783_LED_AB_MD1234 4
94   -#define MC13783_LED_AB_MD1234_AD1 5
95   -#define MC13783_LED_AB_MD1234_AD12 6
96   -#define MC13783_LED_AB_MD1_AD 7
97   - char abmode;
98   -
99   -#define MC13783_LED_ABREF_200MV 0
100   -#define MC13783_LED_ABREF_400MV 1
101   -#define MC13783_LED_ABREF_600MV 2
102   -#define MC13783_LED_ABREF_800MV 3
103   - char abref;
104   -
105   -#define MC13783_LED_PERIOD_10MS 0
106   -#define MC13783_LED_PERIOD_100MS 1
107   -#define MC13783_LED_PERIOD_500MS 2
108   -#define MC13783_LED_PERIOD_2S 3
109   - char bl_period;
110   - char tc1_period;
111   - char tc2_period;
112   - char tc3_period;
113   -};
114   -
115   -/* to be cleaned up */
116   -struct regulator_init_data;
117   -
118   -struct mc13783_regulator_init_data {
119   - int id;
120   - struct regulator_init_data *init_data;
121   -};
122   -
123   -struct mc13783_regulator_platform_data {
124   - int num_regulators;
125   - struct mc13783_regulator_init_data *regulators;
126   -};
127   -
128   -struct mc13783_platform_data {
129   - int num_regulators;
130   - struct mc13783_regulator_init_data *regulators;
131   - struct mc13783_leds_platform_data *leds;
132   -
133   -#define MC13783_USE_TOUCHSCREEN (1 << 0)
134   -#define MC13783_USE_CODEC (1 << 1)
135   -#define MC13783_USE_ADC (1 << 2)
136   -#define MC13783_USE_RTC (1 << 3)
137   -#define MC13783_USE_REGULATOR (1 << 4)
138   -#define MC13783_USE_LED (1 << 5)
139   - unsigned int flags;
140   -};
141   -
142 117 #define MC13783_ADC_MODE_TS 1
143 118 #define MC13783_ADC_MODE_SINGLE_CHAN 2
144 119 #define MC13783_ADC_MODE_MULT_CHAN 3
145 120  
146 121  
147 122  
148 123  
149 124  
150 125  
151 126  
... ... @@ -181,47 +156,47 @@
181 156 #define MC13783_REGU_PWGT1SPI 31
182 157 #define MC13783_REGU_PWGT2SPI 32
183 158  
184   -#define MC13783_IRQ_ADCDONE 0
185   -#define MC13783_IRQ_ADCBISDONE 1
186   -#define MC13783_IRQ_TS 2
  159 +#define MC13783_IRQ_ADCDONE MC13XXX_IRQ_ADCDONE
  160 +#define MC13783_IRQ_ADCBISDONE MC13XXX_IRQ_ADCBISDONE
  161 +#define MC13783_IRQ_TS MC13XXX_IRQ_TS
187 162 #define MC13783_IRQ_WHIGH 3
188 163 #define MC13783_IRQ_WLOW 4
189   -#define MC13783_IRQ_CHGDET 6
  164 +#define MC13783_IRQ_CHGDET MC13XXX_IRQ_CHGDET
190 165 #define MC13783_IRQ_CHGOV 7
191   -#define MC13783_IRQ_CHGREV 8
192   -#define MC13783_IRQ_CHGSHORT 9
193   -#define MC13783_IRQ_CCCV 10
194   -#define MC13783_IRQ_CHGCURR 11
195   -#define MC13783_IRQ_BPON 12
196   -#define MC13783_IRQ_LOBATL 13
197   -#define MC13783_IRQ_LOBATH 14
  166 +#define MC13783_IRQ_CHGREV MC13XXX_IRQ_CHGREV
  167 +#define MC13783_IRQ_CHGSHORT MC13XXX_IRQ_CHGSHORT
  168 +#define MC13783_IRQ_CCCV MC13XXX_IRQ_CCCV
  169 +#define MC13783_IRQ_CHGCURR MC13XXX_IRQ_CHGCURR
  170 +#define MC13783_IRQ_BPON MC13XXX_IRQ_BPON
  171 +#define MC13783_IRQ_LOBATL MC13XXX_IRQ_LOBATL
  172 +#define MC13783_IRQ_LOBATH MC13XXX_IRQ_LOBATH
198 173 #define MC13783_IRQ_UDP 15
199 174 #define MC13783_IRQ_USB 16
200 175 #define MC13783_IRQ_ID 19
201 176 #define MC13783_IRQ_SE1 21
202 177 #define MC13783_IRQ_CKDET 22
203 178 #define MC13783_IRQ_UDM 23
204   -#define MC13783_IRQ_1HZ 24
205   -#define MC13783_IRQ_TODA 25
  179 +#define MC13783_IRQ_1HZ MC13XXX_IRQ_1HZ
  180 +#define MC13783_IRQ_TODA MC13XXX_IRQ_TODA
206 181 #define MC13783_IRQ_ONOFD1 27
207 182 #define MC13783_IRQ_ONOFD2 28
208 183 #define MC13783_IRQ_ONOFD3 29
209   -#define MC13783_IRQ_SYSRST 30
210   -#define MC13783_IRQ_RTCRST 31
211   -#define MC13783_IRQ_PC 32
212   -#define MC13783_IRQ_WARM 33
213   -#define MC13783_IRQ_MEMHLD 34
  184 +#define MC13783_IRQ_SYSRST MC13XXX_IRQ_SYSRST
  185 +#define MC13783_IRQ_RTCRST MC13XXX_IRQ_RTCRST
  186 +#define MC13783_IRQ_PC MC13XXX_IRQ_PC
  187 +#define MC13783_IRQ_WARM MC13XXX_IRQ_WARM
  188 +#define MC13783_IRQ_MEMHLD MC13XXX_IRQ_MEMHLD
214 189 #define MC13783_IRQ_PWRRDY 35
215   -#define MC13783_IRQ_THWARNL 36
216   -#define MC13783_IRQ_THWARNH 37
217   -#define MC13783_IRQ_CLK 38
  190 +#define MC13783_IRQ_THWARNL MC13XXX_IRQ_THWARNL
  191 +#define MC13783_IRQ_THWARNH MC13XXX_IRQ_THWARNH
  192 +#define MC13783_IRQ_CLK MC13XXX_IRQ_CLK
218 193 #define MC13783_IRQ_SEMAF 39
219 194 #define MC13783_IRQ_MC2B 41
220 195 #define MC13783_IRQ_HSDET 42
221 196 #define MC13783_IRQ_HSL 43
222 197 #define MC13783_IRQ_ALSPTH 44
223 198 #define MC13783_IRQ_AHSSHORT 45
224   -#define MC13783_NUM_IRQ 46
  199 +#define MC13783_NUM_IRQ MC13XXX_NUM_IRQ
225 200  
226   -#endif /* __LINUX_MFD_MC13783_H */
  201 +#endif /* ifndef __LINUX_MFD_MC13783_H */
include/linux/mfd/mc13xxx.h
  1 +/*
  2 + * Copyright 2009-2010 Pengutronix
  3 + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
  4 + *
  5 + * This program is free software; you can redistribute it and/or modify it under
  6 + * the terms of the GNU General Public License version 2 as published by the
  7 + * Free Software Foundation.
  8 + */
  9 +#ifndef __LINUX_MFD_MC13XXX_H
  10 +#define __LINUX_MFD_MC13XXX_H
  11 +
  12 +#include <linux/interrupt.h>
  13 +
  14 +struct mc13xxx;
  15 +
  16 +void mc13xxx_lock(struct mc13xxx *mc13xxx);
  17 +void mc13xxx_unlock(struct mc13xxx *mc13xxx);
  18 +
  19 +int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val);
  20 +int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val);
  21 +int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset,
  22 + u32 mask, u32 val);
  23 +
  24 +int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
  25 +
  26 +int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
  27 + irq_handler_t handler, const char *name, void *dev);
  28 +int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq,
  29 + irq_handler_t handler, const char *name, void *dev);
  30 +int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev);
  31 +
  32 +int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq);
  33 +int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq);
  34 +int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq,
  35 + int *enabled, int *pending);
  36 +int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq);
  37 +
  38 +int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
  39 +
  40 +#define MC13XXX_IRQ_ADCDONE 0
  41 +#define MC13XXX_IRQ_ADCBISDONE 1
  42 +#define MC13XXX_IRQ_TS 2
  43 +#define MC13XXX_IRQ_CHGDET 6
  44 +#define MC13XXX_IRQ_CHGREV 8
  45 +#define MC13XXX_IRQ_CHGSHORT 9
  46 +#define MC13XXX_IRQ_CCCV 10
  47 +#define MC13XXX_IRQ_CHGCURR 11
  48 +#define MC13XXX_IRQ_BPON 12
  49 +#define MC13XXX_IRQ_LOBATL 13
  50 +#define MC13XXX_IRQ_LOBATH 14
  51 +#define MC13XXX_IRQ_1HZ 24
  52 +#define MC13XXX_IRQ_TODA 25
  53 +#define MC13XXX_IRQ_SYSRST 30
  54 +#define MC13XXX_IRQ_RTCRST 31
  55 +#define MC13XXX_IRQ_PC 32
  56 +#define MC13XXX_IRQ_WARM 33
  57 +#define MC13XXX_IRQ_MEMHLD 34
  58 +#define MC13XXX_IRQ_THWARNL 36
  59 +#define MC13XXX_IRQ_THWARNH 37
  60 +#define MC13XXX_IRQ_CLK 38
  61 +
  62 +#define MC13XXX_NUM_IRQ 46
  63 +
  64 +struct regulator_init_data;
  65 +
  66 +struct mc13xxx_regulator_init_data {
  67 + int id;
  68 + struct regulator_init_data *init_data;
  69 +};
  70 +
  71 +struct mc13xxx_regulator_platform_data {
  72 + int num_regulators;
  73 + struct mc13xxx_regulator_init_data *regulators;
  74 +};
  75 +
  76 +struct mc13xxx_led_platform_data {
  77 +#define MC13783_LED_MD 0
  78 +#define MC13783_LED_AD 1
  79 +#define MC13783_LED_KP 2
  80 +#define MC13783_LED_R1 3
  81 +#define MC13783_LED_G1 4
  82 +#define MC13783_LED_B1 5
  83 +#define MC13783_LED_R2 6
  84 +#define MC13783_LED_G2 7
  85 +#define MC13783_LED_B2 8
  86 +#define MC13783_LED_R3 9
  87 +#define MC13783_LED_G3 10
  88 +#define MC13783_LED_B3 11
  89 +#define MC13783_LED_MAX MC13783_LED_B3
  90 + int id;
  91 + const char *name;
  92 + const char *default_trigger;
  93 +
  94 +/* Three or two bits current selection depending on the led */
  95 + char max_current;
  96 +};
  97 +
  98 +struct mc13xxx_leds_platform_data {
  99 + int num_leds;
  100 + struct mc13xxx_led_platform_data *led;
  101 +
  102 +#define MC13783_LED_TRIODE_MD (1 << 0)
  103 +#define MC13783_LED_TRIODE_AD (1 << 1)
  104 +#define MC13783_LED_TRIODE_KP (1 << 2)
  105 +#define MC13783_LED_BOOST_EN (1 << 3)
  106 +#define MC13783_LED_TC1HALF (1 << 4)
  107 +#define MC13783_LED_SLEWLIMTC (1 << 5)
  108 +#define MC13783_LED_SLEWLIMBL (1 << 6)
  109 +#define MC13783_LED_TRIODE_TC1 (1 << 7)
  110 +#define MC13783_LED_TRIODE_TC2 (1 << 8)
  111 +#define MC13783_LED_TRIODE_TC3 (1 << 9)
  112 + int flags;
  113 +
  114 +#define MC13783_LED_AB_DISABLED 0
  115 +#define MC13783_LED_AB_MD1 1
  116 +#define MC13783_LED_AB_MD12 2
  117 +#define MC13783_LED_AB_MD123 3
  118 +#define MC13783_LED_AB_MD1234 4
  119 +#define MC13783_LED_AB_MD1234_AD1 5
  120 +#define MC13783_LED_AB_MD1234_AD12 6
  121 +#define MC13783_LED_AB_MD1_AD 7
  122 + char abmode;
  123 +
  124 +#define MC13783_LED_ABREF_200MV 0
  125 +#define MC13783_LED_ABREF_400MV 1
  126 +#define MC13783_LED_ABREF_600MV 2
  127 +#define MC13783_LED_ABREF_800MV 3
  128 + char abref;
  129 +
  130 +#define MC13783_LED_PERIOD_10MS 0
  131 +#define MC13783_LED_PERIOD_100MS 1
  132 +#define MC13783_LED_PERIOD_500MS 2
  133 +#define MC13783_LED_PERIOD_2S 3
  134 + char bl_period;
  135 + char tc1_period;
  136 + char tc2_period;
  137 + char tc3_period;
  138 +};
  139 +
  140 +struct mc13xxx_platform_data {
  141 +#define MC13XXX_USE_TOUCHSCREEN (1 << 0)
  142 +#define MC13XXX_USE_CODEC (1 << 1)
  143 +#define MC13XXX_USE_ADC (1 << 2)
  144 +#define MC13XXX_USE_RTC (1 << 3)
  145 +#define MC13XXX_USE_REGULATOR (1 << 4)
  146 +#define MC13XXX_USE_LED (1 << 5)
  147 + unsigned int flags;
  148 +
  149 + int num_regulators;
  150 + struct mc13xxx_regulator_init_data *regulators;
  151 + struct mc13xxx_leds_platform_data *leds;
  152 +};
  153 +
  154 +#endif /* ifndef __LINUX_MFD_MC13XXX_H */