aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/mc13783-core.c755
-rw-r--r--include/linux/mfd/mc13783-private.h208
-rw-r--r--include/linux/mfd/mc13783.h120
3 files changed, 617 insertions, 466 deletions
diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c
index e354d2912ef1..dc1add0c4949 100644
--- a/drivers/mfd/mc13783-core.c
+++ b/drivers/mfd/mc13783-core.c
@@ -1,286 +1,549 @@
1/* 1/*
2 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> 2 * Copyright 2009 Pengutronix
3 * 3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 * This code is in parts based on wm8350-core.c and pcf50633-core.c
5 *
6 * Initial development of this code was funded by
7 * Phytec Messtechnik GmbH, http://www.phytec.de
8 * 4 *
9 * This program is free software; you can redistribute it and/or modify 5 * loosely based on an earlier driver that has
10 * it under the terms of the GNU General Public License as published by 6 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 * 7 *
19 * You should have received a copy of the GNU General Public License 8 * This program is free software; you can redistribute it and/or modify it under
20 * along with this program; if not, write to the Free Software 9 * the terms of the GNU General Public License version 2 as published by the
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 10 * Free Software Foundation.
22 */ 11 */
23
24#include <linux/mfd/mc13783-private.h>
25#include <linux/platform_device.h>
26#include <linux/mfd/mc13783.h>
27#include <linux/completion.h>
28#include <linux/interrupt.h>
29#include <linux/mfd/core.h>
30#include <linux/spi/spi.h>
31#include <linux/uaccess.h>
32#include <linux/kernel.h>
33#include <linux/module.h> 12#include <linux/module.h>
34#include <linux/init.h> 13#include <linux/spi/spi.h>
35#include <linux/slab.h> 14#include <linux/mfd/core.h>
36#include <linux/irq.h> 15#include <linux/mfd/mc13783-private.h>
16
17#define MC13783_IRQSTAT0 0
18#define MC13783_IRQSTAT0_ADCDONEI (1 << 0)
19#define MC13783_IRQSTAT0_ADCBISDONEI (1 << 1)
20#define MC13783_IRQSTAT0_TSI (1 << 2)
21#define MC13783_IRQSTAT0_WHIGHI (1 << 3)
22#define MC13783_IRQSTAT0_WLOWI (1 << 4)
23#define MC13783_IRQSTAT0_CHGDETI (1 << 6)
24#define MC13783_IRQSTAT0_CHGOVI (1 << 7)
25#define MC13783_IRQSTAT0_CHGREVI (1 << 8)
26#define MC13783_IRQSTAT0_CHGSHORTI (1 << 9)
27#define MC13783_IRQSTAT0_CCCVI (1 << 10)
28#define MC13783_IRQSTAT0_CHGCURRI (1 << 11)
29#define MC13783_IRQSTAT0_BPONI (1 << 12)
30#define MC13783_IRQSTAT0_LOBATLI (1 << 13)
31#define MC13783_IRQSTAT0_LOBATHI (1 << 14)
32#define MC13783_IRQSTAT0_UDPI (1 << 15)
33#define MC13783_IRQSTAT0_USBI (1 << 16)
34#define MC13783_IRQSTAT0_IDI (1 << 19)
35#define MC13783_IRQSTAT0_SE1I (1 << 21)
36#define MC13783_IRQSTAT0_CKDETI (1 << 22)
37#define MC13783_IRQSTAT0_UDMI (1 << 23)
38
39#define MC13783_IRQMASK0 1
40#define MC13783_IRQMASK0_ADCDONEM MC13783_IRQSTAT0_ADCDONEI
41#define MC13783_IRQMASK0_ADCBISDONEM MC13783_IRQSTAT0_ADCBISDONEI
42#define MC13783_IRQMASK0_TSM MC13783_IRQSTAT0_TSI
43#define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI
44#define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI
45#define MC13783_IRQMASK0_CHGDETM MC13783_IRQSTAT0_CHGDETI
46#define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI
47#define MC13783_IRQMASK0_CHGREVM MC13783_IRQSTAT0_CHGREVI
48#define MC13783_IRQMASK0_CHGSHORTM MC13783_IRQSTAT0_CHGSHORTI
49#define MC13783_IRQMASK0_CCCVM MC13783_IRQSTAT0_CCCVI
50#define MC13783_IRQMASK0_CHGCURRM MC13783_IRQSTAT0_CHGCURRI
51#define MC13783_IRQMASK0_BPONM MC13783_IRQSTAT0_BPONI
52#define MC13783_IRQMASK0_LOBATLM MC13783_IRQSTAT0_LOBATLI
53#define MC13783_IRQMASK0_LOBATHM MC13783_IRQSTAT0_LOBATHI
54#define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI
55#define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI
56#define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI
57#define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I
58#define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI
59#define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI
60
61#define MC13783_IRQSTAT1 3
62#define MC13783_IRQSTAT1_1HZI (1 << 0)
63#define MC13783_IRQSTAT1_TODAI (1 << 1)
64#define MC13783_IRQSTAT1_ONOFD1I (1 << 3)
65#define MC13783_IRQSTAT1_ONOFD2I (1 << 4)
66#define MC13783_IRQSTAT1_ONOFD3I (1 << 5)
67#define MC13783_IRQSTAT1_SYSRSTI (1 << 6)
68#define MC13783_IRQSTAT1_RTCRSTI (1 << 7)
69#define MC13783_IRQSTAT1_PCI (1 << 8)
70#define MC13783_IRQSTAT1_WARMI (1 << 9)
71#define MC13783_IRQSTAT1_MEMHLDI (1 << 10)
72#define MC13783_IRQSTAT1_PWRRDYI (1 << 11)
73#define MC13783_IRQSTAT1_THWARNLI (1 << 12)
74#define MC13783_IRQSTAT1_THWARNHI (1 << 13)
75#define MC13783_IRQSTAT1_CLKI (1 << 14)
76#define MC13783_IRQSTAT1_SEMAFI (1 << 15)
77#define MC13783_IRQSTAT1_MC2BI (1 << 17)
78#define MC13783_IRQSTAT1_HSDETI (1 << 18)
79#define MC13783_IRQSTAT1_HSLI (1 << 19)
80#define MC13783_IRQSTAT1_ALSPTHI (1 << 20)
81#define MC13783_IRQSTAT1_AHSSHORTI (1 << 21)
82
83#define MC13783_IRQMASK1 4
84#define MC13783_IRQMASK1_1HZM MC13783_IRQSTAT1_1HZI
85#define MC13783_IRQMASK1_TODAM MC13783_IRQSTAT1_TODAI
86#define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I
87#define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I
88#define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I
89#define MC13783_IRQMASK1_SYSRSTM MC13783_IRQSTAT1_SYSRSTI
90#define MC13783_IRQMASK1_RTCRSTM MC13783_IRQSTAT1_RTCRSTI
91#define MC13783_IRQMASK1_PCM MC13783_IRQSTAT1_PCI
92#define MC13783_IRQMASK1_WARMM MC13783_IRQSTAT1_WARMI
93#define MC13783_IRQMASK1_MEMHLDM MC13783_IRQSTAT1_MEMHLDI
94#define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI
95#define MC13783_IRQMASK1_THWARNLM MC13783_IRQSTAT1_THWARNLI
96#define MC13783_IRQMASK1_THWARNHM MC13783_IRQSTAT1_THWARNHI
97#define MC13783_IRQMASK1_CLKM MC13783_IRQSTAT1_CLKI
98#define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI
99#define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI
100#define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI
101#define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI
102#define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI
103#define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI
104
105#define MC13783_ADC1 44
106#define MC13783_ADC1_ADEN (1 << 0)
107#define MC13783_ADC1_RAND (1 << 1)
108#define MC13783_ADC1_ADSEL (1 << 3)
109#define MC13783_ADC1_ASC (1 << 20)
110#define MC13783_ADC1_ADTRIGIGN (1 << 21)
111
112#define MC13783_NUMREGS 0x3f
113
114void mc13783_lock(struct mc13783 *mc13783)
115{
116 if (!mutex_trylock(&mc13783->lock)) {
117 dev_dbg(&mc13783->spidev->dev, "wait for %s from %pf\n",
118 __func__, __builtin_return_address(0));
119
120 mutex_lock(&mc13783->lock);
121 }
122 dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
123 __func__, __builtin_return_address(0));
124}
125EXPORT_SYMBOL(mc13783_lock);
37 126
38#define MC13783_MAX_REG_NUM 0x3f 127void mc13783_unlock(struct mc13783 *mc13783)
39#define MC13783_FRAME_MASK 0x00ffffff 128{
40#define MC13783_MAX_REG_NUM 0x3f 129 dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
41#define MC13783_REG_NUM_SHIFT 0x19 130 __func__, __builtin_return_address(0));
42#define MC13783_WRITE_BIT_SHIFT 31 131 mutex_unlock(&mc13783->lock);
132}
133EXPORT_SYMBOL(mc13783_unlock);
43 134
44static inline int spi_rw(struct spi_device *spi, u8 * buf, size_t len) 135#define MC13783_REGOFFSET_SHIFT 25
136int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val)
45{ 137{
46 struct spi_transfer t = { 138 struct spi_transfer t;
47 .tx_buf = (const void *)buf,
48 .rx_buf = buf,
49 .len = len,
50 .cs_change = 0,
51 .delay_usecs = 0,
52 };
53 struct spi_message m; 139 struct spi_message m;
140 int ret;
141
142 BUG_ON(!mutex_is_locked(&mc13783->lock));
143
144 if (offset > MC13783_NUMREGS)
145 return -EINVAL;
146
147 *val = offset << MC13783_REGOFFSET_SHIFT;
148
149 memset(&t, 0, sizeof(t));
150
151 t.tx_buf = val;
152 t.rx_buf = val;
153 t.len = sizeof(u32);
54 154
55 spi_message_init(&m); 155 spi_message_init(&m);
56 spi_message_add_tail(&t, &m); 156 spi_message_add_tail(&t, &m);
57 if (spi_sync(spi, &m) != 0 || m.status != 0)
58 return -EINVAL;
59 return len - m.actual_length;
60}
61 157
62static int mc13783_read(struct mc13783 *mc13783, int reg_num, u32 *reg_val) 158 ret = spi_sync(mc13783->spidev, &m);
63{
64 unsigned int frame = 0;
65 int ret = 0;
66 159
67 if (reg_num > MC13783_MAX_REG_NUM) 160 /* error in message.status implies error return from spi_sync */
68 return -EINVAL; 161 BUG_ON(!ret && m.status);
69 162
70 frame |= reg_num << MC13783_REG_NUM_SHIFT; 163 if (ret)
164 return ret;
71 165
72 ret = spi_rw(mc13783->spi_device, (u8 *)&frame, 4); 166 *val &= 0xffffff;
73 167
74 *reg_val = frame & MC13783_FRAME_MASK; 168 dev_vdbg(&mc13783->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val);
75 169
76 return ret; 170 return 0;
77} 171}
172EXPORT_SYMBOL(mc13783_reg_read);
78 173
79static int mc13783_write(struct mc13783 *mc13783, int reg_num, u32 reg_val) 174int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val)
80{ 175{
81 unsigned int frame = 0; 176 u32 buf;
177 struct spi_transfer t;
178 struct spi_message m;
179 int ret;
180
181 BUG_ON(!mutex_is_locked(&mc13783->lock));
82 182
83 if (reg_num > MC13783_MAX_REG_NUM) 183 dev_vdbg(&mc13783->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val);
184
185 if (offset > MC13783_NUMREGS || val > 0xffffff)
84 return -EINVAL; 186 return -EINVAL;
85 187
86 frame |= (1 << MC13783_WRITE_BIT_SHIFT); 188 buf = 1 << 31 | offset << MC13783_REGOFFSET_SHIFT | val;
87 frame |= reg_num << MC13783_REG_NUM_SHIFT; 189
88 frame |= reg_val & MC13783_FRAME_MASK; 190 memset(&t, 0, sizeof(t));
89 191
90 return spi_rw(mc13783->spi_device, (u8 *)&frame, 4); 192 t.tx_buf = &buf;
193 t.rx_buf = &buf;
194 t.len = sizeof(u32);
195
196 spi_message_init(&m);
197 spi_message_add_tail(&t, &m);
198
199 ret = spi_sync(mc13783->spidev, &m);
200
201 BUG_ON(!ret && m.status);
202
203 if (ret)
204 return ret;
205
206 return 0;
91} 207}
208EXPORT_SYMBOL(mc13783_reg_write);
92 209
93int mc13783_reg_read(struct mc13783 *mc13783, int reg_num, u32 *reg_val) 210int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
211 u32 mask, u32 val)
94{ 212{
95 int ret; 213 int ret;
214 u32 valread;
96 215
97 mutex_lock(&mc13783->io_lock); 216 BUG_ON(val & ~mask);
98 ret = mc13783_read(mc13783, reg_num, reg_val);
99 mutex_unlock(&mc13783->io_lock);
100 217
101 return ret; 218 ret = mc13783_reg_read(mc13783, offset, &valread);
219 if (ret)
220 return ret;
221
222 valread = (valread & ~mask) | val;
223
224 return mc13783_reg_write(mc13783, offset, valread);
102} 225}
103EXPORT_SYMBOL_GPL(mc13783_reg_read); 226EXPORT_SYMBOL(mc13783_reg_rmw);
104 227
105int mc13783_reg_write(struct mc13783 *mc13783, int reg_num, u32 reg_val) 228int mc13783_mask(struct mc13783 *mc13783, int irq)
106{ 229{
107 int ret; 230 int ret;
231 unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
232 u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
233 u32 mask;
108 234
109 mutex_lock(&mc13783->io_lock); 235 if (irq < 0 || irq >= MC13783_NUM_IRQ)
110 ret = mc13783_write(mc13783, reg_num, reg_val); 236 return -EINVAL;
111 mutex_unlock(&mc13783->io_lock);
112 237
113 return ret; 238 ret = mc13783_reg_read(mc13783, offmask, &mask);
239 if (ret)
240 return ret;
241
242 if (mask & irqbit)
243 /* already masked */
244 return 0;
245
246 return mc13783_reg_write(mc13783, offmask, mask | irqbit);
114} 247}
115EXPORT_SYMBOL_GPL(mc13783_reg_write); 248EXPORT_SYMBOL(mc13783_mask);
116 249
117/** 250int mc13783_unmask(struct mc13783 *mc13783, int irq)
118 * mc13783_set_bits - Bitmask write
119 *
120 * @mc13783: Pointer to mc13783 control structure
121 * @reg: Register to access
122 * @mask: Mask of bits to change
123 * @val: Value to set for masked bits
124 */
125int mc13783_set_bits(struct mc13783 *mc13783, int reg, u32 mask, u32 val)
126{ 251{
127 u32 tmp;
128 int ret; 252 int ret;
253 unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
254 u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
255 u32 mask;
129 256
130 mutex_lock(&mc13783->io_lock); 257 if (irq < 0 || irq >= MC13783_NUM_IRQ)
258 return -EINVAL;
131 259
132 ret = mc13783_read(mc13783, reg, &tmp); 260 ret = mc13783_reg_read(mc13783, offmask, &mask);
133 tmp = (tmp & ~mask) | val; 261 if (ret)
134 if (ret == 0) 262 return ret;
135 ret = mc13783_write(mc13783, reg, tmp);
136 263
137 mutex_unlock(&mc13783->io_lock); 264 if (!(mask & irqbit))
265 /* already unmasked */
266 return 0;
138 267
139 return ret; 268 return mc13783_reg_write(mc13783, offmask, mask & ~irqbit);
140} 269}
141EXPORT_SYMBOL_GPL(mc13783_set_bits); 270EXPORT_SYMBOL(mc13783_unmask);
142 271
143int mc13783_register_irq(struct mc13783 *mc13783, int irq, 272int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
144 void (*handler) (int, void *), void *data) 273 irq_handler_t handler, const char *name, void *dev)
145{ 274{
146 if (irq < 0 || irq > MC13783_NUM_IRQ || !handler) 275 BUG_ON(!mutex_is_locked(&mc13783->lock));
276 BUG_ON(!handler);
277
278 if (irq < 0 || irq >= MC13783_NUM_IRQ)
147 return -EINVAL; 279 return -EINVAL;
148 280
149 if (WARN_ON(mc13783->irq_handler[irq].handler)) 281 if (mc13783->irqhandler[irq])
150 return -EBUSY; 282 return -EBUSY;
151 283
152 mutex_lock(&mc13783->io_lock); 284 mc13783->irqhandler[irq] = handler;
153 mc13783->irq_handler[irq].handler = handler; 285 mc13783->irqdata[irq] = dev;
154 mc13783->irq_handler[irq].data = data;
155 mutex_unlock(&mc13783->io_lock);
156 286
157 return 0; 287 return 0;
158} 288}
159EXPORT_SYMBOL_GPL(mc13783_register_irq); 289EXPORT_SYMBOL(mc13783_irq_request_nounmask);
160 290
161int mc13783_free_irq(struct mc13783 *mc13783, int irq) 291int mc13783_irq_request(struct mc13783 *mc13783, int irq,
292 irq_handler_t handler, const char *name, void *dev)
162{ 293{
163 if (irq < 0 || irq > MC13783_NUM_IRQ) 294 int ret;
295
296 ret = mc13783_irq_request_nounmask(mc13783, irq, handler, name, dev);
297 if (ret)
298 return ret;
299
300 ret = mc13783_unmask(mc13783, irq);
301 if (ret) {
302 mc13783->irqhandler[irq] = NULL;
303 mc13783->irqdata[irq] = NULL;
304 return ret;
305 }
306
307 return 0;
308}
309EXPORT_SYMBOL(mc13783_irq_request);
310
311int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
312{
313 int ret;
314 BUG_ON(!mutex_is_locked(&mc13783->lock));
315
316 if (irq < 0 || irq >= MC13783_NUM_IRQ || !mc13783->irqhandler[irq] ||
317 mc13783->irqdata[irq] != dev)
164 return -EINVAL; 318 return -EINVAL;
165 319
166 mutex_lock(&mc13783->io_lock); 320 ret = mc13783_mask(mc13783, irq);
167 mc13783->irq_handler[irq].handler = NULL; 321 if (ret)
168 mutex_unlock(&mc13783->io_lock); 322 return ret;
323
324 mc13783->irqhandler[irq] = NULL;
325 mc13783->irqdata[irq] = NULL;
169 326
170 return 0; 327 return 0;
171} 328}
172EXPORT_SYMBOL_GPL(mc13783_free_irq); 329EXPORT_SYMBOL(mc13783_irq_free);
173 330
174static void mc13783_irq_work(struct work_struct *work) 331static inline irqreturn_t mc13783_irqhandler(struct mc13783 *mc13783, int irq)
175{ 332{
176 struct mc13783 *mc13783 = container_of(work, struct mc13783, work); 333 return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]);
177 int i;
178 unsigned int adc_sts;
179
180 /* check if the adc has finished any completion */
181 mc13783_reg_read(mc13783, MC13783_REG_INTERRUPT_STATUS_0, &adc_sts);
182 mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_0,
183 adc_sts & MC13783_INT_STAT_ADCDONEI);
184
185 if (adc_sts & MC13783_INT_STAT_ADCDONEI)
186 complete_all(&mc13783->adc_done);
187
188 for (i = 0; i < MC13783_NUM_IRQ; i++)
189 if (mc13783->irq_handler[i].handler)
190 mc13783->irq_handler[i].handler(i,
191 mc13783->irq_handler[i].data);
192 enable_irq(mc13783->irq);
193} 334}
194 335
195static irqreturn_t mc13783_interrupt(int irq, void *dev_id) 336int mc13783_ackirq(struct mc13783 *mc13783, int irq)
196{ 337{
197 struct mc13783 *mc13783 = dev_id; 338 unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
339 unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
198 340
199 disable_irq_nosync(irq); 341 BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
200 342
201 schedule_work(&mc13783->work); 343 return mc13783_reg_write(mc13783, offstat, val);
202 return IRQ_HANDLED;
203} 344}
345EXPORT_SYMBOL(mc13783_ackirq);
204 346
205/* set adc to ts interrupt mode, which generates touchscreen wakeup interrupt */ 347/*
206static inline void mc13783_adc_set_ts_irq_mode(struct mc13783 *mc13783) 348 * returns: number of handled irqs or negative error
349 * locking: holds mc13783->lock
350 */
351static int mc13783_irq_handle(struct mc13783 *mc13783,
352 unsigned int offstat, unsigned int offmask, int baseirq)
207{ 353{
208 unsigned int reg_adc0, reg_adc1; 354 u32 stat, mask;
355 int ret = mc13783_reg_read(mc13783, offstat, &stat);
356 int num_handled = 0;
357
358 if (ret)
359 return ret;
360
361 ret = mc13783_reg_read(mc13783, offmask, &mask);
362 if (ret)
363 return ret;
364
365 while (stat & ~mask) {
366 int irq = __ffs(stat & ~mask);
367
368 stat &= ~(1 << irq);
369
370 if (likely(mc13783->irqhandler[baseirq + irq])) {
371 irqreturn_t handled;
209 372
210 reg_adc0 = MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE 373 handled = mc13783_irqhandler(mc13783, baseirq + irq);
211 | MC13783_ADC0_TSMOD0; 374 if (handled == IRQ_HANDLED)
212 reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN; 375 num_handled++;
376 } else {
377 dev_err(&mc13783->spidev->dev,
378 "BUG: irq %u but no handler\n",
379 baseirq + irq);
213 380
214 mc13783_reg_write(mc13783, MC13783_REG_ADC_0, reg_adc0); 381 mask |= 1 << irq;
215 mc13783_reg_write(mc13783, MC13783_REG_ADC_1, reg_adc1); 382
383 ret = mc13783_reg_write(mc13783, offmask, mask);
384 }
385 }
386
387 return num_handled;
216} 388}
217 389
390static irqreturn_t mc13783_irq_thread(int irq, void *data)
391{
392 struct mc13783 *mc13783 = data;
393 irqreturn_t ret;
394 int handled = 0;
395
396 mc13783_lock(mc13783);
397
398 ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT0,
399 MC13783_IRQMASK0, MC13783_IRQ_ADCDONE);
400 if (ret > 0)
401 handled = 1;
402
403 ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT1,
404 MC13783_IRQMASK1, MC13783_IRQ_1HZ);
405 if (ret > 0)
406 handled = 1;
407
408 mc13783_unlock(mc13783);
409
410 return IRQ_RETVAL(handled);
411}
412
413#define MC13783_ADC1_CHAN0_SHIFT 5
414#define MC13783_ADC1_CHAN1_SHIFT 8
415
416struct mc13783_adcdone_data {
417 struct mc13783 *mc13783;
418 struct completion done;
419};
420
421static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
422{
423 struct mc13783_adcdone_data *adcdone_data = data;
424
425 mc13783_ackirq(adcdone_data->mc13783, irq);
426
427 complete_all(&adcdone_data->done);
428
429 return IRQ_HANDLED;
430}
431
432#define MC13783_ADC_WORKING (1 << 16)
433
218int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, 434int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
219 unsigned int channel, unsigned int *sample) 435 unsigned int channel, unsigned int *sample)
220{ 436{
221 unsigned int reg_adc0, reg_adc1; 437 u32 adc0, adc1, old_adc0;
222 int i; 438 int i, ret;
439 struct mc13783_adcdone_data adcdone_data = {
440 .mc13783 = mc13783,
441 };
442 init_completion(&adcdone_data.done);
443
444 dev_dbg(&mc13783->spidev->dev, "%s\n", __func__);
445
446 mc13783_lock(mc13783);
447
448 if (mc13783->flags & MC13783_ADC_WORKING) {
449 ret = -EBUSY;
450 goto out;
451 }
452
453 mc13783->flags |= MC13783_ADC_WORKING;
223 454
224 mutex_lock(&mc13783->adc_conv_lock); 455 mc13783_reg_read(mc13783, MC13783_ADC0, &old_adc0);
225 456
226 /* set up auto incrementing anyway to make quick read */ 457 adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
227 reg_adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2; 458 adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC;
228 /* enable the adc, ignore external triggering and set ASC to trigger
229 * conversion */
230 reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN
231 | MC13783_ADC1_ASC;
232 459
233 /* setup channel number */
234 if (channel > 7) 460 if (channel > 7)
235 reg_adc1 |= MC13783_ADC1_ADSEL; 461 adc1 |= MC13783_ADC1_ADSEL;
236 462
237 switch (mode) { 463 switch (mode) {
238 case MC13783_ADC_MODE_TS: 464 case MC13783_ADC_MODE_TS:
239 /* enables touch screen reference mode and set touchscreen mode 465 adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
240 * to position mode */
241 reg_adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
242 | MC13783_ADC0_TSMOD0 | MC13783_ADC0_TSMOD1; 466 | MC13783_ADC0_TSMOD0 | MC13783_ADC0_TSMOD1;
243 reg_adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT; 467 adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
244 break; 468 break;
469
245 case MC13783_ADC_MODE_SINGLE_CHAN: 470 case MC13783_ADC_MODE_SINGLE_CHAN:
246 reg_adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT; 471 adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
247 reg_adc1 |= MC13783_ADC1_RAND; 472 adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
473 adc1 |= MC13783_ADC1_RAND;
248 break; 474 break;
475
249 case MC13783_ADC_MODE_MULT_CHAN: 476 case MC13783_ADC_MODE_MULT_CHAN:
250 reg_adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT; 477 adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
478 adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
251 break; 479 break;
480
252 default: 481 default:
482 mc13783_unlock(mc13783);
253 return -EINVAL; 483 return -EINVAL;
254 } 484 }
255 485
256 mc13783_reg_write(mc13783, MC13783_REG_ADC_0, reg_adc0); 486 dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__);
257 mc13783_reg_write(mc13783, MC13783_REG_ADC_1, reg_adc1); 487 mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE,
488 mc13783_handler_adcdone, __func__, &adcdone_data);
489 mc13783_ackirq(mc13783, MC13783_IRQ_ADCDONE);
258 490
259 wait_for_completion_interruptible(&mc13783->adc_done); 491 mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0);
492 mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1);
260 493
261 for (i = 0; i < 4; i++) 494 mc13783_unlock(mc13783);
262 mc13783_reg_read(mc13783, MC13783_REG_ADC_2, &sample[i]);
263 495
264 if (mc13783->ts_active) 496 ret = wait_for_completion_interruptible_timeout(&adcdone_data.done, HZ);
265 mc13783_adc_set_ts_irq_mode(mc13783);
266 497
267 mutex_unlock(&mc13783->adc_conv_lock); 498 if (!ret)
499 ret = -ETIMEDOUT;
268 500
269 return 0; 501 mc13783_lock(mc13783);
502
503 mc13783_irq_free(mc13783, MC13783_IRQ_ADCDONE, &adcdone_data);
504
505 if (ret > 0)
506 for (i = 0; i < 4; ++i) {
507 ret = mc13783_reg_read(mc13783,
508 MC13783_REG_ADC_2, &sample[i]);
509 if (ret)
510 break;
511 }
512
513 if (mode == MC13783_ADC_MODE_TS)
514 /* restore TSMOD */
515 mc13783_reg_write(mc13783, MC13783_REG_ADC_0, old_adc0);
516
517 mc13783->flags &= ~MC13783_ADC_WORKING;
518out:
519 mc13783_unlock(mc13783);
520
521 return ret;
270} 522}
271EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion); 523EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
272 524
273void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status) 525static int mc13783_add_subdevice_pdata(struct mc13783 *mc13783,
526 const char *name, void *pdata, size_t pdata_size)
274{ 527{
275 mc13783->ts_active = status; 528 struct mfd_cell cell = {
529 .name = name,
530 .platform_data = pdata,
531 .data_size = pdata_size,
532 };
533
534 return mfd_add_devices(&mc13783->spidev->dev, -1, &cell, 1, NULL, 0);
535}
536
537static int mc13783_add_subdevice(struct mc13783 *mc13783, const char *name)
538{
539 return mc13783_add_subdevice_pdata(mc13783, name, NULL, 0);
276} 540}
277EXPORT_SYMBOL_GPL(mc13783_adc_set_ts_status);
278 541
279static int mc13783_check_revision(struct mc13783 *mc13783) 542static int mc13783_check_revision(struct mc13783 *mc13783)
280{ 543{
281 u32 rev_id, rev1, rev2, finid, icid; 544 u32 rev_id, rev1, rev2, finid, icid;
282 545
283 mc13783_read(mc13783, MC13783_REG_REVISION, &rev_id); 546 mc13783_reg_read(mc13783, MC13783_REG_REVISION, &rev_id);
284 547
285 rev1 = (rev_id & 0x018) >> 3; 548 rev1 = (rev_id & 0x018) >> 3;
286 rev2 = (rev_id & 0x007); 549 rev2 = (rev_id & 0x007);
@@ -292,38 +555,24 @@ static int mc13783_check_revision(struct mc13783 *mc13783)
292 rev1 = 3; 555 rev1 = 3;
293 556
294 if (rev1 == 0 || icid != 2) { 557 if (rev1 == 0 || icid != 2) {
295 dev_err(mc13783->dev, "No MC13783 detected.\n"); 558 dev_err(&mc13783->spidev->dev, "No MC13783 detected.\n");
296 return -ENODEV; 559 return -ENODEV;
297 } 560 }
298 561
299 mc13783->revision = ((rev1 * 10) + rev2); 562 dev_info(&mc13783->spidev->dev,
300 dev_info(mc13783->dev, "MC13783 Rev %d.%d FinVer %x detected\n", rev1, 563 "MC13783 Rev %d.%d FinVer %x detected\n",
301 rev2, finid); 564 rev1, rev2, finid);
302 565
303 return 0; 566 return 0;
304} 567}
305 568
306/* 569static int mc13783_probe(struct spi_device *spi)
307 * Register a client device. This is non-fatal since there is no need to
308 * fail the entire device init due to a single platform device failing.
309 */
310static void mc13783_client_dev_register(struct mc13783 *mc13783,
311 const char *name)
312{
313 struct mfd_cell cell = {};
314
315 cell.name = name;
316
317 mfd_add_devices(mc13783->dev, -1, &cell, 1, NULL, 0);
318}
319
320static int __devinit mc13783_probe(struct spi_device *spi)
321{ 570{
322 struct mc13783 *mc13783; 571 struct mc13783 *mc13783;
323 struct mc13783_platform_data *pdata = spi->dev.platform_data; 572 struct mc13783_platform_data *pdata = dev_get_platdata(&spi->dev);
324 int ret; 573 int ret;
325 574
326 mc13783 = kzalloc(sizeof(struct mc13783), GFP_KERNEL); 575 mc13783 = kzalloc(sizeof(*mc13783), GFP_KERNEL);
327 if (!mc13783) 576 if (!mc13783)
328 return -ENOMEM; 577 return -ENOMEM;
329 578
@@ -332,96 +581,104 @@ static int __devinit mc13783_probe(struct spi_device *spi)
332 spi->bits_per_word = 32; 581 spi->bits_per_word = 32;
333 spi_setup(spi); 582 spi_setup(spi);
334 583
335 mc13783->spi_device = spi; 584 mc13783->spidev = spi;
336 mc13783->dev = &spi->dev; 585
337 mc13783->irq = spi->irq; 586 mutex_init(&mc13783->lock);
587 mc13783_lock(mc13783);
588
589 ret = mc13783_check_revision(mc13783);
590 if (ret)
591 goto err_revision;
592
593 /* mask all irqs */
594 ret = mc13783_reg_write(mc13783, MC13783_IRQMASK0, 0x00ffffff);
595 if (ret)
596 goto err_mask;
338 597
339 INIT_WORK(&mc13783->work, mc13783_irq_work); 598 ret = mc13783_reg_write(mc13783, MC13783_IRQMASK1, 0x00ffffff);
340 mutex_init(&mc13783->io_lock); 599 if (ret)
341 mutex_init(&mc13783->adc_conv_lock); 600 goto err_mask;
342 init_completion(&mc13783->adc_done); 601
602 ret = request_threaded_irq(spi->irq, NULL, mc13783_irq_thread,
603 IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13783", mc13783);
604
605 if (ret) {
606err_mask:
607err_revision:
608 mutex_unlock(&mc13783->lock);
609 dev_set_drvdata(&spi->dev, NULL);
610 kfree(mc13783);
611 return ret;
612 }
343 613
614 /* This should go away (BEGIN) */
344 if (pdata) { 615 if (pdata) {
345 mc13783->flags = pdata->flags; 616 mc13783->flags = pdata->flags;
346 mc13783->regulators = pdata->regulators; 617 mc13783->regulators = pdata->regulators;
347 mc13783->num_regulators = pdata->num_regulators; 618 mc13783->num_regulators = pdata->num_regulators;
348 } 619 }
620 /* This should go away (END) */
349 621
350 if (mc13783_check_revision(mc13783)) { 622 if (pdata->flags & MC13783_USE_ADC)
351 ret = -ENODEV; 623 mc13783_add_subdevice(mc13783, "mc13783-adc");
352 goto err_out; 624
625 if (pdata->flags & MC13783_USE_CODEC)
626 mc13783_add_subdevice(mc13783, "mc13783-codec");
627
628 if (pdata->flags & MC13783_USE_REGULATOR) {
629 struct mc13783_regulator_platform_data regulator_pdata = {
630 .num_regulators = pdata->num_regulators,
631 .regulators = pdata->regulators,
632 };
633
634 mc13783_add_subdevice_pdata(mc13783, "mc13783-regulator",
635 &regulator_pdata, sizeof(regulator_pdata));
353 } 636 }
354 637
355 /* clear and mask all interrupts */ 638 if (pdata->flags & MC13783_USE_RTC)
356 mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_0, 0x00ffffff); 639 mc13783_add_subdevice(mc13783, "mc13783-rtc");
357 mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_MASK_0, 0x00ffffff);
358 mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_1, 0x00ffffff);
359 mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_MASK_1, 0x00ffffff);
360 640
361 /* unmask adcdone interrupts */ 641 if (pdata->flags & MC13783_USE_TOUCHSCREEN)
362 mc13783_set_bits(mc13783, MC13783_REG_INTERRUPT_MASK_0, 642 mc13783_add_subdevice(mc13783, "mc13783-ts");
363 MC13783_INT_MASK_ADCDONEM, 0);
364 643
365 ret = request_irq(mc13783->irq, mc13783_interrupt, 644 mc13783_unlock(mc13783);
366 IRQF_DISABLED | IRQF_TRIGGER_HIGH, "mc13783",
367 mc13783);
368 if (ret)
369 goto err_out;
370
371 if (mc13783->flags & MC13783_USE_CODEC)
372 mc13783_client_dev_register(mc13783, "mc13783-codec");
373 if (mc13783->flags & MC13783_USE_ADC)
374 mc13783_client_dev_register(mc13783, "mc13783-adc");
375 if (mc13783->flags & MC13783_USE_RTC)
376 mc13783_client_dev_register(mc13783, "mc13783-rtc");
377 if (mc13783->flags & MC13783_USE_REGULATOR)
378 mc13783_client_dev_register(mc13783, "mc13783-regulator");
379 if (mc13783->flags & MC13783_USE_TOUCHSCREEN)
380 mc13783_client_dev_register(mc13783, "mc13783-ts");
381 645
382 return 0; 646 return 0;
383
384err_out:
385 kfree(mc13783);
386 return ret;
387} 647}
388 648
389static int __devexit mc13783_remove(struct spi_device *spi) 649static int __devexit mc13783_remove(struct spi_device *spi)
390{ 650{
391 struct mc13783 *mc13783; 651 struct mc13783 *mc13783 = dev_get_drvdata(&spi->dev);
392 652
393 mc13783 = dev_get_drvdata(&spi->dev); 653 free_irq(mc13783->spidev->irq, mc13783);
394
395 free_irq(mc13783->irq, mc13783);
396 654
397 mfd_remove_devices(&spi->dev); 655 mfd_remove_devices(&spi->dev);
398 656
399 return 0; 657 return 0;
400} 658}
401 659
402static struct spi_driver pmic_driver = { 660static struct spi_driver mc13783_driver = {
403 .driver = { 661 .driver = {
404 .name = "mc13783", 662 .name = "mc13783",
405 .bus = &spi_bus_type, 663 .bus = &spi_bus_type,
406 .owner = THIS_MODULE, 664 .owner = THIS_MODULE,
407 }, 665 },
408 .probe = mc13783_probe, 666 .probe = mc13783_probe,
409 .remove = __devexit_p(mc13783_remove), 667 .remove = __devexit_p(mc13783_remove),
410}; 668};
411 669
412static int __init pmic_init(void) 670static int __init mc13783_init(void)
413{ 671{
414 return spi_register_driver(&pmic_driver); 672 return spi_register_driver(&mc13783_driver);
415} 673}
416subsys_initcall(pmic_init); 674subsys_initcall(mc13783_init);
417 675
418static void __exit pmic_exit(void) 676static void __exit mc13783_exit(void)
419{ 677{
420 spi_unregister_driver(&pmic_driver); 678 spi_unregister_driver(&mc13783_driver);
421} 679}
422module_exit(pmic_exit); 680module_exit(mc13783_exit);
423
424MODULE_DESCRIPTION("Core/Protocol driver for Freescale MC13783 PMIC");
425MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
426MODULE_LICENSE("GPL");
427 681
682MODULE_DESCRIPTION("Core driver for Freescale MC13783 PMIC");
683MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
684MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/mc13783-private.h b/include/linux/mfd/mc13783-private.h
index 47e698cb0f16..95cf9360553f 100644
--- a/include/linux/mfd/mc13783-private.h
+++ b/include/linux/mfd/mc13783-private.h
@@ -24,52 +24,23 @@
24 24
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/mfd/mc13783.h> 26#include <linux/mfd/mc13783.h>
27#include <linux/workqueue.h>
28#include <linux/mutex.h> 27#include <linux/mutex.h>
29 28#include <linux/interrupt.h>
30struct mc13783_irq {
31 void (*handler)(int, void *);
32 void *data;
33};
34
35#define MC13783_NUM_IRQ 2
36#define MC13783_IRQ_TS 0
37#define MC13783_IRQ_REGULATOR 1
38
39#define MC13783_ADC_MODE_TS 1
40#define MC13783_ADC_MODE_SINGLE_CHAN 2
41#define MC13783_ADC_MODE_MULT_CHAN 3
42 29
43struct mc13783 { 30struct mc13783 {
44 int revision; 31 struct spi_device *spidev;
45 struct device *dev; 32 struct mutex lock;
46 struct spi_device *spi_device;
47
48 int (*read_dev)(void *data, char reg, int count, u32 *dst);
49 int (*write_dev)(void *data, char reg, int count, const u32 *src);
50
51 struct mutex io_lock;
52 void *io_data;
53 int irq; 33 int irq;
54 unsigned int flags; 34 int flags;
55 35
56 struct mc13783_irq irq_handler[MC13783_NUM_IRQ]; 36 irq_handler_t irqhandler[MC13783_NUM_IRQ];
57 struct work_struct work; 37 void *irqdata[MC13783_NUM_IRQ];
58 struct completion adc_done;
59 unsigned int ts_active;
60 struct mutex adc_conv_lock;
61 38
39 /* XXX these should go as platformdata to the regulator subdevice */
62 struct mc13783_regulator_init_data *regulators; 40 struct mc13783_regulator_init_data *regulators;
63 int num_regulators; 41 int num_regulators;
64}; 42};
65 43
66int mc13783_reg_read(struct mc13783 *, int reg_num, u32 *);
67int mc13783_reg_write(struct mc13783 *, int, u32);
68int mc13783_set_bits(struct mc13783 *, int, u32, u32);
69int mc13783_free_irq(struct mc13783 *mc13783, int irq);
70int mc13783_register_irq(struct mc13783 *mc13783, int irq,
71 void (*handler) (int, void *), void *data);
72
73#define MC13783_REG_INTERRUPT_STATUS_0 0 44#define MC13783_REG_INTERRUPT_STATUS_0 0
74#define MC13783_REG_INTERRUPT_MASK_0 1 45#define MC13783_REG_INTERRUPT_MASK_0 1
75#define MC13783_REG_INTERRUPT_SENSE_0 2 46#define MC13783_REG_INTERRUPT_SENSE_0 2
@@ -136,55 +107,6 @@ int mc13783_register_irq(struct mc13783 *mc13783, int irq,
136#define MC13783_REG_TEST_3 63 107#define MC13783_REG_TEST_3 63
137#define MC13783_REG_NB 64 108#define MC13783_REG_NB 64
138 109
139
140/*
141 * Interrupt Status
142 */
143#define MC13783_INT_STAT_ADCDONEI (1 << 0)
144#define MC13783_INT_STAT_ADCBISDONEI (1 << 1)
145#define MC13783_INT_STAT_TSI (1 << 2)
146#define MC13783_INT_STAT_WHIGHI (1 << 3)
147#define MC13783_INT_STAT_WLOWI (1 << 4)
148#define MC13783_INT_STAT_CHGDETI (1 << 6)
149#define MC13783_INT_STAT_CHGOVI (1 << 7)
150#define MC13783_INT_STAT_CHGREVI (1 << 8)
151#define MC13783_INT_STAT_CHGSHORTI (1 << 9)
152#define MC13783_INT_STAT_CCCVI (1 << 10)
153#define MC13783_INT_STAT_CHGCURRI (1 << 11)
154#define MC13783_INT_STAT_BPONI (1 << 12)
155#define MC13783_INT_STAT_LOBATLI (1 << 13)
156#define MC13783_INT_STAT_LOBATHI (1 << 14)
157#define MC13783_INT_STAT_UDPI (1 << 15)
158#define MC13783_INT_STAT_USBI (1 << 16)
159#define MC13783_INT_STAT_IDI (1 << 19)
160#define MC13783_INT_STAT_Unused (1 << 20)
161#define MC13783_INT_STAT_SE1I (1 << 21)
162#define MC13783_INT_STAT_CKDETI (1 << 22)
163#define MC13783_INT_STAT_UDMI (1 << 23)
164
165/*
166 * Interrupt Mask
167 */
168#define MC13783_INT_MASK_ADCDONEM (1 << 0)
169#define MC13783_INT_MASK_ADCBISDONEM (1 << 1)
170#define MC13783_INT_MASK_TSM (1 << 2)
171#define MC13783_INT_MASK_WHIGHM (1 << 3)
172#define MC13783_INT_MASK_WLOWM (1 << 4)
173#define MC13783_INT_MASK_CHGDETM (1 << 6)
174#define MC13783_INT_MASK_CHGOVM (1 << 7)
175#define MC13783_INT_MASK_CHGREVM (1 << 8)
176#define MC13783_INT_MASK_CHGSHORTM (1 << 9)
177#define MC13783_INT_MASK_CCCVM (1 << 10)
178#define MC13783_INT_MASK_CHGCURRM (1 << 11)
179#define MC13783_INT_MASK_BPONM (1 << 12)
180#define MC13783_INT_MASK_LOBATLM (1 << 13)
181#define MC13783_INT_MASK_LOBATHM (1 << 14)
182#define MC13783_INT_MASK_UDPM (1 << 15)
183#define MC13783_INT_MASK_USBM (1 << 16)
184#define MC13783_INT_MASK_IDM (1 << 19)
185#define MC13783_INT_MASK_SE1M (1 << 21)
186#define MC13783_INT_MASK_CKDETM (1 << 22)
187
188/* 110/*
189 * Reg Regulator Mode 0 111 * Reg Regulator Mode 0
190 */ 112 */
@@ -284,113 +206,15 @@ int mc13783_register_irq(struct mc13783 *mc13783, int irq,
284#define MC13783_SWCTRL_SW3_STBY (1 << 21) 206#define MC13783_SWCTRL_SW3_STBY (1 << 21)
285#define MC13783_SWCTRL_SW3_MODE (1 << 22) 207#define MC13783_SWCTRL_SW3_MODE (1 << 22)
286 208
287/* 209static inline int mc13783_set_bits(struct mc13783 *mc13783, unsigned int offset,
288 * ADC/Touch 210 u32 mask, u32 val)
289 */ 211{
290#define MC13783_ADC0_LICELLCON (1 << 0) 212 int ret;
291#define MC13783_ADC0_CHRGICON (1 << 1) 213 mc13783_lock(mc13783);
292#define MC13783_ADC0_BATICON (1 << 2) 214 ret = mc13783_reg_rmw(mc13783, offset, mask, val);
293#define MC13783_ADC0_RTHEN (1 << 3) 215 mc13783_unlock(mc13783);
294#define MC13783_ADC0_DTHEN (1 << 4)
295#define MC13783_ADC0_UIDEN (1 << 5)
296#define MC13783_ADC0_ADOUTEN (1 << 6)
297#define MC13783_ADC0_ADOUTPER (1 << 7)
298#define MC13783_ADC0_ADREFEN (1 << 10)
299#define MC13783_ADC0_ADREFMODE (1 << 11)
300#define MC13783_ADC0_TSMOD0 (1 << 12)
301#define MC13783_ADC0_TSMOD1 (1 << 13)
302#define MC13783_ADC0_TSMOD2 (1 << 14)
303#define MC13783_ADC0_CHRGRAWDIV (1 << 15)
304#define MC13783_ADC0_ADINC1 (1 << 16)
305#define MC13783_ADC0_ADINC2 (1 << 17)
306#define MC13783_ADC0_WCOMP (1 << 18)
307#define MC13783_ADC0_ADCBIS0 (1 << 23)
308
309#define MC13783_ADC1_ADEN (1 << 0)
310#define MC13783_ADC1_RAND (1 << 1)
311#define MC13783_ADC1_ADSEL (1 << 3)
312#define MC13783_ADC1_TRIGMASK (1 << 4)
313#define MC13783_ADC1_ADA10 (1 << 5)
314#define MC13783_ADC1_ADA11 (1 << 6)
315#define MC13783_ADC1_ADA12 (1 << 7)
316#define MC13783_ADC1_ADA20 (1 << 8)
317#define MC13783_ADC1_ADA21 (1 << 9)
318#define MC13783_ADC1_ADA22 (1 << 10)
319#define MC13783_ADC1_ATO0 (1 << 11)
320#define MC13783_ADC1_ATO1 (1 << 12)
321#define MC13783_ADC1_ATO2 (1 << 13)
322#define MC13783_ADC1_ATO3 (1 << 14)
323#define MC13783_ADC1_ATO4 (1 << 15)
324#define MC13783_ADC1_ATO5 (1 << 16)
325#define MC13783_ADC1_ATO6 (1 << 17)
326#define MC13783_ADC1_ATO7 (1 << 18)
327#define MC13783_ADC1_ATOX (1 << 19)
328#define MC13783_ADC1_ASC (1 << 20)
329#define MC13783_ADC1_ADTRIGIGN (1 << 21)
330#define MC13783_ADC1_ADONESHOT (1 << 22)
331#define MC13783_ADC1_ADCBIS1 (1 << 23)
332
333#define MC13783_ADC1_CHAN0_SHIFT 5
334#define MC13783_ADC1_CHAN1_SHIFT 8
335
336#define MC13783_ADC2_ADD10 (1 << 2)
337#define MC13783_ADC2_ADD11 (1 << 3)
338#define MC13783_ADC2_ADD12 (1 << 4)
339#define MC13783_ADC2_ADD13 (1 << 5)
340#define MC13783_ADC2_ADD14 (1 << 6)
341#define MC13783_ADC2_ADD15 (1 << 7)
342#define MC13783_ADC2_ADD16 (1 << 8)
343#define MC13783_ADC2_ADD17 (1 << 9)
344#define MC13783_ADC2_ADD18 (1 << 10)
345#define MC13783_ADC2_ADD19 (1 << 11)
346#define MC13783_ADC2_ADD20 (1 << 14)
347#define MC13783_ADC2_ADD21 (1 << 15)
348#define MC13783_ADC2_ADD22 (1 << 16)
349#define MC13783_ADC2_ADD23 (1 << 17)
350#define MC13783_ADC2_ADD24 (1 << 18)
351#define MC13783_ADC2_ADD25 (1 << 19)
352#define MC13783_ADC2_ADD26 (1 << 20)
353#define MC13783_ADC2_ADD27 (1 << 21)
354#define MC13783_ADC2_ADD28 (1 << 22)
355#define MC13783_ADC2_ADD29 (1 << 23)
356 216
357#define MC13783_ADC3_WHIGH0 (1 << 0) 217 return ret;
358#define MC13783_ADC3_WHIGH1 (1 << 1) 218}
359#define MC13783_ADC3_WHIGH2 (1 << 2)
360#define MC13783_ADC3_WHIGH3 (1 << 3)
361#define MC13783_ADC3_WHIGH4 (1 << 4)
362#define MC13783_ADC3_WHIGH5 (1 << 5)
363#define MC13783_ADC3_ICID0 (1 << 6)
364#define MC13783_ADC3_ICID1 (1 << 7)
365#define MC13783_ADC3_ICID2 (1 << 8)
366#define MC13783_ADC3_WLOW0 (1 << 9)
367#define MC13783_ADC3_WLOW1 (1 << 10)
368#define MC13783_ADC3_WLOW2 (1 << 11)
369#define MC13783_ADC3_WLOW3 (1 << 12)
370#define MC13783_ADC3_WLOW4 (1 << 13)
371#define MC13783_ADC3_WLOW5 (1 << 14)
372#define MC13783_ADC3_ADCBIS2 (1 << 23)
373
374#define MC13783_ADC4_ADDBIS10 (1 << 2)
375#define MC13783_ADC4_ADDBIS11 (1 << 3)
376#define MC13783_ADC4_ADDBIS12 (1 << 4)
377#define MC13783_ADC4_ADDBIS13 (1 << 5)
378#define MC13783_ADC4_ADDBIS14 (1 << 6)
379#define MC13783_ADC4_ADDBIS15 (1 << 7)
380#define MC13783_ADC4_ADDBIS16 (1 << 8)
381#define MC13783_ADC4_ADDBIS17 (1 << 9)
382#define MC13783_ADC4_ADDBIS18 (1 << 10)
383#define MC13783_ADC4_ADDBIS19 (1 << 11)
384#define MC13783_ADC4_ADDBIS20 (1 << 14)
385#define MC13783_ADC4_ADDBIS21 (1 << 15)
386#define MC13783_ADC4_ADDBIS22 (1 << 16)
387#define MC13783_ADC4_ADDBIS23 (1 << 17)
388#define MC13783_ADC4_ADDBIS24 (1 << 18)
389#define MC13783_ADC4_ADDBIS25 (1 << 19)
390#define MC13783_ADC4_ADDBIS26 (1 << 20)
391#define MC13783_ADC4_ADDBIS27 (1 << 21)
392#define MC13783_ADC4_ADDBIS28 (1 << 22)
393#define MC13783_ADC4_ADDBIS29 (1 << 23)
394 219
395#endif /* __LINUX_MFD_MC13783_PRIV_H */ 220#endif /* __LINUX_MFD_MC13783_PRIV_H */
396
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
index b3a2a7243573..35680409b8cf 100644
--- a/include/linux/mfd/mc13783.h
+++ b/include/linux/mfd/mc13783.h
@@ -1,28 +1,50 @@
1/* 1/*
2 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> 2 * Copyright 2009 Pengutronix
3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
3 * 4 *
4 * Initial development of this code was funded by 5 * This program is free software; you can redistribute it and/or modify it under
5 * Phytec Messtechnik GmbH, http://www.phytec.de 6 * the terms of the GNU General Public License version 2 as published by the
6 * 7 * Free Software Foundation.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 8 */
9#ifndef __LINUX_MFD_MC13783_H
10#define __LINUX_MFD_MC13783_H
21 11
22#ifndef __INCLUDE_LINUX_MFD_MC13783_H 12#include <linux/interrupt.h>
23#define __INCLUDE_LINUX_MFD_MC13783_H
24 13
25struct mc13783; 14struct mc13783;
15
16void mc13783_lock(struct mc13783 *mc13783);
17void mc13783_unlock(struct mc13783 *mc13783);
18
19int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val);
20int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val);
21int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
22 u32 mask, u32 val);
23
24int mc13783_irq_request(struct mc13783 *mc13783, int irq,
25 irq_handler_t handler, const char *name, void *dev);
26int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
27 irq_handler_t handler, const char *name, void *dev);
28int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev);
29int mc13783_ackirq(struct mc13783 *mc13783, int irq);
30
31int mc13783_mask(struct mc13783 *mc13783, int irq);
32int mc13783_unmask(struct mc13783 *mc13783, int irq);
33
34#define MC13783_ADC0 43
35#define MC13783_ADC0_ADREFEN (1 << 10)
36#define MC13783_ADC0_ADREFMODE (1 << 11)
37#define MC13783_ADC0_TSMOD0 (1 << 12)
38#define MC13783_ADC0_TSMOD1 (1 << 13)
39#define MC13783_ADC0_TSMOD2 (1 << 14)
40#define MC13783_ADC0_ADINC1 (1 << 16)
41#define MC13783_ADC0_ADINC2 (1 << 17)
42
43#define MC13783_ADC0_TSMOD_MASK (MC13783_ADC0_TSMOD0 | \
44 MC13783_ADC0_TSMOD1 | \
45 MC13783_ADC0_TSMOD2)
46
47/* to be cleaned up */
26struct regulator_init_data; 48struct regulator_init_data;
27 49
28struct mc13783_regulator_init_data { 50struct mc13783_regulator_init_data {
@@ -30,23 +52,30 @@ struct mc13783_regulator_init_data {
30 struct regulator_init_data *init_data; 52 struct regulator_init_data *init_data;
31}; 53};
32 54
33struct mc13783_platform_data { 55struct mc13783_regulator_platform_data {
34 struct mc13783_regulator_init_data *regulators;
35 int num_regulators; 56 int num_regulators;
36 unsigned int flags; 57 struct mc13783_regulator_init_data *regulators;
37}; 58};
38 59
39/* mc13783_platform_data flags */ 60struct mc13783_platform_data {
61 int num_regulators;
62 struct mc13783_regulator_init_data *regulators;
63
40#define MC13783_USE_TOUCHSCREEN (1 << 0) 64#define MC13783_USE_TOUCHSCREEN (1 << 0)
41#define MC13783_USE_CODEC (1 << 1) 65#define MC13783_USE_CODEC (1 << 1)
42#define MC13783_USE_ADC (1 << 2) 66#define MC13783_USE_ADC (1 << 2)
43#define MC13783_USE_RTC (1 << 3) 67#define MC13783_USE_RTC (1 << 3)
44#define MC13783_USE_REGULATOR (1 << 4) 68#define MC13783_USE_REGULATOR (1 << 4)
69 unsigned int flags;
70};
71
72#define MC13783_ADC_MODE_TS 1
73#define MC13783_ADC_MODE_SINGLE_CHAN 2
74#define MC13783_ADC_MODE_MULT_CHAN 3
45 75
46int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, 76int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
47 unsigned int channel, unsigned int *sample); 77 unsigned int channel, unsigned int *sample);
48 78
49void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status);
50 79
51#define MC13783_SW_SW1A 0 80#define MC13783_SW_SW1A 0
52#define MC13783_SW_SW1B 1 81#define MC13783_SW_SW1B 1
@@ -80,5 +109,46 @@ void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status);
80#define MC13783_REGU_V3 29 109#define MC13783_REGU_V3 29
81#define MC13783_REGU_V4 30 110#define MC13783_REGU_V4 30
82 111
83#endif /* __INCLUDE_LINUX_MFD_MC13783_H */ 112#define MC13783_IRQ_ADCDONE 0
113#define MC13783_IRQ_ADCBISDONE 1
114#define MC13783_IRQ_TS 2
115#define MC13783_IRQ_WHIGH 3
116#define MC13783_IRQ_WLOW 4
117#define MC13783_IRQ_CHGDET 6
118#define MC13783_IRQ_CHGOV 7
119#define MC13783_IRQ_CHGREV 8
120#define MC13783_IRQ_CHGSHORT 9
121#define MC13783_IRQ_CCCV 10
122#define MC13783_IRQ_CHGCURR 11
123#define MC13783_IRQ_BPON 12
124#define MC13783_IRQ_LOBATL 13
125#define MC13783_IRQ_LOBATH 14
126#define MC13783_IRQ_UDP 15
127#define MC13783_IRQ_USB 16
128#define MC13783_IRQ_ID 19
129#define MC13783_IRQ_SE1 21
130#define MC13783_IRQ_CKDET 22
131#define MC13783_IRQ_UDM 23
132#define MC13783_IRQ_1HZ 24
133#define MC13783_IRQ_TODA 25
134#define MC13783_IRQ_ONOFD1 27
135#define MC13783_IRQ_ONOFD2 28
136#define MC13783_IRQ_ONOFD3 29
137#define MC13783_IRQ_SYSRST 30
138#define MC13783_IRQ_RTCRST 31
139#define MC13783_IRQ_PC 32
140#define MC13783_IRQ_WARM 33
141#define MC13783_IRQ_MEMHLD 34
142#define MC13783_IRQ_PWRRDY 35
143#define MC13783_IRQ_THWARNL 36
144#define MC13783_IRQ_THWARNH 37
145#define MC13783_IRQ_CLK 38
146#define MC13783_IRQ_SEMAF 39
147#define MC13783_IRQ_MC2B 41
148#define MC13783_IRQ_HSDET 42
149#define MC13783_IRQ_HSL 43
150#define MC13783_IRQ_ALSPTH 44
151#define MC13783_IRQ_AHSSHORT 45
152#define MC13783_NUM_IRQ 46
84 153
154#endif /* __LINUX_MFD_MC13783_H */