• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/mfd/
1/*
2 * Driver for Motorola PCAP2 as present in EZX phones
3 *
4 * Copyright (C) 2006 Harald Welte <laforge@openezx.org>
5 * Copyright (C) 2009 Daniel Ribeiro <drwyrm@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/mfd/ezx-pcap.h>
19#include <linux/spi/spi.h>
20#include <linux/gpio.h>
21#include <linux/slab.h>
22
23#define PCAP_ADC_MAXQ		8
24struct pcap_adc_request {
25	u8 bank;
26	u8 ch[2];
27	u32 flags;
28	void (*callback)(void *, u16[]);
29	void *data;
30};
31
32struct pcap_adc_sync_request {
33	u16 res[2];
34	struct completion completion;
35};
36
37struct pcap_chip {
38	struct spi_device *spi;
39
40	/* IO */
41	u32 buf;
42	struct mutex io_mutex;
43
44	/* IRQ */
45	unsigned int irq_base;
46	u32 msr;
47	struct work_struct isr_work;
48	struct work_struct msr_work;
49	struct workqueue_struct *workqueue;
50
51	/* ADC */
52	struct pcap_adc_request *adc_queue[PCAP_ADC_MAXQ];
53	u8 adc_head;
54	u8 adc_tail;
55	struct mutex adc_mutex;
56};
57
58/* IO */
59static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data)
60{
61	struct spi_transfer t;
62	struct spi_message m;
63	int status;
64
65	memset(&t, 0, sizeof t);
66	spi_message_init(&m);
67	t.len = sizeof(u32);
68	spi_message_add_tail(&t, &m);
69
70	pcap->buf = *data;
71	t.tx_buf = (u8 *) &pcap->buf;
72	t.rx_buf = (u8 *) &pcap->buf;
73	status = spi_sync(pcap->spi, &m);
74
75	if (status == 0)
76		*data = pcap->buf;
77
78	return status;
79}
80
81int ezx_pcap_write(struct pcap_chip *pcap, u8 reg_num, u32 value)
82{
83	int ret;
84
85	mutex_lock(&pcap->io_mutex);
86	value &= PCAP_REGISTER_VALUE_MASK;
87	value |= PCAP_REGISTER_WRITE_OP_BIT
88		| (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
89	ret = ezx_pcap_putget(pcap, &value);
90	mutex_unlock(&pcap->io_mutex);
91
92	return ret;
93}
94EXPORT_SYMBOL_GPL(ezx_pcap_write);
95
96int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value)
97{
98	int ret;
99
100	mutex_lock(&pcap->io_mutex);
101	*value = PCAP_REGISTER_READ_OP_BIT
102		| (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
103
104	ret = ezx_pcap_putget(pcap, value);
105	mutex_unlock(&pcap->io_mutex);
106
107	return ret;
108}
109EXPORT_SYMBOL_GPL(ezx_pcap_read);
110
111int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val)
112{
113	int ret;
114	u32 tmp = PCAP_REGISTER_READ_OP_BIT |
115		(reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
116
117	mutex_lock(&pcap->io_mutex);
118	ret = ezx_pcap_putget(pcap, &tmp);
119	if (ret)
120		goto out_unlock;
121
122	tmp &= (PCAP_REGISTER_VALUE_MASK & ~mask);
123	tmp |= (val & mask) | PCAP_REGISTER_WRITE_OP_BIT |
124		(reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
125
126	ret = ezx_pcap_putget(pcap, &tmp);
127out_unlock:
128	mutex_unlock(&pcap->io_mutex);
129
130	return ret;
131}
132EXPORT_SYMBOL_GPL(ezx_pcap_set_bits);
133
134/* IRQ */
135int irq_to_pcap(struct pcap_chip *pcap, int irq)
136{
137	return irq - pcap->irq_base;
138}
139EXPORT_SYMBOL_GPL(irq_to_pcap);
140
141int pcap_to_irq(struct pcap_chip *pcap, int irq)
142{
143	return pcap->irq_base + irq;
144}
145EXPORT_SYMBOL_GPL(pcap_to_irq);
146
147static void pcap_mask_irq(unsigned int irq)
148{
149	struct pcap_chip *pcap = get_irq_chip_data(irq);
150
151	pcap->msr |= 1 << irq_to_pcap(pcap, irq);
152	queue_work(pcap->workqueue, &pcap->msr_work);
153}
154
155static void pcap_unmask_irq(unsigned int irq)
156{
157	struct pcap_chip *pcap = get_irq_chip_data(irq);
158
159	pcap->msr &= ~(1 << irq_to_pcap(pcap, irq));
160	queue_work(pcap->workqueue, &pcap->msr_work);
161}
162
163static struct irq_chip pcap_irq_chip = {
164	.name	= "pcap",
165	.mask	= pcap_mask_irq,
166	.unmask	= pcap_unmask_irq,
167};
168
169static void pcap_msr_work(struct work_struct *work)
170{
171	struct pcap_chip *pcap = container_of(work, struct pcap_chip, msr_work);
172
173	ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
174}
175
176static void pcap_isr_work(struct work_struct *work)
177{
178	struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work);
179	struct pcap_platform_data *pdata = pcap->spi->dev.platform_data;
180	u32 msr, isr, int_sel, service;
181	int irq;
182
183	do {
184		ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
185		ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
186
187		/* We cant service/ack irqs that are assigned to port 2 */
188		if (!(pdata->config & PCAP_SECOND_PORT)) {
189			ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
190			isr &= ~int_sel;
191		}
192
193		ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
194		ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
195
196		local_irq_disable();
197		service = isr & ~msr;
198		for (irq = pcap->irq_base; service; service >>= 1, irq++) {
199			if (service & 1) {
200				struct irq_desc *desc = irq_to_desc(irq);
201
202				if (WARN(!desc, KERN_WARNING
203						"Invalid PCAP IRQ %d\n", irq))
204					break;
205
206				if (desc->status & IRQ_DISABLED)
207					note_interrupt(irq, desc, IRQ_NONE);
208				else
209					desc->handle_irq(irq, desc);
210			}
211		}
212		local_irq_enable();
213		ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
214	} while (gpio_get_value(irq_to_gpio(pcap->spi->irq)));
215}
216
217static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
218{
219	struct pcap_chip *pcap = get_irq_data(irq);
220
221	desc->chip->ack(irq);
222	queue_work(pcap->workqueue, &pcap->isr_work);
223	return;
224}
225
226/* ADC */
227void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits)
228{
229	u32 tmp;
230
231	mutex_lock(&pcap->adc_mutex);
232	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
233	tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
234	tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
235	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
236	mutex_unlock(&pcap->adc_mutex);
237}
238EXPORT_SYMBOL_GPL(pcap_set_ts_bits);
239
240static void pcap_disable_adc(struct pcap_chip *pcap)
241{
242	u32 tmp;
243
244	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
245	tmp &= ~(PCAP_ADC_ADEN|PCAP_ADC_BATT_I_ADC|PCAP_ADC_BATT_I_POLARITY);
246	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
247}
248
249static void pcap_adc_trigger(struct pcap_chip *pcap)
250{
251	u32 tmp;
252	u8 head;
253
254	mutex_lock(&pcap->adc_mutex);
255	head = pcap->adc_head;
256	if (!pcap->adc_queue[head]) {
257		/* queue is empty, save power */
258		pcap_disable_adc(pcap);
259		mutex_unlock(&pcap->adc_mutex);
260		return;
261	}
262	/* start conversion on requested bank, save TS_M bits */
263	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
264	tmp &= (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
265	tmp |= pcap->adc_queue[head]->flags | PCAP_ADC_ADEN;
266
267	if (pcap->adc_queue[head]->bank == PCAP_ADC_BANK_1)
268		tmp |= PCAP_ADC_AD_SEL1;
269
270	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
271	mutex_unlock(&pcap->adc_mutex);
272	ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
273}
274
275static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
276{
277	struct pcap_chip *pcap = _pcap;
278	struct pcap_adc_request *req;
279	u16 res[2];
280	u32 tmp;
281
282	mutex_lock(&pcap->adc_mutex);
283	req = pcap->adc_queue[pcap->adc_head];
284
285	if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) {
286		mutex_unlock(&pcap->adc_mutex);
287		return IRQ_HANDLED;
288	}
289
290	/* read requested channels results */
291	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
292	tmp &= ~(PCAP_ADC_ADA1_MASK | PCAP_ADC_ADA2_MASK);
293	tmp |= (req->ch[0] << PCAP_ADC_ADA1_SHIFT);
294	tmp |= (req->ch[1] << PCAP_ADC_ADA2_SHIFT);
295	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
296	ezx_pcap_read(pcap, PCAP_REG_ADR, &tmp);
297	res[0] = (tmp & PCAP_ADR_ADD1_MASK) >> PCAP_ADR_ADD1_SHIFT;
298	res[1] = (tmp & PCAP_ADR_ADD2_MASK) >> PCAP_ADR_ADD2_SHIFT;
299
300	pcap->adc_queue[pcap->adc_head] = NULL;
301	pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1);
302	mutex_unlock(&pcap->adc_mutex);
303
304	/* pass the results and release memory */
305	req->callback(req->data, res);
306	kfree(req);
307
308	/* trigger next conversion (if any) on queue */
309	pcap_adc_trigger(pcap);
310
311	return IRQ_HANDLED;
312}
313
314int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
315						void *callback, void *data)
316{
317	struct pcap_adc_request *req;
318
319	/* This will be freed after we have a result */
320	req = kmalloc(sizeof(struct pcap_adc_request), GFP_KERNEL);
321	if (!req)
322		return -ENOMEM;
323
324	req->bank = bank;
325	req->flags = flags;
326	req->ch[0] = ch[0];
327	req->ch[1] = ch[1];
328	req->callback = callback;
329	req->data = data;
330
331	mutex_lock(&pcap->adc_mutex);
332	if (pcap->adc_queue[pcap->adc_tail]) {
333		mutex_unlock(&pcap->adc_mutex);
334		kfree(req);
335		return -EBUSY;
336	}
337	pcap->adc_queue[pcap->adc_tail] = req;
338	pcap->adc_tail = (pcap->adc_tail + 1) & (PCAP_ADC_MAXQ - 1);
339	mutex_unlock(&pcap->adc_mutex);
340
341	/* start conversion */
342	pcap_adc_trigger(pcap);
343
344	return 0;
345}
346EXPORT_SYMBOL_GPL(pcap_adc_async);
347
348static void pcap_adc_sync_cb(void *param, u16 res[])
349{
350	struct pcap_adc_sync_request *req = param;
351
352	req->res[0] = res[0];
353	req->res[1] = res[1];
354	complete(&req->completion);
355}
356
357int pcap_adc_sync(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
358								u16 res[])
359{
360	struct pcap_adc_sync_request sync_data;
361	int ret;
362
363	init_completion(&sync_data.completion);
364	ret = pcap_adc_async(pcap, bank, flags, ch, pcap_adc_sync_cb,
365								&sync_data);
366	if (ret)
367		return ret;
368	wait_for_completion(&sync_data.completion);
369	res[0] = sync_data.res[0];
370	res[1] = sync_data.res[1];
371
372	return 0;
373}
374EXPORT_SYMBOL_GPL(pcap_adc_sync);
375
376/* subdevs */
377static int pcap_remove_subdev(struct device *dev, void *unused)
378{
379	platform_device_unregister(to_platform_device(dev));
380	return 0;
381}
382
383static int __devinit pcap_add_subdev(struct pcap_chip *pcap,
384						struct pcap_subdev *subdev)
385{
386	struct platform_device *pdev;
387
388	pdev = platform_device_alloc(subdev->name, subdev->id);
389	pdev->dev.parent = &pcap->spi->dev;
390	pdev->dev.platform_data = subdev->platform_data;
391
392	return platform_device_add(pdev);
393}
394
395static int __devexit ezx_pcap_remove(struct spi_device *spi)
396{
397	struct pcap_chip *pcap = dev_get_drvdata(&spi->dev);
398	struct pcap_platform_data *pdata = spi->dev.platform_data;
399	int i, adc_irq;
400
401	/* remove all registered subdevs */
402	device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
403
404	/* cleanup ADC */
405	adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
406				PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);
407	free_irq(adc_irq, pcap);
408	mutex_lock(&pcap->adc_mutex);
409	for (i = 0; i < PCAP_ADC_MAXQ; i++)
410		kfree(pcap->adc_queue[i]);
411	mutex_unlock(&pcap->adc_mutex);
412
413	/* cleanup irqchip */
414	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
415		set_irq_chip_and_handler(i, NULL, NULL);
416
417	destroy_workqueue(pcap->workqueue);
418
419	kfree(pcap);
420
421	return 0;
422}
423
424static int __devinit ezx_pcap_probe(struct spi_device *spi)
425{
426	struct pcap_platform_data *pdata = spi->dev.platform_data;
427	struct pcap_chip *pcap;
428	int i, adc_irq;
429	int ret = -ENODEV;
430
431	/* platform data is required */
432	if (!pdata)
433		goto ret;
434
435	pcap = kzalloc(sizeof(*pcap), GFP_KERNEL);
436	if (!pcap) {
437		ret = -ENOMEM;
438		goto ret;
439	}
440
441	mutex_init(&pcap->io_mutex);
442	mutex_init(&pcap->adc_mutex);
443	INIT_WORK(&pcap->isr_work, pcap_isr_work);
444	INIT_WORK(&pcap->msr_work, pcap_msr_work);
445	dev_set_drvdata(&spi->dev, pcap);
446
447	/* setup spi */
448	spi->bits_per_word = 32;
449	spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0);
450	ret = spi_setup(spi);
451	if (ret)
452		goto free_pcap;
453
454	pcap->spi = spi;
455
456	/* setup irq */
457	pcap->irq_base = pdata->irq_base;
458	pcap->workqueue = create_singlethread_workqueue("pcapd");
459	if (!pcap->workqueue) {
460		dev_err(&spi->dev, "cant create pcap thread\n");
461		goto free_pcap;
462	}
463
464	/* redirect interrupts to AP, except adcdone2 */
465	if (!(pdata->config & PCAP_SECOND_PORT))
466		ezx_pcap_write(pcap, PCAP_REG_INT_SEL,
467					(1 << PCAP_IRQ_ADCDONE2));
468
469	/* setup irq chip */
470	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) {
471		set_irq_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq);
472		set_irq_chip_data(i, pcap);
473#ifdef CONFIG_ARM
474		set_irq_flags(i, IRQF_VALID);
475#else
476		set_irq_noprobe(i);
477#endif
478	}
479
480	/* mask/ack all PCAP interrupts */
481	ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT);
482	ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER);
483	pcap->msr = PCAP_MASK_ALL_INTERRUPT;
484
485	set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING);
486	set_irq_data(spi->irq, pcap);
487	set_irq_chained_handler(spi->irq, pcap_irq_handler);
488	set_irq_wake(spi->irq, 1);
489
490	/* ADC */
491	adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
492					PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);
493
494	ret = request_irq(adc_irq, pcap_adc_irq, 0, "ADC", pcap);
495	if (ret)
496		goto free_irqchip;
497
498	/* setup subdevs */
499	for (i = 0; i < pdata->num_subdevs; i++) {
500		ret = pcap_add_subdev(pcap, &pdata->subdevs[i]);
501		if (ret)
502			goto remove_subdevs;
503	}
504
505	/* board specific quirks */
506	if (pdata->init)
507		pdata->init(pcap);
508
509	return 0;
510
511remove_subdevs:
512	device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
513/* free_adc: */
514	free_irq(adc_irq, pcap);
515free_irqchip:
516	for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
517		set_irq_chip_and_handler(i, NULL, NULL);
518/* destroy_workqueue: */
519	destroy_workqueue(pcap->workqueue);
520free_pcap:
521	kfree(pcap);
522ret:
523	return ret;
524}
525
526static struct spi_driver ezxpcap_driver = {
527	.probe	= ezx_pcap_probe,
528	.remove = __devexit_p(ezx_pcap_remove),
529	.driver = {
530		.name	= "ezx-pcap",
531		.owner	= THIS_MODULE,
532	},
533};
534
535static int __init ezx_pcap_init(void)
536{
537	return spi_register_driver(&ezxpcap_driver);
538}
539
540static void __exit ezx_pcap_exit(void)
541{
542	spi_unregister_driver(&ezxpcap_driver);
543}
544
545subsys_initcall(ezx_pcap_init);
546module_exit(ezx_pcap_exit);
547
548MODULE_LICENSE("GPL");
549MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
550MODULE_DESCRIPTION("Motorola PCAP2 ASIC Driver");
551MODULE_ALIAS("spi:ezx-pcap");
552