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#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(struct irq_data *d)
 148{
 149        struct pcap_chip *pcap = irq_data_get_irq_chip_data(d);
 150
 151        pcap->msr |= 1 << irq_to_pcap(pcap, d->irq);
 152        queue_work(pcap->workqueue, &pcap->msr_work);
 153}
 154
 155static void pcap_unmask_irq(struct irq_data *d)
 156{
 157        struct pcap_chip *pcap = irq_data_get_irq_chip_data(d);
 158
 159        pcap->msr &= ~(1 << irq_to_pcap(pcap, d->irq));
 160        queue_work(pcap->workqueue, &pcap->msr_work);
 161}
 162
 163static struct irq_chip pcap_irq_chip = {
 164        .name           = "pcap",
 165        .irq_disable    = pcap_mask_irq,
 166        .irq_mask       = pcap_mask_irq,
 167        .irq_unmask     = pcap_unmask_irq,
 168};
 169
 170static void pcap_msr_work(struct work_struct *work)
 171{
 172        struct pcap_chip *pcap = container_of(work, struct pcap_chip, msr_work);
 173
 174        ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
 175}
 176
 177static void pcap_isr_work(struct work_struct *work)
 178{
 179        struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work);
 180        struct pcap_platform_data *pdata = pcap->spi->dev.platform_data;
 181        u32 msr, isr, int_sel, service;
 182        int irq;
 183
 184        do {
 185                ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
 186                ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
 187
 188                /* We can't service/ack irqs that are assigned to port 2 */
 189                if (!(pdata->config & PCAP_SECOND_PORT)) {
 190                        ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
 191                        isr &= ~int_sel;
 192                }
 193
 194                ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
 195                ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
 196
 197                local_irq_disable();
 198                service = isr & ~msr;
 199                for (irq = pcap->irq_base; service; service >>= 1, irq++) {
 200                        if (service & 1)
 201                                generic_handle_irq(irq);
 202                }
 203                local_irq_enable();
 204                ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
 205        } while (gpio_get_value(pdata->gpio));
 206}
 207
 208static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
 209{
 210        struct pcap_chip *pcap = irq_get_handler_data(irq);
 211
 212        desc->irq_data.chip->irq_ack(&desc->irq_data);
 213        queue_work(pcap->workqueue, &pcap->isr_work);
 214        return;
 215}
 216
 217/* ADC */
 218void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits)
 219{
 220        u32 tmp;
 221
 222        mutex_lock(&pcap->adc_mutex);
 223        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 224        tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
 225        tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
 226        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 227        mutex_unlock(&pcap->adc_mutex);
 228}
 229EXPORT_SYMBOL_GPL(pcap_set_ts_bits);
 230
 231static void pcap_disable_adc(struct pcap_chip *pcap)
 232{
 233        u32 tmp;
 234
 235        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 236        tmp &= ~(PCAP_ADC_ADEN|PCAP_ADC_BATT_I_ADC|PCAP_ADC_BATT_I_POLARITY);
 237        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 238}
 239
 240static void pcap_adc_trigger(struct pcap_chip *pcap)
 241{
 242        u32 tmp;
 243        u8 head;
 244
 245        mutex_lock(&pcap->adc_mutex);
 246        head = pcap->adc_head;
 247        if (!pcap->adc_queue[head]) {
 248                /* queue is empty, save power */
 249                pcap_disable_adc(pcap);
 250                mutex_unlock(&pcap->adc_mutex);
 251                return;
 252        }
 253        /* start conversion on requested bank, save TS_M bits */
 254        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 255        tmp &= (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
 256        tmp |= pcap->adc_queue[head]->flags | PCAP_ADC_ADEN;
 257
 258        if (pcap->adc_queue[head]->bank == PCAP_ADC_BANK_1)
 259                tmp |= PCAP_ADC_AD_SEL1;
 260
 261        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 262        mutex_unlock(&pcap->adc_mutex);
 263        ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
 264}
 265
 266static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
 267{
 268        struct pcap_chip *pcap = _pcap;
 269        struct pcap_adc_request *req;
 270        u16 res[2];
 271        u32 tmp;
 272
 273        mutex_lock(&pcap->adc_mutex);
 274        req = pcap->adc_queue[pcap->adc_head];
 275
 276        if (WARN(!req, "adc irq without pending request\n")) {
 277                mutex_unlock(&pcap->adc_mutex);
 278                return IRQ_HANDLED;
 279        }
 280
 281        /* read requested channels results */
 282        ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
 283        tmp &= ~(PCAP_ADC_ADA1_MASK | PCAP_ADC_ADA2_MASK);
 284        tmp |= (req->ch[0] << PCAP_ADC_ADA1_SHIFT);
 285        tmp |= (req->ch[1] << PCAP_ADC_ADA2_SHIFT);
 286        ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
 287        ezx_pcap_read(pcap, PCAP_REG_ADR, &tmp);
 288        res[0] = (tmp & PCAP_ADR_ADD1_MASK) >> PCAP_ADR_ADD1_SHIFT;
 289        res[1] = (tmp & PCAP_ADR_ADD2_MASK) >> PCAP_ADR_ADD2_SHIFT;
 290
 291        pcap->adc_queue[pcap->adc_head] = NULL;
 292        pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1);
 293        mutex_unlock(&pcap->adc_mutex);
 294
 295        /* pass the results and release memory */
 296        req->callback(req->data, res);
 297        kfree(req);
 298
 299        /* trigger next conversion (if any) on queue */
 300        pcap_adc_trigger(pcap);
 301
 302        return IRQ_HANDLED;
 303}
 304
 305int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
 306                                                void *callback, void *data)
 307{
 308        struct pcap_adc_request *req;
 309
 310        /* This will be freed after we have a result */
 311        req = kmalloc(sizeof(struct pcap_adc_request), GFP_KERNEL);
 312        if (!req)
 313                return -ENOMEM;
 314
 315        req->bank = bank;
 316        req->flags = flags;
 317        req->ch[0] = ch[0];
 318        req->ch[1] = ch[1];
 319        req->callback = callback;
 320        req->data = data;
 321
 322        mutex_lock(&pcap->adc_mutex);
 323        if (pcap->adc_queue[pcap->adc_tail]) {
 324                mutex_unlock(&pcap->adc_mutex);
 325                kfree(req);
 326                return -EBUSY;
 327        }
 328        pcap->adc_queue[pcap->adc_tail] = req;
 329        pcap->adc_tail = (pcap->adc_tail + 1) & (PCAP_ADC_MAXQ - 1);
 330        mutex_unlock(&pcap->adc_mutex);
 331
 332        /* start conversion */
 333        pcap_adc_trigger(pcap);
 334
 335        return 0;
 336}
 337EXPORT_SYMBOL_GPL(pcap_adc_async);
 338
 339static void pcap_adc_sync_cb(void *param, u16 res[])
 340{
 341        struct pcap_adc_sync_request *req = param;
 342
 343        req->res[0] = res[0];
 344        req->res[1] = res[1];
 345        complete(&req->completion);
 346}
 347
 348int pcap_adc_sync(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
 349                                                                u16 res[])
 350{
 351        struct pcap_adc_sync_request sync_data;
 352        int ret;
 353
 354        init_completion(&sync_data.completion);
 355        ret = pcap_adc_async(pcap, bank, flags, ch, pcap_adc_sync_cb,
 356                                                                &sync_data);
 357        if (ret)
 358                return ret;
 359        wait_for_completion(&sync_data.completion);
 360        res[0] = sync_data.res[0];
 361        res[1] = sync_data.res[1];
 362
 363        return 0;
 364}
 365EXPORT_SYMBOL_GPL(pcap_adc_sync);
 366
 367/* subdevs */
 368static int pcap_remove_subdev(struct device *dev, void *unused)
 369{
 370        platform_device_unregister(to_platform_device(dev));
 371        return 0;
 372}
 373
 374static int pcap_add_subdev(struct pcap_chip *pcap,
 375                                                struct pcap_subdev *subdev)
 376{
 377        struct platform_device *pdev;
 378        int ret;
 379
 380        pdev = platform_device_alloc(subdev->name, subdev->id);
 381        if (!pdev)
 382                return -ENOMEM;
 383
 384        pdev->dev.parent = &pcap->spi->dev;
 385        pdev->dev.platform_data = subdev->platform_data;
 386
 387        ret = platform_device_add(pdev);
 388        if (ret)
 389                platform_device_put(pdev);
 390
 391        return ret;
 392}
 393
 394static int ezx_pcap_remove(struct spi_device *spi)
 395{
 396        struct pcap_chip *pcap = spi_get_drvdata(spi);
 397        struct pcap_platform_data *pdata = spi->dev.platform_data;
 398        int i, adc_irq;
 399
 400        /* remove all registered subdevs */
 401        device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
 402
 403        /* cleanup ADC */
 404        adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
 405                                PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);
 406        devm_free_irq(&spi->dev, adc_irq, pcap);
 407        mutex_lock(&pcap->adc_mutex);
 408        for (i = 0; i < PCAP_ADC_MAXQ; i++)
 409                kfree(pcap->adc_queue[i]);
 410        mutex_unlock(&pcap->adc_mutex);
 411
 412        /* cleanup irqchip */
 413        for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
 414                irq_set_chip_and_handler(i, NULL, NULL);
 415
 416        destroy_workqueue(pcap->workqueue);
 417
 418        return 0;
 419}
 420
 421static int ezx_pcap_probe(struct spi_device *spi)
 422{
 423        struct pcap_platform_data *pdata = spi->dev.platform_data;
 424        struct pcap_chip *pcap;
 425        int i, adc_irq;
 426        int ret = -ENODEV;
 427
 428        /* platform data is required */
 429        if (!pdata)
 430                goto ret;
 431
 432        pcap = devm_kzalloc(&spi->dev, sizeof(*pcap), GFP_KERNEL);
 433        if (!pcap) {
 434                ret = -ENOMEM;
 435                goto ret;
 436        }
 437
 438        mutex_init(&pcap->io_mutex);
 439        mutex_init(&pcap->adc_mutex);
 440        INIT_WORK(&pcap->isr_work, pcap_isr_work);
 441        INIT_WORK(&pcap->msr_work, pcap_msr_work);
 442        spi_set_drvdata(spi, pcap);
 443
 444        /* setup spi */
 445        spi->bits_per_word = 32;
 446        spi->mode = SPI_MODE_0 | (pdata->config & PCAP_CS_AH ? SPI_CS_HIGH : 0);
 447        ret = spi_setup(spi);
 448        if (ret)
 449                goto ret;
 450
 451        pcap->spi = spi;
 452
 453        /* setup irq */
 454        pcap->irq_base = pdata->irq_base;
 455        pcap->workqueue = create_singlethread_workqueue("pcapd");
 456        if (!pcap->workqueue) {
 457                ret = -ENOMEM;
 458                dev_err(&spi->dev, "can't create pcap thread\n");
 459                goto ret;
 460        }
 461
 462        /* redirect interrupts to AP, except adcdone2 */
 463        if (!(pdata->config & PCAP_SECOND_PORT))
 464                ezx_pcap_write(pcap, PCAP_REG_INT_SEL,
 465                                        (1 << PCAP_IRQ_ADCDONE2));
 466
 467        /* setup irq chip */
 468        for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) {
 469                irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq);
 470                irq_set_chip_data(i, pcap);
 471#ifdef CONFIG_ARM
 472                set_irq_flags(i, IRQF_VALID);
 473#else
 474                irq_set_noprobe(i);
 475#endif
 476        }
 477
 478        /* mask/ack all PCAP interrupts */
 479        ezx_pcap_write(pcap, PCAP_REG_MSR, PCAP_MASK_ALL_INTERRUPT);
 480        ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER);
 481        pcap->msr = PCAP_MASK_ALL_INTERRUPT;
 482
 483        irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING);
 484        irq_set_handler_data(spi->irq, pcap);
 485        irq_set_chained_handler(spi->irq, pcap_irq_handler);
 486        irq_set_irq_wake(spi->irq, 1);
 487
 488        /* ADC */
 489        adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
 490                                        PCAP_IRQ_ADCDONE2 : PCAP_IRQ_ADCDONE);
 491
 492        ret = devm_request_irq(&spi->dev, adc_irq, pcap_adc_irq, 0, "ADC",
 493                                pcap);
 494        if (ret)
 495                goto free_irqchip;
 496
 497        /* setup subdevs */
 498        for (i = 0; i < pdata->num_subdevs; i++) {
 499                ret = pcap_add_subdev(pcap, &pdata->subdevs[i]);
 500                if (ret)
 501                        goto remove_subdevs;
 502        }
 503
 504        /* board specific quirks */
 505        if (pdata->init)
 506                pdata->init(pcap);
 507
 508        return 0;
 509
 510remove_subdevs:
 511        device_for_each_child(&spi->dev, NULL, pcap_remove_subdev);
 512/* free_adc: */
 513        devm_free_irq(&spi->dev, adc_irq, pcap);
 514free_irqchip:
 515        for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
 516                irq_set_chip_and_handler(i, NULL, NULL);
 517/* destroy_workqueue: */
 518        destroy_workqueue(pcap->workqueue);
 519ret:
 520        return ret;
 521}
 522
 523static struct spi_driver ezxpcap_driver = {
 524        .probe  = ezx_pcap_probe,
 525        .remove = ezx_pcap_remove,
 526        .driver = {
 527                .name   = "ezx-pcap",
 528                .owner  = THIS_MODULE,
 529        },
 530};
 531
 532static int __init ezx_pcap_init(void)
 533{
 534        return spi_register_driver(&ezxpcap_driver);
 535}
 536
 537static void __exit ezx_pcap_exit(void)
 538{
 539        spi_unregister_driver(&ezxpcap_driver);
 540}
 541
 542subsys_initcall(ezx_pcap_init);
 543module_exit(ezx_pcap_exit);
 544
 545MODULE_LICENSE("GPL");
 546MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
 547MODULE_DESCRIPTION("Motorola PCAP2 ASIC Driver");
 548MODULE_ALIAS("spi:ezx-pcap");
 549
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.