linux/drivers/mfd/da903x.c
<<
>>
Prefs
   1/*
   2 * Base driver for Dialog Semiconductor DA9030/DA9034
   3 *
   4 * Copyright (C) 2008 Compulab, Ltd.
   5 *      Mike Rapoport <mike@compulab.co.il>
   6 *
   7 * Copyright (C) 2006-2008 Marvell International Ltd.
   8 *      Eric Miao <eric.miao@marvell.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/interrupt.h>
  18#include <linux/platform_device.h>
  19#include <linux/i2c.h>
  20#include <linux/mfd/da903x.h>
  21#include <linux/slab.h>
  22
  23#define DA9030_CHIP_ID          0x00
  24#define DA9030_EVENT_A          0x01
  25#define DA9030_EVENT_B          0x02
  26#define DA9030_EVENT_C          0x03
  27#define DA9030_STATUS           0x04
  28#define DA9030_IRQ_MASK_A       0x05
  29#define DA9030_IRQ_MASK_B       0x06
  30#define DA9030_IRQ_MASK_C       0x07
  31#define DA9030_SYS_CTRL_A       0x08
  32#define DA9030_SYS_CTRL_B       0x09
  33#define DA9030_FAULT_LOG        0x0a
  34
  35#define DA9034_CHIP_ID          0x00
  36#define DA9034_EVENT_A          0x01
  37#define DA9034_EVENT_B          0x02
  38#define DA9034_EVENT_C          0x03
  39#define DA9034_EVENT_D          0x04
  40#define DA9034_STATUS_A         0x05
  41#define DA9034_STATUS_B         0x06
  42#define DA9034_IRQ_MASK_A       0x07
  43#define DA9034_IRQ_MASK_B       0x08
  44#define DA9034_IRQ_MASK_C       0x09
  45#define DA9034_IRQ_MASK_D       0x0a
  46#define DA9034_SYS_CTRL_A       0x0b
  47#define DA9034_SYS_CTRL_B       0x0c
  48#define DA9034_FAULT_LOG        0x0d
  49
  50struct da903x_chip;
  51
  52struct da903x_chip_ops {
  53        int     (*init_chip)(struct da903x_chip *);
  54        int     (*unmask_events)(struct da903x_chip *, unsigned int events);
  55        int     (*mask_events)(struct da903x_chip *, unsigned int events);
  56        int     (*read_events)(struct da903x_chip *, unsigned int *events);
  57        int     (*read_status)(struct da903x_chip *, unsigned int *status);
  58};
  59
  60struct da903x_chip {
  61        struct i2c_client       *client;
  62        struct device           *dev;
  63        struct da903x_chip_ops  *ops;
  64
  65        int                     type;
  66        uint32_t                events_mask;
  67
  68        struct mutex            lock;
  69        struct work_struct      irq_work;
  70
  71        struct blocking_notifier_head notifier_list;
  72};
  73
  74static inline int __da903x_read(struct i2c_client *client,
  75                                int reg, uint8_t *val)
  76{
  77        int ret;
  78
  79        ret = i2c_smbus_read_byte_data(client, reg);
  80        if (ret < 0) {
  81                dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
  82                return ret;
  83        }
  84
  85        *val = (uint8_t)ret;
  86        return 0;
  87}
  88
  89static inline int __da903x_reads(struct i2c_client *client, int reg,
  90                                 int len, uint8_t *val)
  91{
  92        int ret;
  93
  94        ret = i2c_smbus_read_i2c_block_data(client, reg, len, val);
  95        if (ret < 0) {
  96                dev_err(&client->dev, "failed reading from 0x%02x\n", reg);
  97                return ret;
  98        }
  99        return 0;
 100}
 101
 102static inline int __da903x_write(struct i2c_client *client,
 103                                 int reg, uint8_t val)
 104{
 105        int ret;
 106
 107        ret = i2c_smbus_write_byte_data(client, reg, val);
 108        if (ret < 0) {
 109                dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
 110                                val, reg);
 111                return ret;
 112        }
 113        return 0;
 114}
 115
 116static inline int __da903x_writes(struct i2c_client *client, int reg,
 117                                  int len, uint8_t *val)
 118{
 119        int ret;
 120
 121        ret = i2c_smbus_write_i2c_block_data(client, reg, len, val);
 122        if (ret < 0) {
 123                dev_err(&client->dev, "failed writings to 0x%02x\n", reg);
 124                return ret;
 125        }
 126        return 0;
 127}
 128
 129int da903x_register_notifier(struct device *dev, struct notifier_block *nb,
 130                                unsigned int events)
 131{
 132        struct da903x_chip *chip = dev_get_drvdata(dev);
 133
 134        chip->ops->unmask_events(chip, events);
 135        return blocking_notifier_chain_register(&chip->notifier_list, nb);
 136}
 137EXPORT_SYMBOL_GPL(da903x_register_notifier);
 138
 139int da903x_unregister_notifier(struct device *dev, struct notifier_block *nb,
 140                                unsigned int events)
 141{
 142        struct da903x_chip *chip = dev_get_drvdata(dev);
 143
 144        chip->ops->mask_events(chip, events);
 145        return blocking_notifier_chain_unregister(&chip->notifier_list, nb);
 146}
 147EXPORT_SYMBOL_GPL(da903x_unregister_notifier);
 148
 149int da903x_write(struct device *dev, int reg, uint8_t val)
 150{
 151        return __da903x_write(to_i2c_client(dev), reg, val);
 152}
 153EXPORT_SYMBOL_GPL(da903x_write);
 154
 155int da903x_writes(struct device *dev, int reg, int len, uint8_t *val)
 156{
 157        return __da903x_writes(to_i2c_client(dev), reg, len, val);
 158}
 159EXPORT_SYMBOL_GPL(da903x_writes);
 160
 161int da903x_read(struct device *dev, int reg, uint8_t *val)
 162{
 163        return __da903x_read(to_i2c_client(dev), reg, val);
 164}
 165EXPORT_SYMBOL_GPL(da903x_read);
 166
 167int da903x_reads(struct device *dev, int reg, int len, uint8_t *val)
 168{
 169        return __da903x_reads(to_i2c_client(dev), reg, len, val);
 170}
 171EXPORT_SYMBOL_GPL(da903x_reads);
 172
 173int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
 174{
 175        struct da903x_chip *chip = dev_get_drvdata(dev);
 176        uint8_t reg_val;
 177        int ret = 0;
 178
 179        mutex_lock(&chip->lock);
 180
 181        ret = __da903x_read(chip->client, reg, &reg_val);
 182        if (ret)
 183                goto out;
 184
 185        if ((reg_val & bit_mask) != bit_mask) {
 186                reg_val |= bit_mask;
 187                ret = __da903x_write(chip->client, reg, reg_val);
 188        }
 189out:
 190        mutex_unlock(&chip->lock);
 191        return ret;
 192}
 193EXPORT_SYMBOL_GPL(da903x_set_bits);
 194
 195int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
 196{
 197        struct da903x_chip *chip = dev_get_drvdata(dev);
 198        uint8_t reg_val;
 199        int ret = 0;
 200
 201        mutex_lock(&chip->lock);
 202
 203        ret = __da903x_read(chip->client, reg, &reg_val);
 204        if (ret)
 205                goto out;
 206
 207        if (reg_val & bit_mask) {
 208                reg_val &= ~bit_mask;
 209                ret = __da903x_write(chip->client, reg, reg_val);
 210        }
 211out:
 212        mutex_unlock(&chip->lock);
 213        return ret;
 214}
 215EXPORT_SYMBOL_GPL(da903x_clr_bits);
 216
 217int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
 218{
 219        struct da903x_chip *chip = dev_get_drvdata(dev);
 220        uint8_t reg_val;
 221        int ret = 0;
 222
 223        mutex_lock(&chip->lock);
 224
 225        ret = __da903x_read(chip->client, reg, &reg_val);
 226        if (ret)
 227                goto out;
 228
 229        if ((reg_val & mask) != val) {
 230                reg_val = (reg_val & ~mask) | val;
 231                ret = __da903x_write(chip->client, reg, reg_val);
 232        }
 233out:
 234        mutex_unlock(&chip->lock);
 235        return ret;
 236}
 237EXPORT_SYMBOL_GPL(da903x_update);
 238
 239int da903x_query_status(struct device *dev, unsigned int sbits)
 240{
 241        struct da903x_chip *chip = dev_get_drvdata(dev);
 242        unsigned int status = 0;
 243
 244        chip->ops->read_status(chip, &status);
 245        return ((status & sbits) == sbits);
 246}
 247EXPORT_SYMBOL(da903x_query_status);
 248
 249static int da9030_init_chip(struct da903x_chip *chip)
 250{
 251        uint8_t chip_id;
 252        int err;
 253
 254        err = __da903x_read(chip->client, DA9030_CHIP_ID, &chip_id);
 255        if (err)
 256                return err;
 257
 258        err = __da903x_write(chip->client, DA9030_SYS_CTRL_A, 0xE8);
 259        if (err)
 260                return err;
 261
 262        dev_info(chip->dev, "DA9030 (CHIP ID: 0x%02x) detected\n", chip_id);
 263        return 0;
 264}
 265
 266static int da9030_unmask_events(struct da903x_chip *chip, unsigned int events)
 267{
 268        uint8_t v[3];
 269
 270        chip->events_mask &= ~events;
 271
 272        v[0] = (chip->events_mask & 0xff);
 273        v[1] = (chip->events_mask >> 8) & 0xff;
 274        v[2] = (chip->events_mask >> 16) & 0xff;
 275
 276        return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
 277}
 278
 279static int da9030_mask_events(struct da903x_chip *chip, unsigned int events)
 280{
 281        uint8_t v[3];
 282
 283        chip->events_mask |= events;
 284
 285        v[0] = (chip->events_mask & 0xff);
 286        v[1] = (chip->events_mask >> 8) & 0xff;
 287        v[2] = (chip->events_mask >> 16) & 0xff;
 288
 289        return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
 290}
 291
 292static int da9030_read_events(struct da903x_chip *chip, unsigned int *events)
 293{
 294        uint8_t v[3] = {0, 0, 0};
 295        int ret;
 296
 297        ret = __da903x_reads(chip->client, DA9030_EVENT_A, 3, v);
 298        if (ret < 0)
 299                return ret;
 300
 301        *events = (v[2] << 16) | (v[1] << 8) | v[0];
 302        return 0;
 303}
 304
 305static int da9030_read_status(struct da903x_chip *chip, unsigned int *status)
 306{
 307        return __da903x_read(chip->client, DA9030_STATUS, (uint8_t *)status);
 308}
 309
 310static int da9034_init_chip(struct da903x_chip *chip)
 311{
 312        uint8_t chip_id;
 313        int err;
 314
 315        err = __da903x_read(chip->client, DA9034_CHIP_ID, &chip_id);
 316        if (err)
 317                return err;
 318
 319        err = __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0xE8);
 320        if (err)
 321                return err;
 322
 323        /* avoid SRAM power off during sleep*/
 324        __da903x_write(chip->client, 0x10, 0x07);
 325        __da903x_write(chip->client, 0x11, 0xff);
 326        __da903x_write(chip->client, 0x12, 0xff);
 327
 328        /* Enable the ONKEY power down functionality */
 329        __da903x_write(chip->client, DA9034_SYS_CTRL_B, 0x20);
 330        __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0x60);
 331
 332        /* workaround to make LEDs work */
 333        __da903x_write(chip->client, 0x90, 0x01);
 334        __da903x_write(chip->client, 0xB0, 0x08);
 335
 336        /* make ADTV1 and SDTV1 effective */
 337        __da903x_write(chip->client, 0x20, 0x00);
 338
 339        dev_info(chip->dev, "DA9034 (CHIP ID: 0x%02x) detected\n", chip_id);
 340        return 0;
 341}
 342
 343static int da9034_unmask_events(struct da903x_chip *chip, unsigned int events)
 344{
 345        uint8_t v[4];
 346
 347        chip->events_mask &= ~events;
 348
 349        v[0] = (chip->events_mask & 0xff);
 350        v[1] = (chip->events_mask >> 8) & 0xff;
 351        v[2] = (chip->events_mask >> 16) & 0xff;
 352        v[3] = (chip->events_mask >> 24) & 0xff;
 353
 354        return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
 355}
 356
 357static int da9034_mask_events(struct da903x_chip *chip, unsigned int events)
 358{
 359        uint8_t v[4];
 360
 361        chip->events_mask |= events;
 362
 363        v[0] = (chip->events_mask & 0xff);
 364        v[1] = (chip->events_mask >> 8) & 0xff;
 365        v[2] = (chip->events_mask >> 16) & 0xff;
 366        v[3] = (chip->events_mask >> 24) & 0xff;
 367
 368        return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
 369}
 370
 371static int da9034_read_events(struct da903x_chip *chip, unsigned int *events)
 372{
 373        uint8_t v[4] = {0, 0, 0, 0};
 374        int ret;
 375
 376        ret = __da903x_reads(chip->client, DA9034_EVENT_A, 4, v);
 377        if (ret < 0)
 378                return ret;
 379
 380        *events = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0];
 381        return 0;
 382}
 383
 384static int da9034_read_status(struct da903x_chip *chip, unsigned int *status)
 385{
 386        uint8_t v[2] = {0, 0};
 387        int ret = 0;
 388
 389        ret = __da903x_reads(chip->client, DA9034_STATUS_A, 2, v);
 390        if (ret)
 391                return ret;
 392
 393        *status = (v[1] << 8) | v[0];
 394        return 0;
 395}
 396
 397static void da903x_irq_work(struct work_struct *work)
 398{
 399        struct da903x_chip *chip =
 400                container_of(work, struct da903x_chip, irq_work);
 401        unsigned int events = 0;
 402
 403        while (1) {
 404                if (chip->ops->read_events(chip, &events))
 405                        break;
 406
 407                events &= ~chip->events_mask;
 408                if (events == 0)
 409                        break;
 410
 411                blocking_notifier_call_chain(
 412                                &chip->notifier_list, events, NULL);
 413        }
 414        enable_irq(chip->client->irq);
 415}
 416
 417static irqreturn_t da903x_irq_handler(int irq, void *data)
 418{
 419        struct da903x_chip *chip = data;
 420
 421        disable_irq_nosync(irq);
 422        (void)schedule_work(&chip->irq_work);
 423
 424        return IRQ_HANDLED;
 425}
 426
 427static struct da903x_chip_ops da903x_ops[] = {
 428        [0] = {
 429                .init_chip      = da9030_init_chip,
 430                .unmask_events  = da9030_unmask_events,
 431                .mask_events    = da9030_mask_events,
 432                .read_events    = da9030_read_events,
 433                .read_status    = da9030_read_status,
 434        },
 435        [1] = {
 436                .init_chip      = da9034_init_chip,
 437                .unmask_events  = da9034_unmask_events,
 438                .mask_events    = da9034_mask_events,
 439                .read_events    = da9034_read_events,
 440                .read_status    = da9034_read_status,
 441        }
 442};
 443
 444static const struct i2c_device_id da903x_id_table[] = {
 445        { "da9030", 0 },
 446        { "da9034", 1 },
 447        { },
 448};
 449MODULE_DEVICE_TABLE(i2c, da903x_id_table);
 450
 451static int __remove_subdev(struct device *dev, void *unused)
 452{
 453        platform_device_unregister(to_platform_device(dev));
 454        return 0;
 455}
 456
 457static int da903x_remove_subdevs(struct da903x_chip *chip)
 458{
 459        return device_for_each_child(chip->dev, NULL, __remove_subdev);
 460}
 461
 462static int da903x_add_subdevs(struct da903x_chip *chip,
 463                                        struct da903x_platform_data *pdata)
 464{
 465        struct da903x_subdev_info *subdev;
 466        struct platform_device *pdev;
 467        int i, ret = 0;
 468
 469        for (i = 0; i < pdata->num_subdevs; i++) {
 470                subdev = &pdata->subdevs[i];
 471
 472                pdev = platform_device_alloc(subdev->name, subdev->id);
 473                if (!pdev) {
 474                        ret = -ENOMEM;
 475                        goto failed;
 476                }
 477
 478                pdev->dev.parent = chip->dev;
 479                pdev->dev.platform_data = subdev->platform_data;
 480
 481                ret = platform_device_add(pdev);
 482                if (ret) {
 483                        platform_device_put(pdev);
 484                        goto failed;
 485                }
 486        }
 487        return 0;
 488
 489failed:
 490        da903x_remove_subdevs(chip);
 491        return ret;
 492}
 493
 494static int da903x_probe(struct i2c_client *client,
 495                                  const struct i2c_device_id *id)
 496{
 497        struct da903x_platform_data *pdata = dev_get_platdata(&client->dev);
 498        struct da903x_chip *chip;
 499        unsigned int tmp;
 500        int ret;
 501
 502        chip = devm_kzalloc(&client->dev, sizeof(struct da903x_chip),
 503                                GFP_KERNEL);
 504        if (chip == NULL)
 505                return -ENOMEM;
 506
 507        chip->client = client;
 508        chip->dev = &client->dev;
 509        chip->ops = &da903x_ops[id->driver_data];
 510
 511        mutex_init(&chip->lock);
 512        INIT_WORK(&chip->irq_work, da903x_irq_work);
 513        BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);
 514
 515        i2c_set_clientdata(client, chip);
 516
 517        ret = chip->ops->init_chip(chip);
 518        if (ret)
 519                return ret;
 520
 521        /* mask and clear all IRQs */
 522        chip->events_mask = 0xffffffff;
 523        chip->ops->mask_events(chip, chip->events_mask);
 524        chip->ops->read_events(chip, &tmp);
 525
 526        ret = devm_request_irq(&client->dev, client->irq, da903x_irq_handler,
 527                        IRQF_TRIGGER_FALLING,
 528                        "da903x", chip);
 529        if (ret) {
 530                dev_err(&client->dev, "failed to request irq %d\n",
 531                                client->irq);
 532                return ret;
 533        }
 534
 535        ret = da903x_add_subdevs(chip, pdata);
 536        if (ret)
 537                return ret;
 538
 539        return 0;
 540}
 541
 542static int da903x_remove(struct i2c_client *client)
 543{
 544        struct da903x_chip *chip = i2c_get_clientdata(client);
 545
 546        da903x_remove_subdevs(chip);
 547        return 0;
 548}
 549
 550static struct i2c_driver da903x_driver = {
 551        .driver = {
 552                .name   = "da903x",
 553                .owner  = THIS_MODULE,
 554        },
 555        .probe          = da903x_probe,
 556        .remove         = da903x_remove,
 557        .id_table       = da903x_id_table,
 558};
 559
 560static int __init da903x_init(void)
 561{
 562        return i2c_add_driver(&da903x_driver);
 563}
 564subsys_initcall(da903x_init);
 565
 566static void __exit da903x_exit(void)
 567{
 568        i2c_del_driver(&da903x_driver);
 569}
 570module_exit(da903x_exit);
 571
 572MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");
 573MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
 574              "Mike Rapoport <mike@compulab.co.il>");
 575MODULE_LICENSE("GPL");
 576
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.