linux/drivers/mfd/ezx-pcap.c
<<
>>
Prefs
   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
  22#define PCAP_ADC_MAXQ           8
  23struct pcap_adc_request {
  24        u8 bank;
  25        u8 ch[2];
  26        u32 flags;
  27        void (*callback)(void *, u16[]);
  28        void *data;
  29};
  30
  31struct pcap_adc_sync_request {
  32        u16 res[2];
  33        struct completion completion;
  34};
  35
  36struct pcap_chip {
  37        struct spi_device *spi;
  38
  39        /* IO */
  40        u32 buf;
  41        struct mutex io_mutex;
  42
  43        /* IRQ */
  44        unsigned int irq_base;
  45        u32 msr;
  46        struct work_struct isr_work;
  47        struct work_struct msr_work;
  48        struct workqueue_struct *workqueue;
  49
  50        /* ADC */
  51        struct pcap_adc_request *adc_queue[PCAP_ADC_MAXQ];
  52        u8 adc_head;
  53        u8 adc_tail;
  54        struct mutex adc_mutex;
  55};
  56
  57/* IO */
  58static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data)
  59{
  60        struct spi_transfer t;
  61        struct spi_message m;
  62        int status;
  63
  64        memset(&t, 0, sizeof t);
  65        spi_message_init(&m);
  66        t.len = sizeof(u32);
  67        spi_message_add_tail(&t, &m);
  68
  69        pcap->buf = *data;
  70        t.tx_buf = (u8 *) &pcap->buf;
  71        t.rx_buf = (u8 *) &pcap->buf;
  72        status = spi_sync(pcap->spi, &m);
  73
  74        if (status == 0)
  75                *data = pcap->buf;
  76
  77        return status;
  78}
  79
  80int ezx_pcap_write(struct pcap_chip *pcap, u8 reg_num, u32 value)
  81{
  82        int ret;
  83
  84        mutex_lock(&pcap->io_mutex);
  85        value &= PCAP_REGISTER_VALUE_MASK;
  86        value |= PCAP_REGISTER_WRITE_OP_BIT
  87                | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
  88        ret = ezx_pcap_putget(pcap, &value);
  89        mutex_unlock(&pcap->io_mutex);
  90
  91        return ret;
  92}
  93EXPORT_SYMBOL_GPL(ezx_pcap_write);
  94
  95int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value)
  96{
  97        int ret;
  98
  99        mutex_lock(&pcap->io_mutex);
 100        *value = PCAP_REGISTER_READ_OP_BIT
 101                | (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
 102
 103        ret = ezx_pcap_putget(pcap, value);
 104        mutex_unlock(&pcap->io_mutex);
 105
 106        return ret;
 107}
 108EXPORT_SYMBOL_GPL(ezx_pcap_read);
 109
 110int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val)
 111{
 112        int ret;
 113        u32 tmp = PCAP_REGISTER_READ_OP_BIT |
 114                (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
 115
 116        mutex_lock(&pcap->io_mutex);
 117        ret = ezx_pcap_putget(pcap, &tmp);
 118        if (ret)
 119                goto out_unlock;
 120
 121        tmp &= (PCAP_REGISTER_VALUE_MASK & ~mask);
 122        tmp |= (val & mask) | PCAP_REGISTER_WRITE_OP_BIT |
 123                (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
 124
 125        ret = ezx_pcap_putget(pcap, &tmp);
 126out_unlock:
 127        mutex_unlock(&pcap->io_mutex);
 128
 129        return ret;
 130}
 131EXPORT_SYMBOL_GPL(ezx_pcap_set_bits);
 132
 133/* IRQ */
 134int irq_to_pcap(struct pcap_chip *pcap, int irq)
 135{
 136        return irq - pcap->irq_base;
 137}
 138EXPORT_SYMBOL_GPL(irq_to_pcap);
 139
 140int pcap_to_irq(struct pcap_chip *pcap, int irq)
 141{
 142        return pcap->irq_base + irq;
 143}
 144EXPORT_SYMBOL_GPL(pcap_to_irq);
 145
 146static void pcap_mask_irq(unsigned int irq)
 147{
 148        struct pcap_chip *pcap = get_irq_chip_data(irq);
 149
 150        pcap->msr |= 1 << irq_to_pcap(pcap, irq);
 151        queue_work(pcap->workqueue, &pcap->msr_work);
 152}
 153
 154static void pcap_unmask_irq(unsigned int irq)
 155{
 156        struct pcap_chip *pcap = get_irq_chip_data(irq);
 157
 158        pcap->msr &= ~(1 << irq_to_pcap(pcap, irq));
 159        queue_work(pcap->workqueue, &pcap->msr_work);
 160}
 161
 162static struct irq_chip pcap_irq_chip = {
 163        .name   = "pcap",
 164        .mask   = pcap_mask_irq,
 165        .unmask = pcap_unmask_irq,
 166};
 167
 168static void pcap_msr_work(struct work_struct *work)
 169{
 170        struct pcap_chip *pcap = container_of(work, struct pcap_chip, msr_work);
 171
 172        ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
 173}
 174
 175static void pcap_isr_work(struct work_struct *work)
 176{
 177        struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work);
 178        struct pcap_platform_data *pdata = pcap->spi->dev.platform_data;
 179        u32 msr, isr, int_sel, service;
 180        int irq;
 181
 182        do {
 183                ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
 184                ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
 185
 186                /* We cant service/ack irqs that are assigned to port 2 */
 187                if (!(pdata->config & PCAP_SECOND_PORT)) {
 188                        ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
 189                        isr &= ~int_sel;
 190                }
 191
 192                ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
 193                ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
 194
 195                local_irq_disable();
 196                service = isr & ~msr;
 197                for (irq = pcap->irq_base; service; service >>= 1, irq++) {
 198                        if (service & 1) {
 199                                struct irq_desc *desc = irq_to_desc(irq);
 200
 201                                if (WARN(!desc, KERN_WARNING
 202                                                "Invalid PCAP IRQ %d\n", irq))
 203                                        break;
 204
 205                                if (desc->status & IRQ_DISABLED)
 206                                        note_interrupt(irq, desc, IRQ_NONE);
 207                                else
 208                                        desc->handle_irq(irq, desc);
 209                        }
 210                }
 211                local_irq_enable();
 212                ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
 213        } while (gpio_get_value(irq_to_gpio(pcap->spi->irq)));
 214}
 215
 216static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
 217{
 218        struct pcap_chip *pcap = get_irq_data(irq);
 219
 220        desc->chip->ack(irq);
 221        queue_work(pcap->workqueue, &pcap->isr_work);
 222        return;
 223}
 224
 225/* ADC */
 226void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits)
 227{
 228        u32 tmp;
 229
 230        mutex_lock(&pcap->adc_mutex);
 231        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 232        tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
 233        tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
 234        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 235        mutex_unlock(&pcap->adc_mutex);
 236}
 237EXPORT_SYMBOL_GPL(pcap_set_ts_bits);
 238
 239static void pcap_disable_adc(struct pcap_chip *pcap)
 240{
 241        u32 tmp;
 242
 243        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 244        tmp &= ~(PCAP_ADC_ADEN|PCAP_ADC_BATT_I_ADC|PCAP_ADC_BATT_I_POLARITY);
 245        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 246}
 247
 248static void pcap_adc_trigger(struct pcap_chip *pcap)
 249{
 250        u32 tmp;
 251        u8 head;
 252
 253        mutex_lock(&pcap->adc_mutex);
 254        head = pcap->adc_head;
 255        if (!pcap->adc_queue[head]) {
 256                /* queue is empty, save power */
 257                pcap_disable_adc(pcap);
 258                mutex_unlock(&pcap->adc_mutex);
 259                return;
 260        }
 261        /* start conversion on requested bank, save TS_M bits */
 262        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 263        tmp &= (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
 264        tmp |= pcap->adc_queue[head]->flags | PCAP_ADC_ADEN;
 265
 266        if (pcap->adc_queue[head]->bank == PCAP_ADC_BANK_1)
 267                tmp |= PCAP_ADC_AD_SEL1;
 268
 269        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 270        mutex_unlock(&pcap->adc_mutex);
 271        ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
 272}
 273
 274static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
 275{
 276        struct pcap_chip *pcap = _pcap;
 277        struct pcap_adc_request *req;
 278        u16 res[2];
 279        u32 tmp;
 280
 281        mutex_lock(&pcap->adc_mutex);
 282        req = pcap->adc_queue[pcap->adc_head];
 283
 284        if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) {
 285                mutex_unlock(&pcap->adc_mutex);
 286                return IRQ_HANDLED;
 287        }
 288
 289        /* read requested channels results */
 290        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 291        tmp &= ~(PCAP_ADC_ADA1_MASK | PCAP_ADC_ADA2_MASK);
 292        tmp |= (req->ch[0] << PCAP_ADC_ADA1_SHIFT);
 293        tmp |= (req->ch[1] << PCAP_ADC_ADA2_SHIFT);
 294        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 295        ezx_pcap_read(pcap, PCAP_REG_ADR, &tmp);
 296        res[0] = (tmp & PCAP_ADR_ADD1_MASK) >> PCAP_ADR_ADD1_SHIFT;
 297        res[1] = (tmp & PCAP_ADR_ADD2_MASK) >> PCAP_ADR_ADD2_SHIFT;
 298
 299        pcap->adc_queue[pcap->adc_head] = NULL;
 300        pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1);
 301        mutex_unlock(&pcap->adc_mutex);
 302
 303        /* pass the results and release memory */
 304        req->callback(req->data, res);
 305        kfree(req);
 306
 307        /* trigger next conversion (if any) on queue */
 308        pcap_adc_trigger(pcap);
 309
 310        return IRQ_HANDLED;
 311}
 312
 313int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
 314                                                void *callback, void *data)
 315{
 316        struct pcap_adc_request *req;
 317
 318        /* This will be freed after we have a result */
 319        req = kmalloc(sizeof(struct pcap_adc_request), GFP_KERNEL);
 320        if (!req)
 321                return -ENOMEM;
 322
 323        req->bank = bank;
 324        req->flags = flags;
 325        req->ch[0] = ch[0];
 326        req->ch[1] = ch[1];
 327        req->callback = callback;
 328        req->data = data;
 329
 330        mutex_lock(&pcap->adc_mutex);
 331        if (pcap->adc_queue[pcap->adc_tail]) {
 332                mutex_unlock(&pcap->adc_mutex);
 333                kfree(req);
 334                return -EBUSY;
 335        }
 336        pcap->adc_queue[pcap->adc_tail] = req;
 337        pcap->adc_tail = (pcap->adc_tail + 1) & (PCAP_ADC_MAXQ - 1);
 338        mutex_unlock(&pcap->adc_mutex);
 339
 340        /* start conversion */
 341        pcap_adc_trigger(pcap);
 342
 343        return 0;
 344}
 345EXPORT_SYMBOL_GPL(pcap_adc_async);
 346
 347static void pcap_adc_sync_cb(void *param, u16 res[])
 348{
 349        struct pcap_adc_sync_request *req = param;
 350
 351        req->res[0] = res[0];
 352        req->res[1] = res[1];
 353        complete(&req->completion);
 354}
 355
 356int pcap_adc_sync(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
 357                                                                u16 res[])
 358{
 359        struct pcap_adc_sync_request sync_data;
 360        int ret;
 361
 362        init_completion(&sync_data.completion);
 363        ret = pcap_adc_async(pcap, bank, flags, ch, pcap_adc_sync_cb,
 364                                                                &sync_data);
 365        if (ret)
 366                return ret;
 367        wait_for_completion(&sync_data.completion);
 368        res[0] = sync_data.res[0];
 369        res[1] = sync_data.res[1];
 370
 371        return 0;
 372}
 373EXPORT_SYMBOL_GPL(pcap_adc_sync);
 374
 375/* subdevs */
 376static int pcap_remove_subdev(struct device *dev, void *unused)
 377{
 378        platform_device_unregister(to_platform_device(dev));
 379        return 0;
 380}
 381
 382static int __devinit pcap_add_subdev(struct pcap_chip *pcap,
 383                                                struct pcap_subdev *subdev)
 384{
 385        struct platform_device *pdev;
 386
 387        pdev = platform_device_alloc(subdev->name, subdev->id);
 388        pdev->dev.parent = &pcap->spi->dev;
 389        pdev->dev.platform_data = subdev->platform_data;
 390        platform_set_drvdata(pdev, pcap);
 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