linux/drivers/mfd/rt5033.c
<<
>>
Prefs
   1/*
   2 * MFD core driver for the Richtek RT5033.
   3 *
   4 * RT5033 comprises multiple sub-devices switcing charger, fuel gauge,
   5 * flash LED, current source, LDO and BUCK regulators.
   6 *
   7 * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
   8 * Author: Beomho Seo <beomho.seo@samsung.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 bythe Free Software Foundation.
  13 */
  14
  15#include <linux/err.h>
  16#include <linux/module.h>
  17#include <linux/interrupt.h>
  18#include <linux/of_device.h>
  19#include <linux/mfd/core.h>
  20#include <linux/mfd/rt5033.h>
  21#include <linux/mfd/rt5033-private.h>
  22
  23static const struct regmap_irq rt5033_irqs[] = {
  24        { .mask = RT5033_PMIC_IRQ_BUCKOCP, },
  25        { .mask = RT5033_PMIC_IRQ_BUCKLV, },
  26        { .mask = RT5033_PMIC_IRQ_SAFELDOLV, },
  27        { .mask = RT5033_PMIC_IRQ_LDOLV, },
  28        { .mask = RT5033_PMIC_IRQ_OT, },
  29        { .mask = RT5033_PMIC_IRQ_VDDA_UV, },
  30};
  31
  32static const struct regmap_irq_chip rt5033_irq_chip = {
  33        .name           = "rt5033",
  34        .status_base    = RT5033_REG_PMIC_IRQ_STAT,
  35        .mask_base      = RT5033_REG_PMIC_IRQ_CTRL,
  36        .mask_invert    = true,
  37        .num_regs       = 1,
  38        .irqs           = rt5033_irqs,
  39        .num_irqs       = ARRAY_SIZE(rt5033_irqs),
  40};
  41
  42static const struct mfd_cell rt5033_devs[] = {
  43        { .name = "rt5033-regulator", },
  44        {
  45                .name = "rt5033-charger",
  46                .of_compatible = "richtek,rt5033-charger",
  47        }, {
  48                .name = "rt5033-battery",
  49                .of_compatible = "richtek,rt5033-battery",
  50        }, {
  51                .name = "rt5033-led",
  52                .of_compatible = "richtek,rt5033-led",
  53        },
  54};
  55
  56static const struct regmap_config rt5033_regmap_config = {
  57        .reg_bits       = 8,
  58        .val_bits       = 8,
  59        .max_register   = RT5033_REG_END,
  60};
  61
  62static int rt5033_i2c_probe(struct i2c_client *i2c,
  63                                const struct i2c_device_id *id)
  64{
  65        struct rt5033_dev *rt5033;
  66        unsigned int dev_id;
  67        int ret;
  68
  69        rt5033 = devm_kzalloc(&i2c->dev, sizeof(*rt5033), GFP_KERNEL);
  70        if (!rt5033)
  71                return -ENOMEM;
  72
  73        i2c_set_clientdata(i2c, rt5033);
  74        rt5033->dev = &i2c->dev;
  75        rt5033->irq = i2c->irq;
  76        rt5033->wakeup = true;
  77
  78        rt5033->regmap = devm_regmap_init_i2c(i2c, &rt5033_regmap_config);
  79        if (IS_ERR(rt5033->regmap)) {
  80                dev_err(&i2c->dev, "Failed to allocate register map.\n");
  81                return PTR_ERR(rt5033->regmap);
  82        }
  83
  84        ret = regmap_read(rt5033->regmap, RT5033_REG_DEVICE_ID, &dev_id);
  85        if (ret) {
  86                dev_err(&i2c->dev, "Device not found\n");
  87                return -ENODEV;
  88        }
  89        dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id);
  90
  91        ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
  92                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  93                        0, &rt5033_irq_chip, &rt5033->irq_data);
  94        if (ret) {
  95                dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
  96                                                        rt5033->irq, ret);
  97                return ret;
  98        }
  99
 100        ret = mfd_add_devices(rt5033->dev, -1, rt5033_devs,
 101                        ARRAY_SIZE(rt5033_devs), NULL, 0,
 102                        regmap_irq_get_domain(rt5033->irq_data));
 103        if (ret < 0) {
 104                dev_err(&i2c->dev, "Failed to add RT5033 child devices.\n");
 105                return ret;
 106        }
 107
 108        device_init_wakeup(rt5033->dev, rt5033->wakeup);
 109
 110        return 0;
 111}
 112
 113static int rt5033_i2c_remove(struct i2c_client *i2c)
 114{
 115        mfd_remove_devices(&i2c->dev);
 116
 117        return 0;
 118}
 119
 120static const struct i2c_device_id rt5033_i2c_id[] = {
 121        { "rt5033", },
 122        { }
 123};
 124MODULE_DEVICE_TABLE(i2c, rt5033_i2c_id);
 125
 126static const struct of_device_id rt5033_dt_match[] = {
 127        { .compatible = "richtek,rt5033", },
 128        { }
 129};
 130MODULE_DEVICE_TABLE(of, rt5033_dt_match);
 131
 132static struct i2c_driver rt5033_driver = {
 133        .driver = {
 134                .name = "rt5033",
 135                .of_match_table = of_match_ptr(rt5033_dt_match),
 136        },
 137        .probe = rt5033_i2c_probe,
 138        .remove = rt5033_i2c_remove,
 139        .id_table = rt5033_i2c_id,
 140};
 141module_i2c_driver(rt5033_driver);
 142
 143MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver");
 144MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
 145MODULE_LICENSE("GPL");
 146