^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Core driver for TI TPS6586x PMIC family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2010 CompuLab Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Mike Rapoport <mike@compulab.co.il>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based on da903x.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2008 Compulab, Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Mike Rapoport <mike@compulab.co.il>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 2006-2008 Marvell International Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Eric Miao <eric.miao@marvell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/mfd/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/mfd/tps6586x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define TPS6586X_SUPPLYENE 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define EXITSLREQ_BIT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SLEEP_MODE_BIT BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* interrupt control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define TPS6586X_INT_ACK1 0xb5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define TPS6586X_INT_ACK2 0xb6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define TPS6586X_INT_ACK3 0xb7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define TPS6586X_INT_ACK4 0xb8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* interrupt mask registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define TPS6586X_INT_MASK1 0xb0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define TPS6586X_INT_MASK2 0xb1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define TPS6586X_INT_MASK3 0xb2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define TPS6586X_INT_MASK4 0xb3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define TPS6586X_INT_MASK5 0xb4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* device id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define TPS6586X_VERSIONCRC 0xcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Maximum register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TPS6586X_MAX_REGISTER TPS6586X_VERSIONCRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct tps6586x_irq_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 mask_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u8 mask_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TPS6586X_IRQ(_reg, _mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .mask_reg = (_reg) - TPS6586X_INT_MASK1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .mask_mask = (_mask), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static const struct tps6586x_irq_data tps6586x_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) [TPS6586X_INT_PLDO_0] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) [TPS6586X_INT_PLDO_1] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) [TPS6586X_INT_PLDO_2] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) [TPS6586X_INT_PLDO_3] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) [TPS6586X_INT_PLDO_4] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) [TPS6586X_INT_PLDO_5] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) [TPS6586X_INT_PLDO_6] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) [TPS6586X_INT_PLDO_7] = TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) [TPS6586X_INT_COMP_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) [TPS6586X_INT_ADC] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) [TPS6586X_INT_PLDO_8] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) [TPS6586X_INT_PLDO_9] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) [TPS6586X_INT_PSM_0] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) [TPS6586X_INT_PSM_1] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) [TPS6586X_INT_PSM_2] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) [TPS6586X_INT_PSM_3] = TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) [TPS6586X_INT_RTC_ALM1] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) [TPS6586X_INT_ACUSB_OVP] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 0x03),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) [TPS6586X_INT_USB_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) [TPS6586X_INT_AC_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) [TPS6586X_INT_BAT_DET] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 1 << 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [TPS6586X_INT_CHG_STAT] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 0xfc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) [TPS6586X_INT_CHG_TEMP] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0x06),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) [TPS6586X_INT_PP] = TPS6586X_IRQ(TPS6586X_INT_MASK3, 0xf0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) [TPS6586X_INT_RESUME] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) [TPS6586X_INT_LOW_SYS] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) [TPS6586X_INT_RTC_ALM2] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static struct resource tps6586x_rtc_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .start = TPS6586X_INT_RTC_ALM1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .end = TPS6586X_INT_RTC_ALM1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .flags = IORESOURCE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static const struct mfd_cell tps6586x_cell[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .name = "tps6586x-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .name = "tps6586x-regulator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .name = "tps6586x-rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .num_resources = ARRAY_SIZE(tps6586x_rtc_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .resources = &tps6586x_rtc_resources[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .name = "tps6586x-onkey",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct tps6586x {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct irq_chip irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct mutex irq_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u32 irq_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u8 mask_reg[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct irq_domain *irq_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static inline struct tps6586x *dev_to_tps6586x(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int tps6586x_write(struct device *dev, int reg, uint8_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return regmap_write(tps6586x->regmap, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) EXPORT_SYMBOL_GPL(tps6586x_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return regmap_bulk_write(tps6586x->regmap, reg, val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) EXPORT_SYMBOL_GPL(tps6586x_writes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int tps6586x_read(struct device *dev, int reg, uint8_t *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = regmap_read(tps6586x->regmap, reg, &rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *val = rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) EXPORT_SYMBOL_GPL(tps6586x_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return regmap_bulk_read(tps6586x->regmap, reg, val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) EXPORT_SYMBOL_GPL(tps6586x_reads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return regmap_update_bits(tps6586x->regmap, reg, bit_mask, bit_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) EXPORT_SYMBOL_GPL(tps6586x_set_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return regmap_update_bits(tps6586x->regmap, reg, bit_mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) EXPORT_SYMBOL_GPL(tps6586x_clr_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return regmap_update_bits(tps6586x->regmap, reg, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) EXPORT_SYMBOL_GPL(tps6586x_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int tps6586x_irq_get_virq(struct device *dev, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct tps6586x *tps6586x = dev_to_tps6586x(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return irq_create_mapping(tps6586x->irq_domain, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) EXPORT_SYMBOL_GPL(tps6586x_irq_get_virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int tps6586x_get_version(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct tps6586x *tps6586x = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return tps6586x->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) EXPORT_SYMBOL_GPL(tps6586x_get_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int __remove_subdev(struct device *dev, void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) platform_device_unregister(to_platform_device(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static int tps6586x_remove_subdevs(struct tps6586x *tps6586x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return device_for_each_child(tps6586x->dev, NULL, __remove_subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void tps6586x_irq_lock(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mutex_lock(&tps6586x->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static void tps6586x_irq_enable(struct irq_data *irq_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned int __irq = irq_data->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) tps6586x->irq_en |= (1 << __irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static void tps6586x_irq_disable(struct irq_data *irq_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned int __irq = irq_data->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) tps6586x->mask_reg[data->mask_reg] |= data->mask_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) tps6586x->irq_en &= ~(1 << __irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static void tps6586x_irq_sync_unlock(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = tps6586x_write(tps6586x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) TPS6586X_INT_MASK1 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) tps6586x->mask_reg[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) WARN_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mutex_unlock(&tps6586x->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int tps6586x_irq_set_wake(struct irq_data *irq_data, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return irq_set_irq_wake(tps6586x->irq, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define tps6586x_irq_set_wake NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static struct irq_chip tps6586x_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .name = "tps6586x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .irq_bus_lock = tps6586x_irq_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .irq_bus_sync_unlock = tps6586x_irq_sync_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .irq_disable = tps6586x_irq_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .irq_enable = tps6586x_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .irq_set_wake = tps6586x_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct tps6586x *tps6586x = h->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) irq_set_chip_data(virq, tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) irq_set_chip_and_handler(virq, &tps6586x_irq_chip, handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) irq_set_nested_thread(virq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) irq_set_noprobe(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static const struct irq_domain_ops tps6586x_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .map = tps6586x_irq_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .xlate = irq_domain_xlate_twocell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static irqreturn_t tps6586x_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct tps6586x *tps6586x = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) uint32_t acks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) __le32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) sizeof(acks), (uint8_t *)&val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_err(tps6586x->dev, "failed to read interrupt status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) acks = le32_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) while (acks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int i = __ffs(acks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (tps6586x->irq_en & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) handle_nested_irq(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) irq_find_mapping(tps6586x->irq_domain, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) acks &= ~(1 << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int irq_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) u8 tmp[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int new_irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int irq_num = ARRAY_SIZE(tps6586x_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) tps6586x->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) mutex_init(&tps6586x->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) for (i = 0; i < 5; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) tps6586x->mask_reg[i] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) tps6586x_write(tps6586x->dev, TPS6586X_INT_MASK1 + i, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, sizeof(tmp), tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (irq_base > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) new_irq_base = irq_alloc_descs(irq_base, 0, irq_num, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (new_irq_base < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) dev_err(tps6586x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) "Failed to alloc IRQs: %d\n", new_irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return new_irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) new_irq_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) tps6586x->irq_domain = irq_domain_add_simple(tps6586x->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) irq_num, new_irq_base, &tps6586x_domain_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!tps6586x->irq_domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) dev_err(tps6586x->dev, "Failed to create IRQ domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) "tps6586x", tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) device_init_wakeup(tps6586x->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int tps6586x_add_subdevs(struct tps6586x *tps6586x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct tps6586x_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct tps6586x_subdev_info *subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for (i = 0; i < pdata->num_subdevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) subdev = &pdata->subdevs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) pdev = platform_device_alloc(subdev->name, subdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) pdev->dev.parent = tps6586x->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) pdev->dev.platform_data = subdev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) pdev->dev.of_node = subdev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = platform_device_add(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) tps6586x_remove_subdevs(tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct device_node *np = client->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct tps6586x_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pdata->num_subdevs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) pdata->subdevs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) pdata->gpio_base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pdata->irq_base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static const struct of_device_id tps6586x_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) { .compatible = "ti,tps6586x", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static bool is_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Cache all interrupt mask register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if ((reg >= TPS6586X_INT_MASK1) && (reg <= TPS6586X_INT_MASK5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static const struct regmap_config tps6586x_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .max_register = TPS6586X_MAX_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .volatile_reg = is_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static struct device *tps6586x_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static void tps6586x_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (tps6586x_clr_bits(tps6586x_dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void tps6586x_print_version(struct i2c_client *client, int version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) switch (version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case TPS658621A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) name = "TPS658621A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case TPS658621CD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) name = "TPS658621C/D";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case TPS658623:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) name = "TPS658623";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case TPS658640:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case TPS658640v2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) name = "TPS658640";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case TPS658643:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) name = "TPS658643";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) name = "TPS6586X";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) dev_info(&client->dev, "Found %s, VERSIONCRC is %02x\n", name, version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static int tps6586x_i2c_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct tps6586x_platform_data *pdata = dev_get_platdata(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct tps6586x *tps6586x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!pdata && client->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) pdata = tps6586x_parse_dt(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dev_err(&client->dev, "tps6586x requires platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) version = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (version < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) dev_err(&client->dev, "Chip ID read failed: %d\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) tps6586x = devm_kzalloc(&client->dev, sizeof(*tps6586x), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (!tps6586x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) tps6586x->version = version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) tps6586x_print_version(client, tps6586x->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) tps6586x->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) tps6586x->dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) i2c_set_clientdata(client, tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) tps6586x->regmap = devm_regmap_init_i2c(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) &tps6586x_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (IS_ERR(tps6586x->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ret = PTR_ERR(tps6586x->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dev_err(&client->dev, "regmap init failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ret = tps6586x_irq_init(tps6586x, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) pdata->irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dev_err(&client->dev, "IRQ init failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ret = mfd_add_devices(tps6586x->dev, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) tps6586x_cell, ARRAY_SIZE(tps6586x_cell),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) NULL, 0, tps6586x->irq_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) goto err_mfd_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ret = tps6586x_add_subdevs(tps6586x, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) dev_err(&client->dev, "add devices failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) goto err_add_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (pdata->pm_off && !pm_power_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) tps6586x_dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) pm_power_off = tps6586x_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) err_add_devs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) mfd_remove_devices(tps6586x->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) err_mfd_add:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) free_irq(client->irq, tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int tps6586x_i2c_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct tps6586x *tps6586x = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) tps6586x_remove_subdevs(tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) mfd_remove_devices(tps6586x->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) free_irq(client->irq, tps6586x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int __maybe_unused tps6586x_i2c_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct tps6586x *tps6586x = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (tps6586x->client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) disable_irq(tps6586x->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static int __maybe_unused tps6586x_i2c_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct tps6586x *tps6586x = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (tps6586x->client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) enable_irq(tps6586x->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_i2c_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) tps6586x_i2c_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static const struct i2c_device_id tps6586x_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) { "tps6586x", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) MODULE_DEVICE_TABLE(i2c, tps6586x_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static struct i2c_driver tps6586x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .name = "tps6586x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) .of_match_table = of_match_ptr(tps6586x_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .pm = &tps6586x_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .probe = tps6586x_i2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .remove = tps6586x_i2c_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .id_table = tps6586x_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static int __init tps6586x_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return i2c_add_driver(&tps6586x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) subsys_initcall(tps6586x_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static void __exit tps6586x_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) i2c_del_driver(&tps6586x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) module_exit(tps6586x_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) MODULE_DESCRIPTION("TPS6586X core driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) MODULE_LICENSE("GPL");