cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rt5033.c (3455B)


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